diff --git a/src/library-authoring/create-library/CreateLibrary.test.tsx b/src/library-authoring/create-library/CreateLibrary.test.tsx
index d88a3b721e..73517f788d 100644
--- a/src/library-authoring/create-library/CreateLibrary.test.tsx
+++ b/src/library-authoring/create-library/CreateLibrary.test.tsx
@@ -15,7 +15,7 @@ import { getContentLibraryV2CreateApiUrl } from './data/api';
let store;
const mockNavigate = jest.fn();
-let axiosMock;
+let axiosMock: MockAdapter;
jest.mock('react-router-dom', () => ({
...jest.requireActual('react-router-dom'),
@@ -60,11 +60,7 @@ describe('', () => {
});
store = initializeStore();
- // The API method to get the Meilisearch connection details uses Axios:
axiosMock = new MockAdapter(getAuthenticatedHttpClient());
- axiosMock.onPost(getContentLibraryV2CreateApiUrl()).reply(200, {
- id: 'library-id',
- });
});
afterEach(() => {
@@ -73,7 +69,11 @@ describe('', () => {
queryClient.clear();
});
- it('call api data with correct data', async () => {
+ test('call api data with correct data', async () => {
+ axiosMock.onPost(getContentLibraryV2CreateApiUrl()).reply(200, {
+ id: 'library-id',
+ });
+
const { getByRole, getByTestId } = render();
const titleInput = getByRole('textbox', { name: /library name/i });
@@ -98,4 +98,35 @@ describe('', () => {
expect(mockNavigate).toHaveBeenCalledWith('/library/library-id');
});
});
+
+ test('show api error', async () => {
+ axiosMock.onPost(getContentLibraryV2CreateApiUrl()).reply(400, {
+ field: 'Error message',
+ });
+ const { getByRole, getByTestId } = render();
+
+ const titleInput = getByRole('textbox', { name: /library name/i });
+ userEvent.click(titleInput);
+ userEvent.type(titleInput, 'Test Library Name');
+
+ const orgInput = getByTestId('autosuggest-textbox-input');
+ userEvent.click(orgInput);
+ userEvent.type(orgInput, 'org1');
+ userEvent.tab();
+
+ const slugInput = getByRole('textbox', { name: /library id/i });
+ userEvent.click(slugInput);
+ userEvent.type(slugInput, 'test_library_slug');
+
+ fireEvent.click(getByRole('button', { name: /create/i }));
+ await waitFor(() => {
+ expect(axiosMock.history.post.length).toBe(1);
+ expect(axiosMock.history.post[0].data).toBe(
+ '{"description":"","title":"Test Library Name","org":"org1","slug":"test_library_slug"}',
+ );
+ expect(mockNavigate).not.toHaveBeenCalled();
+ expect(getByRole('alert')).toHaveTextContent('Request failed with status code 400');
+ expect(getByRole('alert')).toHaveTextContent('{"field":"Error message"}');
+ });
+ });
});
diff --git a/src/library-authoring/create-library/CreateLibrary.tsx b/src/library-authoring/create-library/CreateLibrary.tsx
index 5c245d937f..3fdf765def 100644
--- a/src/library-authoring/create-library/CreateLibrary.tsx
+++ b/src/library-authoring/create-library/CreateLibrary.tsx
@@ -8,6 +8,7 @@ import {
Form,
StatefulButton,
} from '@openedx/paragon';
+import axios from 'axios';
import { Formik } from 'formik';
import { useNavigate } from 'react-router-dom';
import * as Yup from 'yup';
@@ -27,7 +28,7 @@ const CreateLibrary = () => {
const intl = useIntl();
const navigate = useNavigate();
- const [apiError, setApiError] = useState();
+ const [apiError, setApiError] = useState();
const { noSpaceRule, specialCharsRule } = REGEX_RULES;
const validSlugIdRegex = /^[a-zA-Z\d]+(?:[\w -]*[a-zA-Z\d]+)*$/;
@@ -54,7 +55,6 @@ const CreateLibrary = () => {
org: '',
slug: '',
}}
-
validationSchema={
Yup.object().shape({
title: Yup.string()
@@ -74,15 +74,20 @@ const CreateLibrary = () => {
),
})
}
-
onSubmit={async (values: CreateContentLibraryDto) => {
setApiError(undefined);
try {
const data = await mutateAsync(values);
navigate(`/library/${data.id}`);
- } catch (error) {
- if (error instanceof Error) {
- setApiError(error.message);
+ } catch (error: any) {
+ if (axios.isAxiosError(error)) {
+ setApiError((
+ <>
+ {error.message}
+
+ {JSON.stringify(error.response?.data)}
+ >
+ ));
}
}
}}