|
1 | 1 | import React, { Suspense } from 'react';
|
2 |
| -import { BrowserRouter } from 'react-router-dom'; |
3 |
| -import { render } from '@testing-library/react'; |
| 2 | +import { useParams } from 'react-router-dom'; |
| 3 | +import { render, screen, waitFor } from '@testing-library/react'; |
| 4 | +import { IntlProvider } from '@edx/frontend-platform/i18n'; |
| 5 | +import { AppProvider } from '@edx/frontend-platform/react'; |
| 6 | +import { initializeMockApp } from '@edx/frontend-platform/testing'; |
4 | 7 |
|
| 8 | +import PagesAndResourcesProvider from 'CourseAuthoring/pages-and-resources/PagesAndResourcesProvider'; |
| 9 | +import initializeStore from 'CourseAuthoring/store'; |
| 10 | +import { RequestStatus } from 'CourseAuthoring/data/constants'; |
5 | 11 | import SettingsComponent from './SettingsComponent';
|
6 | 12 |
|
7 | 13 | jest.mock('react-router-dom', () => ({
|
8 | 14 | ...jest.requireActual('react-router-dom'),
|
9 |
| - useParams: () => ({ |
10 |
| - appId: 'wiki', |
11 |
| - }), |
| 15 | + useParams: jest.fn(), |
12 | 16 | }));
|
13 | 17 |
|
| 18 | +jest.mock('CourseAuthoring/utils', () => ({ |
| 19 | + useAppSetting: () => [false, () => undefined], |
| 20 | + useIsMobile: () => false, |
| 21 | +})); |
| 22 | + |
| 23 | +let store; |
| 24 | + |
| 25 | +// eslint-disable-next-line react/prop-types |
| 26 | +const RequiredProviders = ({ children }) => ( |
| 27 | + <IntlProvider locale="en" messages={{}}> |
| 28 | + <AppProvider store={store}> |
| 29 | + <PagesAndResourcesProvider courseId="course-v1:foo+bar+baz"> |
| 30 | + {children} |
| 31 | + </PagesAndResourcesProvider> |
| 32 | + </AppProvider> |
| 33 | + </IntlProvider> |
| 34 | +); |
| 35 | + |
14 | 36 | describe('SettingsComponent', () => {
|
| 37 | + beforeEach(async () => { |
| 38 | + initializeMockApp(); |
| 39 | + store = initializeStore({ |
| 40 | + models: { |
| 41 | + courseApps: { |
| 42 | + wiki: {}, |
| 43 | + }, |
| 44 | + }, |
| 45 | + pagesAndResources: { |
| 46 | + loadingStatus: RequestStatus.SUCCESSFUL, |
| 47 | + }, |
| 48 | + }); |
| 49 | + }); |
| 50 | + |
15 | 51 | test('renders LazyLoadedComponent when provided with props', async () => {
|
16 |
| - const { asFragment } = render( |
17 |
| - <BrowserRouter> |
18 |
| - <Suspense fallback="..."> |
19 |
| - <SettingsComponent url="/some-url" /> |
20 |
| - </Suspense> |
21 |
| - </BrowserRouter>, |
| 52 | + useParams.mockImplementation(() => ({ appId: 'wiki' })); |
| 53 | + |
| 54 | + const rendered = render( |
| 55 | + <Suspense fallback="..."> |
| 56 | + <SettingsComponent url="/some-url" /> |
| 57 | + </Suspense>, |
| 58 | + { wrapper: RequiredProviders }, |
| 59 | + ); |
| 60 | + |
| 61 | + await waitFor(() => expect(rendered.getByText('Configure wiki')).toBeInTheDocument()); |
| 62 | + |
| 63 | + const modalComponent = screen.getByRole('dialog'); |
| 64 | + expect(modalComponent.querySelector('#enable-wiki-toggleHelpText')).toContainHTML('The course wiki can be set up'); |
| 65 | + }); |
| 66 | + |
| 67 | + test('renders error message when plugin is unavilable when provided with props', async () => { |
| 68 | + // Silence noisy error about the plugin failing to load, when we do that deliberately. |
| 69 | + jest.spyOn(console, 'trace').mockImplementation(() => {}); |
| 70 | + // Specify an invalid course app, with no matching plugin: |
| 71 | + useParams.mockImplementation(() => ({ appId: 'invalid-plugin' })); |
| 72 | + |
| 73 | + const rendered = render( |
| 74 | + <Suspense fallback="..."> |
| 75 | + <SettingsComponent url="/some-url" /> |
| 76 | + </Suspense>, |
| 77 | + { wrapper: RequiredProviders }, |
22 | 78 | );
|
23 | 79 |
|
24 |
| - expect(asFragment).toMatchSnapshot(); |
| 80 | + const errorMessage = 'An error occurred when loading the configuration UI'; |
| 81 | + await waitFor(() => expect(rendered.container).toHaveTextContent(errorMessage)); |
25 | 82 | });
|
26 | 83 | });
|
0 commit comments