Fix broken StudioHome tests (#2291)

There were a ton of problems with these tests, but the main one was the use of `waitFor` without `await`, causing all of the code inside each `waitFor` block to essentially be ignored.

Other problems fixed:
* Rendering a router inside a router was causing most of the render() calls to fail (our custom `render()` already provides a router so there's no need to provide one in the test case)
* Use of `testid` instead of queries based on what users see
* Tests could match on content in the body when trying to make assertions about the header
* Mock imported via `index.js` was causing `jest-haste-map` to print warnings about duplicate mock names (this is still happening for other mocks)
* Passing `courses: null` instead of `courses: []` was causing a broken render on two of the tests.

I also made other cleanups to follow best practices.
This commit is contained in:
Braden MacDonald
2025-07-17 13:45:22 -07:00
committed by GitHub
parent 2db6d89fca
commit bd18e874b5
21 changed files with 271 additions and 325 deletions

View File

@@ -5,8 +5,8 @@ import {
fireEvent,
render,
waitFor,
} from '../testUtils';
import { studioHomeMock } from '../studio-home/__mocks__';
} from '@src/testUtils';
import studioHomeMock from '@src/studio-home/__mocks__/studioHomeMock';
import { getStudioHomeApiUrl } from '../studio-home/data/api';
import { RequestStatus } from '../data/constants';
import messages from './messages';

View File

@@ -5,7 +5,7 @@ import { initializeMockApp } from '@edx/frontend-platform';
import { IntlProvider } from '@edx/frontend-platform/i18n';
import { AppProvider } from '@edx/frontend-platform/react';
import { studioHomeMock } from '../../studio-home/__mocks__';
import studioHomeMock from '@src/studio-home/__mocks__/studioHomeMock';
import initializeStore from '../../store';
import CourseRerunForm from '.';

View File

@@ -14,7 +14,7 @@ import { getAuthenticatedHttpClient } from '@edx/frontend-platform/auth';
import { AppProvider } from '@edx/frontend-platform/react';
import MockAdapter from 'axios-mock-adapter';
import { studioHomeMock } from '../../studio-home/__mocks__';
import studioHomeMock from '@src/studio-home/__mocks__/studioHomeMock';
import { getStudioHomeApiUrl } from '../../studio-home/data/api';
import { fetchStudioHomeData } from '../../studio-home/data/thunks';
import { RequestStatus } from '../../data/constants';

View File

@@ -1,5 +1,5 @@
import { RequestStatus } from '../../../data/constants';
import { studioHomeMock } from '../../../studio-home/__mocks__';
import { RequestStatus } from '@src/data/constants';
import studioHomeMock from '@src/studio-home/__mocks__/studioHomeMock';
export const courseId = 'course-v1:edX+DemoX+Demo_Course';

View File

@@ -8,7 +8,8 @@ import {
screen,
waitFor,
within,
} from '../testUtils';
} from '@src/testUtils';
import studioHomeMock from '@src/studio-home/__mocks__/studioHomeMock';
import mockResult from './__mocks__/library-search.json';
import mockEmptyResult from '../search-modal/__mocks__/empty-search-result.json';
import {
@@ -19,7 +20,6 @@ import {
mockXBlockFields,
} from './data/api.mocks';
import { mockContentSearchConfig } from '../search-manager/data/api.mock';
import { studioHomeMock } from '../studio-home/__mocks__';
import { getStudioHomeApiUrl } from '../studio-home/data/api';
import { LibraryLayout } from '.';
import { getLibraryCollectionsApiUrl, getLibraryContainersApiUrl } from './data/api';

View File

@@ -8,7 +8,8 @@ import {
waitFor,
screen,
initializeMocks,
} from '../../testUtils';
} from '@src/testUtils';
import studioHomeMock from '@src/studio-home/__mocks__/studioHomeMock';
import mockResult from '../__mocks__/library-search.json';
import editorCmsApi from '../../editors/data/services/cms/api';
import * as textEditorHooks from '../../editors/containers/TextEditor/hooks';
@@ -19,7 +20,6 @@ import {
} from '../data/api.mocks';
import { mockClipboardEmpty } from '../../generic/data/api.mock';
import { mockContentSearchConfig, mockSearchResult } from '../../search-manager/data/api.mock';
import { studioHomeMock } from '../../studio-home/__mocks__';
import { getStudioHomeApiUrl } from '../../studio-home/data/api';
import LibraryLayout from '../LibraryLayout';

View File

@@ -1,12 +1,12 @@
import { mockContentSearchConfig, mockSearchResult } from '../../search-manager/data/api.mock';
import { mockContentSearchConfig, mockSearchResult } from '@src/search-manager/data/api.mock';
import {
fireEvent,
render as baseRender,
waitFor,
screen,
initializeMocks,
} from '../../testUtils';
import { studioHomeMock } from '../../studio-home/__mocks__';
} from '@src/testUtils';
import studioHomeMock from '@src/studio-home/__mocks__/studioHomeMock';
import { getStudioHomeApiUrl } from '../../studio-home/data/api';
import mockResult from '../__mocks__/library-search.json';
import { LibraryProvider } from '../common/context/LibraryContext';

View File

@@ -8,10 +8,10 @@ import {
render,
screen,
waitFor,
} from '../../testUtils';
import { studioHomeMock } from '../../studio-home/__mocks__';
import { getStudioHomeApiUrl } from '../../studio-home/data/api';
import { getApiWaffleFlagsUrl } from '../../data/api';
} from '@src/testUtils';
import studioHomeMock from '@src/studio-home/__mocks__/studioHomeMock';
import { getStudioHomeApiUrl } from '@src/studio-home/data/api';
import { getApiWaffleFlagsUrl } from '@src/data/api';
import { CreateLibrary } from '.';
import { getContentLibraryV2CreateApiUrl } from './data/api';

View File

@@ -1,13 +1,13 @@
import { useEffect } from 'react';
import fetchMock from 'fetch-mock-jest';
import { initializeMocks, render } from '@src/testUtils';
import studioHomeMock from '@src/studio-home/__mocks__/studioHomeMock';
import {
mockContentLibrary,
} from './data/api.mocks';
import { LibraryLayout } from '.';
import { ContentType, useLibraryRoutes } from './routes';
import mockResult from './__mocks__/library-search.json';
import { initializeMocks, render } from '../testUtils';
import { studioHomeMock } from '../studio-home/__mocks__';
import { getStudioHomeApiUrl } from '../studio-home/data/api';
const mockNavigate = jest.fn();

View File

@@ -1,289 +0,0 @@
import { useSelector } from 'react-redux';
import { MemoryRouter, Routes, Route } from 'react-router-dom';
import { RequestStatus } from '../data/constants';
import { COURSE_CREATOR_STATES } from '../constants';
import { studioHomeMock } from './__mocks__';
import { getStudioHomeApiUrl } from './data/api';
import {
act,
fireEvent,
render,
waitFor,
initializeMocks,
} from '../testUtils';
import messages from './messages';
import createNewCourseMessages from './create-new-course-form/messages';
import createOrRerunCourseMessages from '../generic/create-or-rerun-course/messages';
import { StudioHome } from '.';
const {
studioShortName,
studioRequestEmail,
} = studioHomeMock;
jest.mock('react-redux', () => ({
...jest.requireActual('react-redux'),
useSelector: jest.fn(),
}));
const mockNavigate = jest.fn();
jest.mock('react-router-dom', () => ({
...jest.requireActual('react-router-dom'), // use actual for all non-hook parts
useNavigate: () => mockNavigate,
}));
const RootWrapper = () => (
<MemoryRouter initialEntries={['/home']}>
<Routes>
<Route
path="/home"
element={<StudioHome />}
/>
<Route
path="/libraries"
element={<StudioHome />}
/>
<Route
path="/libraries-v1"
element={<StudioHome />}
/>
</Routes>,
</MemoryRouter>
);
describe('<StudioHome />', () => {
describe('api fetch fails', () => {
beforeEach(async () => {
const mocks = initializeMocks();
mocks.axiosMock.onGet(getStudioHomeApiUrl()).reply(404);
useSelector.mockReturnValue({ studioHomeLoadingStatus: RequestStatus.FAILED });
});
it('should render fetch error', () => {
const { getByText } = render(<RootWrapper />);
waitFor(() => {
expect(getByText(messages.homePageLoadFailedMessage.defaultMessage)).toBeInTheDocument();
});
});
it('should render Studio home title', () => {
const { getByText } = render(<RootWrapper />);
waitFor(() => {
expect(getByText('Studio home')).toBeInTheDocument();
});
});
});
describe('api fetch succeeds', () => {
beforeEach(async () => {
const mocks = initializeMocks();
mocks.axiosMock.onGet(getStudioHomeApiUrl()).reply(200, studioHomeMock);
useSelector.mockReturnValue(studioHomeMock);
});
it('should render page and page title correctly', () => {
const { getByText } = render(<RootWrapper />);
waitFor(() => {
expect(getByText(`${studioShortName} home`)).toBeInTheDocument();
});
});
it('should render email staff header button', async () => {
useSelector.mockReturnValue({
...studioHomeMock,
courseCreatorStatus: COURSE_CREATOR_STATES.disallowedForThisSite,
});
const { getByRole } = render(<RootWrapper />);
waitFor(() => {
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,
});
const { getByRole } = render(<RootWrapper />);
waitFor(() => {
expect(getByRole('button', { name: messages.addNewCourseBtnText.defaultMessage })).toBeInTheDocument();
});
});
it('should show verify email layout if user inactive', () => {
useSelector.mockReturnValue({
...studioHomeMock,
userIsActive: false,
});
const { getByText } = render(<RootWrapper />);
waitFor(() => {
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,
});
await act(async () => {
const { getByRole } = render(<RootWrapper />);
waitFor(() => {
const spinner = getByRole('status');
expect(spinner.textContent).toEqual('Loading...');
});
});
});
describe('render new library button', () => {
it('should navigate to home_library when libraries-v2 disabled', () => {
useSelector.mockReturnValue({
...studioHomeMock,
courseCreatorStatus: COURSE_CREATOR_STATES.granted,
librariesV2Enabled: false,
});
const studioBaseUrl = 'http://localhost:18010';
const { getByTestId } = render(<RootWrapper />);
waitFor(() => {
const createNewLibraryButton = getByTestId('new-library-button');
const { open } = window;
window.open = jest.fn();
fireEvent.click(createNewLibraryButton);
expect(window.open).toHaveBeenCalledWith(`${studioBaseUrl}/home_library`);
window.open = open;
});
});
it('should navigate to the library authoring page in course authoring', () => {
useSelector.mockReturnValue({
...studioHomeMock,
librariesV1Enabled: false,
});
const { getByTestId } = render(<RootWrapper />);
waitFor(() => {
const createNewLibraryButton = getByTestId('new-library-button');
fireEvent.click(createNewLibraryButton);
expect(mockNavigate).toHaveBeenCalledWith('/library/create');
});
});
});
it('do not render new library button for "v1 only" mode if showNewLibraryButton is False', () => {
useSelector.mockReturnValue({
...studioHomeMock,
showNewLibraryButton: false,
librariesV2Enabled: false,
});
const { queryByTestId } = render(<RootWrapper />);
expect(queryByTestId('new-library-button')).not.toBeInTheDocument();
});
it('render new library button for "v2 only" mode even if showNewLibraryButton is False', () => {
useSelector.mockReturnValue({
...studioHomeMock,
showNewLibraryButton: false,
librariesV1Enabled: false,
});
const { queryByTestId } = render(<RootWrapper />);
waitFor(() => {
expect(queryByTestId('new-library-button')).toBeInTheDocument();
});
});
it('should render create new course container', async () => {
useSelector.mockReturnValue({
...studioHomeMock,
courseCreatorStatus: COURSE_CREATOR_STATES.granted,
});
const { getByRole, getByText } = render(<RootWrapper />);
waitFor(() => {
const createNewCourseButton = getByRole('button', { name: messages.addNewCourseBtnText.defaultMessage });
act(() => fireEvent.click(createNewCourseButton));
expect(getByText(createNewCourseMessages.createNewCourse.defaultMessage)).toBeInTheDocument();
});
});
it('should hide create new course container', async () => {
useSelector.mockReturnValue({
...studioHomeMock,
courseCreatorStatus: COURSE_CREATOR_STATES.granted,
});
const { getByRole, queryByText, getByText } = render(<RootWrapper />);
waitFor(() => {
const createNewCourseButton = getByRole('button', { name: messages.addNewCourseBtnText.defaultMessage });
fireEvent.click(createNewCourseButton);
expect(getByText(createNewCourseMessages.createNewCourse.defaultMessage)).toBeInTheDocument();
});
waitFor(() => {
const cancelButton = getByRole('button', { name: createOrRerunCourseMessages.cancelButton.defaultMessage });
fireEvent.click(cancelButton);
expect(queryByText(createNewCourseMessages.createNewCourse.defaultMessage)).not.toBeInTheDocument();
});
});
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(<RootWrapper />);
const defaultTitleMessage = messages.defaultSection_1_Title.defaultMessage;
waitFor(() => {
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(<RootWrapper />);
const defaultTitleMessage = messages.defaultSection_1_Title.defaultMessage;
waitFor(() => {
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(<RootWrapper />);
waitFor(() => {
expect(getByText('Looking for help with Studio?')).toBeInTheDocument();
expect(getByText('LMS')).toHaveAttribute('href', process.env.LMS_BASE_URL);
});
});
});
});

View File

@@ -0,0 +1,237 @@
import * as reactRedux from 'react-redux';
import {
fireEvent,
render,
screen,
waitFor,
initializeMocks,
within,
} from '@src/testUtils';
import { RequestStatus } from '../data/constants';
import { COURSE_CREATOR_STATES } from '../constants';
import studioHomeMock from './__mocks__/studioHomeMock';
import { getStudioHomeApiUrl } from './data/api';
import { StudioHome } from '.';
const {
studioShortName,
studioRequestEmail,
} = studioHomeMock;
const mockUseSelector = jest.fn();
jest.spyOn(reactRedux, 'useSelector').mockImplementation(mockUseSelector);
const mockNavigate = jest.fn();
jest.mock('react-router-dom', () => ({
...jest.requireActual('react-router-dom'),
useNavigate: () => mockNavigate,
}));
/** Helper function to get the Studio header in the rendered HTML */
function getHeaderElement(): HTMLElement {
const header = screen.getByRole('banner');
expect(header.tagName).toEqual('HEADER');
return header;
}
describe('<StudioHome />', () => {
describe('api fetch fails', () => {
beforeEach(async () => {
const mocks = initializeMocks();
mocks.axiosMock.onGet(getStudioHomeApiUrl()).reply(404);
mockUseSelector.mockReturnValue({ studioHomeLoadingStatus: RequestStatus.FAILED });
});
it('should render fetch error', async () => {
render(<StudioHome />, { path: '/home' });
expect(screen.getByText('Failed to load Studio home. Please try again later.')).toBeInTheDocument();
});
it('should render Studio home title', async () => {
render(<StudioHome />, { path: '/home' });
// Search only within the header; don't match on the similar text in the body's error message.
const header = getHeaderElement();
expect(within(header).getByText('Studio home')).toBeInTheDocument();
});
});
describe('api fetch succeeds', () => {
beforeEach(async () => {
const mocks = initializeMocks();
mocks.axiosMock.onGet(getStudioHomeApiUrl()).reply(200, studioHomeMock);
mockUseSelector.mockReturnValue(studioHomeMock);
});
it('should render page and page title correctly', async () => {
render(<StudioHome />, { path: '/home' });
const header = getHeaderElement();
expect(within(header).getByText(`${studioShortName} home`)).toBeInTheDocument();
});
it('should render "email staff" header button for users without create permission', async () => {
mockUseSelector.mockReturnValue({
...studioHomeMock,
courseCreatorStatus: COURSE_CREATOR_STATES.disallowedForThisSite,
});
render(<StudioHome />, { path: '/home' });
const header = getHeaderElement();
const link = within(header).getByRole('link', { name: 'Email staff to create course' });
expect(link).toHaveAttribute('href', `mailto:${studioRequestEmail}`);
});
it('should render create new course button for users with create permission', async () => {
mockUseSelector.mockReturnValue({
...studioHomeMock,
courseCreatorStatus: COURSE_CREATOR_STATES.granted,
});
render(<StudioHome />, { path: '/home' });
const header = getHeaderElement();
within(header).getByRole('button', { name: 'New course' }); // will error if not found
});
it('should show verify email layout if user inactive', async () => {
mockUseSelector.mockReturnValue({
...studioHomeMock,
userIsActive: false,
});
render(<StudioHome />, { path: '/home' });
screen.getByText('Thanks for signing up, abc123!', { exact: false }); // will error if not found
});
it('shows the spinner before the query is complete', async () => {
mockUseSelector.mockReturnValue({
studioHomeLoadingStatus: RequestStatus.IN_PROGRESS,
userIsActive: true,
});
render(<StudioHome />, { path: '/home' });
const spinner = screen.getByRole('status');
expect(spinner.textContent).toEqual('Loading...');
});
describe('render new library button', () => {
it('should navigate to home_library when libraries-v2 disabled', async () => {
mockUseSelector.mockReturnValue({
...studioHomeMock,
courseCreatorStatus: COURSE_CREATOR_STATES.granted,
librariesV2Enabled: false,
});
const studioBaseUrl = 'http://localhost:18010';
render(<StudioHome />, { path: '/home' });
await waitFor(() => {
const createNewLibraryButton = screen.getByRole('button', { name: 'New library' });
const mockWindowOpen = jest.spyOn(window, 'open');
fireEvent.click(createNewLibraryButton);
expect(mockWindowOpen).toHaveBeenCalledWith(`${studioBaseUrl}/home_library`);
mockWindowOpen.mockRestore();
});
});
it('should navigate to the library authoring page in course authoring', async () => {
mockUseSelector.mockReturnValue({
...studioHomeMock,
librariesV1Enabled: false,
});
render(<StudioHome />, { path: '/home' });
const createNewLibraryButton = screen.getByRole('button', { name: 'New library' });
fireEvent.click(createNewLibraryButton);
expect(mockNavigate).toHaveBeenCalledWith('/library/create');
});
});
it('does not render new library button for "v1 only" mode if showNewLibraryButton is False', () => {
mockUseSelector.mockReturnValue({
...studioHomeMock,
showNewLibraryButton: false,
librariesV2Enabled: false,
});
render(<StudioHome />, { path: '/home' });
expect(screen.queryByRole('button', { name: 'New library' })).not.toBeInTheDocument();
});
it('render new library button for "v2 only" mode even if showNewLibraryButton is False', () => {
mockUseSelector.mockReturnValue({
...studioHomeMock,
showNewLibraryButton: false,
librariesV1Enabled: false,
});
render(<StudioHome />, { path: '/home' });
expect(screen.queryByRole('button', { name: 'New library' })).toBeInTheDocument();
});
it('should render "create new course" container', async () => {
mockUseSelector.mockReturnValue({
...studioHomeMock,
courseCreatorStatus: COURSE_CREATOR_STATES.granted,
});
const newCourseContainerText = 'Create a new course';
render(<StudioHome />, { path: '/home' });
expect(screen.queryByText(newCourseContainerText)).not.toBeInTheDocument();
const createNewCourseButton = screen.getByRole('button', { name: 'New course' });
fireEvent.click(createNewCourseButton);
expect(screen.queryByText(newCourseContainerText)).toBeInTheDocument();
});
it('should hide "create new course" container', async () => {
mockUseSelector.mockReturnValue({
...studioHomeMock,
courseCreatorStatus: COURSE_CREATOR_STATES.granted,
});
const newCourseContainerText = 'Create a new course';
render(<StudioHome />, { path: '/home' });
const createNewCourseButton = screen.getByRole('button', { name: 'New course' });
fireEvent.click(createNewCourseButton);
expect(screen.queryByText(newCourseContainerText)).toBeInTheDocument();
const cancelButton = screen.getByRole('button', { name: 'Cancel' });
fireEvent.click(cancelButton);
expect(screen.queryByText(newCourseContainerText)).not.toBeInTheDocument();
});
describe('contact administrator card', () => {
const adminCardTitleText = 'Are you staff on an existing Studio course?';
it('should show the "contact administrator" card with no "add course" buttons', () => {
mockUseSelector.mockReturnValue({
...studioHomeMock,
courses: [],
courseCreatorStatus: COURSE_CREATOR_STATES.pending,
});
render(<StudioHome />, { path: '/home' });
const administratorCardTitle = screen.getByText(adminCardTitleText);
expect(administratorCardTitle).toBeVisible();
expect(screen.queryByText('Create your first course')).not.toBeInTheDocument();
});
it('should show contact administrator card with add course buttons', () => {
mockUseSelector.mockReturnValue({
...studioHomeMock,
courses: [],
courseCreatorStatus: COURSE_CREATOR_STATES.granted,
});
render(<StudioHome />, { path: '/home' });
const administratorCardTitle = screen.getByText(adminCardTitleText);
expect(administratorCardTitle).toBeVisible();
const addCourseButton = screen.getByTestId('contact-admin-create-course');
expect(addCourseButton).toBeVisible();
fireEvent.click(addCourseButton);
expect(screen.getByTestId('create-course-form')).toBeVisible();
});
});
it('should show footer', () => {
render(<StudioHome />, { path: '/home' });
expect(screen.getByText('Looking for help with Studio?')).toBeInTheDocument();
expect(screen.getByText('LMS')).toHaveAttribute('href', process.env.LMS_BASE_URL);
});
});
});

View File

@@ -102,7 +102,6 @@ const StudioHome = () => {
iconBefore={AddIcon}
size="sm"
onClick={newLibraryClick}
data-testid="new-library-button"
>
{intl.formatMessage(messages.addNewLibraryBtnText)}
</Button>,

View File

@@ -1 +0,0 @@
export { default as studioHomeMock } from './studioHomeMock';

View File

@@ -1,4 +1,4 @@
module.exports = {
export default {
activeTab: 'courses',
allowCourseReruns: true,
allowedOrganizations: ['edx', 'org'],

View File

@@ -1,15 +1,15 @@
import * as reactRedux from 'react-redux';
import { getConfig } from '@edx/frontend-platform';
import { studioHomeMock } from '../__mocks__';
import messages from '../messages';
import { trimSlashes } from './utils';
import {
fireEvent,
initializeMocks,
render,
screen,
} from '../../testUtils';
} from '@src/testUtils';
import studioHomeMock from '@src/studio-home/__mocks__/studioHomeMock';
import messages from '../messages';
import { trimSlashes } from './utils';
import CardItem from '.';
jest.spyOn(reactRedux, 'useSelector').mockImplementation(() => studioHomeMock);

View File

@@ -9,12 +9,12 @@ import { AppProvider } from '@edx/frontend-platform/react';
import MockAdapter from 'axios-mock-adapter';
import { getAuthenticatedHttpClient } from '@edx/frontend-platform/auth';
import studioHomeMock from '@src/studio-home/__mocks__/studioHomeMock';
import { COURSE_CREATOR_STATES } from '../../constants';
import initializeStore from '../../store';
import { executeThunk } from '../../utils';
import { requestCourseCreatorQuery } from '../data/thunks';
import { getRequestCourseCreatorUrl } from '../data/api';
import { studioHomeMock } from '../__mocks__';
import messages from './messages';
import CollapsibleStateWithAction from '.';

View File

@@ -5,7 +5,7 @@ import { initializeMockApp } from '@edx/frontend-platform';
import { IntlProvider } from '@edx/frontend-platform/i18n';
import { AppProvider } from '@edx/frontend-platform/react';
import { studioHomeMock } from '../__mocks__';
import studioHomeMock from '@src/studio-home/__mocks__/studioHomeMock';
import initializeStore from '../../store';
import messages from './messages';
import CourseNewCourseForm from '.';

View File

@@ -1,8 +1,8 @@
import { useSelector } from 'react-redux';
import { initializeMocks, render } from '../../testUtils';
import { COURSE_CREATOR_STATES } from '../../constants';
import { studioHomeMock } from '../__mocks__';
import { initializeMocks, render } from '@src/testUtils';
import { COURSE_CREATOR_STATES } from '@src/constants';
import studioHomeMock from '@src/studio-home/__mocks__/studioHomeMock';
import HomeSidebar from '.';
jest.mock('react-redux', () => ({

View File

@@ -5,8 +5,8 @@ import { IntlProvider } from '@edx/frontend-platform/i18n';
import { initializeMockApp } from '@edx/frontend-platform';
import { AppProvider } from '@edx/frontend-platform/react';
import studioHomeMock from '@src/studio-home/__mocks__/studioHomeMock';
import initializeStore from '../../store';
import { studioHomeMock } from '../__mocks__';
import messages from './messages';
import ProcessingCourses from '.';

View File

@@ -1,7 +1,7 @@
import { Routes, Route, useLocation } from 'react-router-dom';
import { getConfig, setConfig } from '@edx/frontend-platform';
import { studioHomeMock } from '../__mocks__';
import studioHomeMock from '@src/studio-home/__mocks__/studioHomeMock';
import messages from '../messages';
import tabMessages from './messages';
import TabsSection from '.';

View File

@@ -3,9 +3,9 @@ import {
initializeMocks,
render,
screen,
} from '../../../testUtils';
import { COURSE_CREATOR_STATES } from '../../../constants';
import { studioHomeMock } from '../../__mocks__';
} from '@src/testUtils';
import { COURSE_CREATOR_STATES } from '@src/constants';
import studioHomeMock from '@src/studio-home/__mocks__/studioHomeMock';
import { initialState } from '../../factories/mockApiResponses';
import CoursesTab from '.';