diff --git a/src/studio-home/StudioHome.test.jsx b/src/studio-home/StudioHome.test.jsx
index a926d7c9ef..7286acda0f 100644
--- a/src/studio-home/StudioHome.test.jsx
+++ b/src/studio-home/StudioHome.test.jsx
@@ -50,174 +50,204 @@ const RootWrapper = () => (
);
describe('
', async () => {
- beforeEach(async () => {
- initializeMockApp({
- authenticatedUser: {
- userId: 3,
- username: 'abc123',
- administrator: true,
- roles: [],
- },
- });
- store = initializeStore();
- axiosMock = new MockAdapter(getAuthenticatedHttpClient());
- axiosMock.onGet(getStudioHomeApiUrl()).reply(200, studioHomeMock);
- await executeThunk(fetchStudioHomeData(), store.dispatch);
- useSelector.mockReturnValue(studioHomeMock);
- });
-
- it('should render page and page title correctly', () => {
- const { getByText } = render(
);
- expect(getByText(`${studioShortName} home`)).toBeInTheDocument();
- });
-
- it('should render email staff header button', async () => {
- useSelector.mockReturnValue({
- ...studioHomeMock,
- courseCreatorStatus: COURSE_CREATOR_STATES.disallowedForThisSite,
+ describe('api fetch fails', () => {
+ beforeEach(async () => {
+ initializeMockApp({
+ authenticatedUser: {
+ userId: 3,
+ username: 'abc123',
+ administrator: true,
+ roles: [],
+ },
+ });
+ store = initializeStore();
+ axiosMock = new MockAdapter(getAuthenticatedHttpClient());
+ axiosMock.onGet(getStudioHomeApiUrl()).reply(404);
+ await executeThunk(fetchStudioHomeData(), store.dispatch);
+ useSelector.mockReturnValue({ studioHomeLoadingStatus: RequestStatus.FAILED });
});
- const { getByRole } = render(
);
- expect(getByRole('link', { name: messages.emailStaffBtnText.defaultMessage }))
- .toHaveAttribute('href', `mailto:${studioRequestEmail}`);
- });
-
- it('should render create new course button', async () => {
- useSelector.mockReturnValue({
- ...studioHomeMock,
- courseCreatorStatus: COURSE_CREATOR_STATES.granted,
+ it('should render fetch error', () => {
+ const { getByText } = render(
);
+ expect(getByText(messages.homePageLoadFailedMessage.defaultMessage)).toBeInTheDocument();
});
- const { getByRole } = render(
);
- expect(getByRole('button', { name: messages.addNewCourseBtnText.defaultMessage })).toBeInTheDocument();
- });
-
- it('should show verify email layout if user inactive', () => {
- useSelector.mockReturnValue({
- ...studioHomeMock,
- userIsActive: false,
+ it('should render Studio home title', () => {
+ const { getByText } = render(
);
+ expect(getByText('Studio home')).toBeInTheDocument();
});
-
- const { getByText } = render(
);
- expect(getByText('Thanks for signing up, abc123!', { exact: false })).toBeInTheDocument();
});
- it('shows the spinner before the query is complete', async () => {
- useSelector.mockReturnValue({
- studioHomeLoadingStatus: RequestStatus.IN_PROGRESS,
- userIsActive: true,
+ describe('api fetch succeeds', () => {
+ beforeEach(async () => {
+ initializeMockApp({
+ authenticatedUser: {
+ userId: 3,
+ username: 'abc123',
+ administrator: true,
+ roles: [],
+ },
+ });
+ store = initializeStore();
+ axiosMock = new MockAdapter(getAuthenticatedHttpClient());
+ axiosMock.onGet(getStudioHomeApiUrl()).reply(200, studioHomeMock);
+ await executeThunk(fetchStudioHomeData(), store.dispatch);
+ useSelector.mockReturnValue(studioHomeMock);
});
- await act(async () => {
- const { getByRole } = render(
);
- const spinner = getByRole('status');
- expect(spinner.textContent).toEqual('Loading...');
+ it('should render page and page title correctly', () => {
+ const { getByText } = render(
);
+ expect(getByText(`${studioShortName} home`)).toBeInTheDocument();
});
- });
- describe('render new library button', () => {
- it('href should include home_library', async () => {
+ it('should render email staff header button', async () => {
useSelector.mockReturnValue({
...studioHomeMock,
- courseCreatorStatus: COURSE_CREATOR_STATES.granted,
+ courseCreatorStatus: COURSE_CREATOR_STATES.disallowedForThisSite,
});
- const studioBaseUrl = 'http://localhost:18010';
- const { getByTestId } = render(
);
- const createNewLibraryButton = getByTestId('new-library-button');
- expect(createNewLibraryButton.getAttribute('href')).toBe(`${studioBaseUrl}/home_library`);
+ const { getByRole } = render(
);
+ expect(getByRole('link', { name: messages.emailStaffBtnText.defaultMessage }))
+ .toHaveAttribute('href', `mailto:${studioRequestEmail}`);
});
- it('href should include create', async () => {
+
+ it('should render create new course button', async () => {
useSelector.mockReturnValue({
...studioHomeMock,
courseCreatorStatus: COURSE_CREATOR_STATES.granted,
- splitStudioHome: true,
- redirectToLibraryAuthoringMfe: true,
});
- const libraryAuthoringMfeUrl = 'http://localhost:3001';
-
- const { getByTestId } = render(
);
- const createNewLibraryButton = getByTestId('new-library-button');
- expect(createNewLibraryButton.getAttribute('href')).toBe(`${libraryAuthoringMfeUrl}/create`);
- });
- });
- it('should render create new course container', async () => {
- useSelector.mockReturnValue({
- ...studioHomeMock,
- courseCreatorStatus: COURSE_CREATOR_STATES.granted,
+ const { getByRole } = render(
);
+ expect(getByRole('button', { name: messages.addNewCourseBtnText.defaultMessage })).toBeInTheDocument();
});
- const { getByRole, getByText } = render(
);
- const createNewCourseButton = getByRole('button', { name: messages.addNewCourseBtnText.defaultMessage });
-
- await act(() => fireEvent.click(createNewCourseButton));
- expect(getByText(createNewCourseMessages.createNewCourse.defaultMessage)).toBeInTheDocument();
- });
+ it('should show verify email layout if user inactive', () => {
+ useSelector.mockReturnValue({
+ ...studioHomeMock,
+ userIsActive: false,
+ });
- it('should hide create new course container', async () => {
- useSelector.mockReturnValue({
- ...studioHomeMock,
- courseCreatorStatus: COURSE_CREATOR_STATES.granted,
+ const { getByText } = render(
);
+ expect(getByText('Thanks for signing up, abc123!', { exact: false })).toBeInTheDocument();
});
- const { getByRole, queryByText, getByText } = render(
);
- const createNewCourseButton = getByRole('button', { name: messages.addNewCourseBtnText.defaultMessage });
+ it('shows the spinner before the query is complete', async () => {
+ useSelector.mockReturnValue({
+ studioHomeLoadingStatus: RequestStatus.IN_PROGRESS,
+ userIsActive: true,
+ });
- fireEvent.click(createNewCourseButton);
- waitFor(() => {
- expect(getByText(createNewCourseMessages.createNewCourse.defaultMessage)).toBeInTheDocument();
+ await act(async () => {
+ const { getByRole } = render(
);
+ const spinner = getByRole('status');
+ expect(spinner.textContent).toEqual('Loading...');
+ });
});
- const cancelButton = getByRole('button', { name: createOrRerunCourseMessages.cancelButton.defaultMessage });
- fireEvent.click(cancelButton);
- waitFor(() => {
- expect(queryByText(createNewCourseMessages.createNewCourse.defaultMessage)).not.toBeInTheDocument();
+ describe('render new library button', () => {
+ it('href should include home_library', async () => {
+ useSelector.mockReturnValue({
+ ...studioHomeMock,
+ courseCreatorStatus: COURSE_CREATOR_STATES.granted,
+ });
+ const studioBaseUrl = 'http://localhost:18010';
+
+ const { getByTestId } = render(
);
+ const createNewLibraryButton = getByTestId('new-library-button');
+ expect(createNewLibraryButton.getAttribute('href')).toBe(`${studioBaseUrl}/home_library`);
+ });
+ it('href should include create', async () => {
+ useSelector.mockReturnValue({
+ ...studioHomeMock,
+ courseCreatorStatus: COURSE_CREATOR_STATES.granted,
+ splitStudioHome: true,
+ redirectToLibraryAuthoringMfe: true,
+ });
+ const libraryAuthoringMfeUrl = 'http://localhost:3001';
+
+ const { getByTestId } = render(
);
+ const createNewLibraryButton = getByTestId('new-library-button');
+ expect(createNewLibraryButton.getAttribute('href')).toBe(`${libraryAuthoringMfeUrl}/create`);
+ });
});
- });
- describe('contact administrator card', () => {
- it('should show contact administrator card with no add course buttons', () => {
+ it('should render create new course container', async () => {
useSelector.mockReturnValue({
...studioHomeMock,
- courses: null,
- courseCreatorStatus: COURSE_CREATOR_STATES.pending,
+ courseCreatorStatus: COURSE_CREATOR_STATES.granted,
});
- const { getByText, queryByText } = render(
);
- const defaultTitleMessage = messages.defaultSection_1_Title.defaultMessage;
- const titleWithStudioName = defaultTitleMessage.replace('{studioShortName}', 'Studio');
- const administratorCardTitle = getByText(titleWithStudioName);
- expect(administratorCardTitle).toBeVisible();
+ const { getByRole, getByText } = render(
);
+ const createNewCourseButton = getByRole('button', { name: messages.addNewCourseBtnText.defaultMessage });
- const addCourseButton = queryByText(messages.btnAddNewCourseText.defaultMessage);
- expect(addCourseButton).toBeNull();
+ await act(() => fireEvent.click(createNewCourseButton));
+ expect(getByText(createNewCourseMessages.createNewCourse.defaultMessage)).toBeInTheDocument();
});
- it('should show contact administrator card with add course buttons', () => {
+ it('should hide create new course container', async () => {
useSelector.mockReturnValue({
...studioHomeMock,
- courses: null,
courseCreatorStatus: COURSE_CREATOR_STATES.granted,
});
- const { getByText, getByTestId } = render(
);
- const defaultTitleMessage = messages.defaultSection_1_Title.defaultMessage;
- const titleWithStudioName = defaultTitleMessage.replace('{studioShortName}', 'Studio');
- const administratorCardTitle = getByText(titleWithStudioName);
- expect(administratorCardTitle).toBeVisible();
+ const { getByRole, queryByText, getByText } = render(
);
+ const createNewCourseButton = getByRole('button', { name: messages.addNewCourseBtnText.defaultMessage });
- const addCourseButton = getByTestId('contact-admin-create-course');
- expect(addCourseButton).toBeVisible();
+ fireEvent.click(createNewCourseButton);
+ waitFor(() => {
+ expect(getByText(createNewCourseMessages.createNewCourse.defaultMessage)).toBeInTheDocument();
+ });
- fireEvent.click(addCourseButton);
- expect(getByTestId('create-course-form')).toBeVisible();
+ const cancelButton = getByRole('button', { name: createOrRerunCourseMessages.cancelButton.defaultMessage });
+ fireEvent.click(cancelButton);
+ waitFor(() => {
+ expect(queryByText(createNewCourseMessages.createNewCourse.defaultMessage)).not.toBeInTheDocument();
+ });
});
- });
- it('should show footer', () => {
- const { getByText } = render(
);
- expect(getByText('Looking for help with Studio?')).toBeInTheDocument();
- expect(getByText('LMS')).toHaveAttribute('href', process.env.LMS_BASE_URL);
+ describe('contact administrator card', () => {
+ it('should show contact administrator card with no add course buttons', () => {
+ useSelector.mockReturnValue({
+ ...studioHomeMock,
+ courses: null,
+ courseCreatorStatus: COURSE_CREATOR_STATES.pending,
+ });
+ const { getByText, queryByText } = render(
);
+ const defaultTitleMessage = messages.defaultSection_1_Title.defaultMessage;
+ const titleWithStudioName = defaultTitleMessage.replace('{studioShortName}', 'Studio');
+ const administratorCardTitle = getByText(titleWithStudioName);
+
+ expect(administratorCardTitle).toBeVisible();
+
+ const addCourseButton = queryByText(messages.btnAddNewCourseText.defaultMessage);
+ expect(addCourseButton).toBeNull();
+ });
+
+ it('should show contact administrator card with add course buttons', () => {
+ useSelector.mockReturnValue({
+ ...studioHomeMock,
+ courses: null,
+ courseCreatorStatus: COURSE_CREATOR_STATES.granted,
+ });
+ const { getByText, getByTestId } = render(
);
+ const defaultTitleMessage = messages.defaultSection_1_Title.defaultMessage;
+ const titleWithStudioName = defaultTitleMessage.replace('{studioShortName}', 'Studio');
+ const administratorCardTitle = getByText(titleWithStudioName);
+
+ expect(administratorCardTitle).toBeVisible();
+
+ const addCourseButton = getByTestId('contact-admin-create-course');
+ expect(addCourseButton).toBeVisible();
+
+ fireEvent.click(addCourseButton);
+ expect(getByTestId('create-course-form')).toBeVisible();
+ });
+ });
+
+ it('should show footer', () => {
+ const { getByText } = render(
);
+ expect(getByText('Looking for help with Studio?')).toBeInTheDocument();
+ expect(getByText('LMS')).toHaveAttribute('href', process.env.LMS_BASE_URL);
+ });
});
});
diff --git a/src/studio-home/data/api.js b/src/studio-home/data/api.js
index f6035b9234..546a3d5b01 100644
--- a/src/studio-home/data/api.js
+++ b/src/studio-home/data/api.js
@@ -1,8 +1,8 @@
import { camelCaseObject, getConfig } from '@edx/frontend-platform';
import { getAuthenticatedHttpClient } from '@edx/frontend-platform/auth';
-const getApiBaseUrl = () => getConfig().STUDIO_BASE_URL;
-export const getStudioHomeApiUrl = (search) => new URL(`api/contentstore/v1/home${search}`, getApiBaseUrl()).href;
+export const getApiBaseUrl = () => getConfig().STUDIO_BASE_URL;
+export const getStudioHomeApiUrl = () => new URL('api/contentstore/v1/home', getApiBaseUrl()).href;
export const getRequestCourseCreatorUrl = () => new URL('request_course_creator', getApiBaseUrl()).href;
export const getCourseNotificationUrl = (url) => new URL(url, getApiBaseUrl()).href;
@@ -11,8 +11,18 @@ export const getCourseNotificationUrl = (url) => new URL(url, getApiBaseUrl()).h
* @param {string} search
* @returns {Promise