Skip to content

Commit 7924f5a

Browse files
test: update tests accordingly
1 parent 48b58c6 commit 7924f5a

File tree

7 files changed

+87
-170
lines changed

7 files changed

+87
-170
lines changed

src/library-authoring/LibraryLayout.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ const LibraryLayout = () => {
5050
}, [goBack]);
5151

5252
return (
53-
<LibraryProvider>
53+
<LibraryProvider libraryId={libraryId}>
5454
<Routes>
5555
{/*
5656
TODO: we should be opening this editor as a modal, not making it a separate page/URL.

src/library-authoring/add-content/AddContentContainer.test.tsx

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,30 @@
11
import {
22
fireEvent,
3-
render,
3+
render as baseRender,
44
screen,
55
waitFor,
66
initializeMocks,
77
} from '../../testUtils';
88
import { mockContentLibrary } from '../data/api.mocks';
99
import { getCreateLibraryBlockUrl, getLibraryPasteClipboardUrl } from '../data/api';
1010
import { mockBroadcastChannel, mockClipboardEmpty, mockClipboardHtml } from '../../generic/data/api.mock';
11+
import { LibraryProvider } from '../common/context';
1112
import AddContentContainer from './AddContentContainer';
1213

1314
mockBroadcastChannel();
1415

1516
const { libraryId } = mockContentLibrary;
16-
const renderOpts = { path: '/library/:libraryId/*', params: { libraryId } };
17+
const render = () => baseRender(<AddContentContainer />, {
18+
path: '/library/:libraryId/*',
19+
params: { libraryId },
20+
extraWrapper: ({ children }) => <LibraryProvider libraryId={libraryId}>{ children }</LibraryProvider>,
21+
});
1722

1823
describe('<AddContentContainer />', () => {
1924
it('should render content buttons', () => {
2025
initializeMocks();
2126
mockClipboardEmpty.applyMock();
22-
render(<AddContentContainer />);
27+
render();
2328
expect(screen.getByRole('button', { name: /collection/i })).toBeInTheDocument();
2429
expect(screen.getByRole('button', { name: /text/i })).toBeInTheDocument();
2530
expect(screen.getByRole('button', { name: /problem/i })).toBeInTheDocument();
@@ -36,7 +41,7 @@ describe('<AddContentContainer />', () => {
3641
const url = getCreateLibraryBlockUrl(libraryId);
3742
axiosMock.onPost(url).reply(200);
3843

39-
render(<AddContentContainer />, renderOpts);
44+
render();
4045

4146
const textButton = screen.getByRole('button', { name: /text/i });
4247
fireEvent.click(textButton);
@@ -48,9 +53,9 @@ describe('<AddContentContainer />', () => {
4853
initializeMocks();
4954
// Simulate having an HTML block in the clipboard:
5055
const getClipboardSpy = mockClipboardHtml.applyMock();
51-
const doc = render(<AddContentContainer />, renderOpts);
56+
render();
5257
expect(getClipboardSpy).toHaveBeenCalled(); // Hmm, this is getting called three times! Refactor to use react-query.
53-
await waitFor(() => expect(doc.queryByRole('button', { name: /paste from clipboard/i })).toBeInTheDocument());
58+
await waitFor(() => expect(screen.queryByRole('button', { name: /paste from clipboard/i })).toBeInTheDocument());
5459
});
5560

5661
it('should paste content', async () => {
@@ -61,7 +66,7 @@ describe('<AddContentContainer />', () => {
6166
const pasteUrl = getLibraryPasteClipboardUrl(libraryId);
6267
axiosMock.onPost(pasteUrl).reply(200);
6368

64-
render(<AddContentContainer />, renderOpts);
69+
render();
6570

6671
expect(getClipboardSpy).toHaveBeenCalled(); // Hmm, this is getting called four times! Refactor to use react-query.
6772

@@ -79,7 +84,7 @@ describe('<AddContentContainer />', () => {
7984
const pasteUrl = getLibraryPasteClipboardUrl(libraryId);
8085
axiosMock.onPost(pasteUrl).reply(400);
8186

82-
render(<AddContentContainer />, renderOpts);
87+
render();
8388

8489
const pasteButton = await screen.findByRole('button', { name: /paste from clipboard/i });
8590
fireEvent.click(pasteButton);

src/library-authoring/common/context.tsx

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import { useToggle } from '@openedx/paragon';
22
import React from 'react';
3-
import { useParams } from 'react-router-dom';
43

54
export enum SidebarBodyComponentId {
65
AddContent = 'add-content',
@@ -41,13 +40,7 @@ const LibraryContext = React.createContext<LibraryContextData | undefined>(undef
4140
/**
4241
* React component to provide `LibraryContext`
4342
*/
44-
export const LibraryProvider = (props: { children?: React.ReactNode }) => {
45-
const { libraryId } = useParams();
46-
47-
if (libraryId === undefined) {
48-
// istanbul ignore next - This shouldn't be possible; it's just here to satisfy the type checker.
49-
throw new Error('Error: route is missing libraryId.');
50-
}
43+
export const LibraryProvider = (props: { children?: React.ReactNode, libraryId: string }) => {
5144
const [sidebarBodyComponent, setSidebarBodyComponent] = React.useState<SidebarBodyComponentId | null>(null);
5245
const [currentComponentUsageKey, setCurrentComponentUsageKey] = React.useState<string>();
5346
const [currentCollectionId, setcurrentCollectionId] = React.useState<string>();
@@ -86,7 +79,7 @@ export const LibraryProvider = (props: { children?: React.ReactNode }) => {
8679
}, []);
8780

8881
const context = React.useMemo<LibraryContextData>(() => ({
89-
libraryId,
82+
libraryId: props.libraryId,
9083
sidebarBodyComponent,
9184
closeLibrarySidebar,
9285
openAddContentSidebar,
@@ -99,7 +92,7 @@ export const LibraryProvider = (props: { children?: React.ReactNode }) => {
9992
openCollectionInfoSidebar,
10093
currentCollectionId,
10194
}), [
102-
libraryId,
95+
props.libraryId,
10396
sidebarBodyComponent,
10497
closeLibrarySidebar,
10598
openAddContentSidebar,

src/library-authoring/components/CollectionCard.test.tsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
1+
import React from 'react';
12
import {
23
initializeMocks,
34
fireEvent,
4-
render,
5+
render as baseRender,
56
screen,
67
} from '../../testUtils';
78

9+
import { LibraryProvider } from '../common/context';
810
import { type CollectionHit } from '../../search-manager';
911
import CollectionCard from './CollectionCard';
1012

@@ -28,6 +30,10 @@ const CollectionHitSample: CollectionHit = {
2830
tags: {},
2931
};
3032

33+
const render = (ui: React.ReactElement) => baseRender(ui, {
34+
extraWrapper: ({ children }) => <LibraryProvider libraryId="lib:Axim:TEST">{ children }</LibraryProvider>,
35+
});
36+
3137
describe('<CollectionCard />', () => {
3238
beforeEach(() => {
3339
initializeMocks();
Lines changed: 31 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,21 @@
1-
import React from 'react';
2-
import { AppProvider } from '@edx/frontend-platform/react';
3-
import { initializeMockApp } from '@edx/frontend-platform';
4-
import { getAuthenticatedHttpClient } from '@edx/frontend-platform/auth';
5-
import { IntlProvider } from '@edx/frontend-platform/i18n';
6-
import { render, fireEvent, waitFor } from '@testing-library/react';
7-
import MockAdapter from 'axios-mock-adapter';
8-
import type { Store } from 'redux';
9-
10-
import { ToastProvider } from '../../generic/toast-context';
1+
import {
2+
fireEvent,
3+
render as baseRender,
4+
screen,
5+
waitFor,
6+
initializeMocks,
7+
} from '../../testUtils';
8+
import { LibraryProvider } from '../common/context';
119
import { getClipboardUrl } from '../../generic/data/api';
1210
import { ContentHit } from '../../search-manager';
13-
import initializeStore from '../../store';
1411
import ComponentCard from './ComponentCard';
1512

16-
let store: Store;
17-
let axiosMock: MockAdapter;
18-
1913
const contentHit: ContentHit = {
2014
id: '1',
2115
usageKey: 'lb:org1:demolib:html:a1fa8bdd-dc67-4976-9bf5-0ea75a9bca3d',
2216
type: 'library_block',
2317
blockId: 'a1fa8bdd-dc67-4976-9bf5-0ea75a9bca3d',
24-
contextKey: 'lb:org1:Demo_Course',
18+
contextKey: 'lib:org1:Demo_Course',
2519
org: 'org1',
2620
breadcrumbs: [{ displayName: 'Demo Lib' }],
2721
displayName: 'Text Display Name',
@@ -47,87 +41,63 @@ const clipboardBroadcastChannelMock = {
4741

4842
(global as any).BroadcastChannel = jest.fn(() => clipboardBroadcastChannelMock);
4943

50-
const RootWrapper = () => (
51-
<AppProvider store={store}>
52-
<IntlProvider locale="en">
53-
<ToastProvider>
54-
<ComponentCard
55-
contentHit={contentHit}
56-
blockTypeDisplayName="text"
57-
/>
58-
</ToastProvider>
59-
</IntlProvider>
60-
</AppProvider>
61-
);
44+
const libraryId = 'lib:org1:Demo_Course';
45+
const render = () => baseRender(<ComponentCard contentHit={contentHit} blockTypeDisplayName="text" />, {
46+
extraWrapper: ({ children }) => <LibraryProvider libraryId={libraryId}>{ children }</LibraryProvider>,
47+
});
6248

6349
describe('<ComponentCard />', () => {
64-
beforeEach(() => {
65-
initializeMockApp({
66-
authenticatedUser: {
67-
userId: 3,
68-
username: 'abc123',
69-
administrator: true,
70-
roles: [],
71-
},
72-
});
73-
store = initializeStore();
74-
75-
axiosMock = new MockAdapter(getAuthenticatedHttpClient());
76-
});
77-
78-
afterEach(() => {
79-
jest.clearAllMocks();
80-
axiosMock.restore();
81-
});
82-
8350
it('should render the card with title and description', () => {
84-
const { getByText } = render(<RootWrapper />);
51+
initializeMocks();
52+
render();
8553

86-
expect(getByText('Text Display Formated Name')).toBeInTheDocument();
87-
expect(getByText('This is a text: ID=1')).toBeInTheDocument();
54+
expect(screen.getByText('Text Display Formated Name')).toBeInTheDocument();
55+
expect(screen.getByText('This is a text: ID=1')).toBeInTheDocument();
8856
});
8957

9058
it('should call the updateClipboard function when the copy button is clicked', async () => {
59+
const { axiosMock, mockShowToast } = initializeMocks();
9160
axiosMock.onPost(getClipboardUrl()).reply(200, {});
92-
const { getByRole, getByTestId, getByText } = render(<RootWrapper />);
61+
render();
9362

9463
// Open menu
95-
expect(getByTestId('component-card-menu-toggle')).toBeInTheDocument();
96-
fireEvent.click(getByTestId('component-card-menu-toggle'));
64+
expect(screen.getByTestId('component-card-menu-toggle')).toBeInTheDocument();
65+
fireEvent.click(screen.getByTestId('component-card-menu-toggle'));
9766

9867
// Click copy to clipboard
99-
expect(getByRole('button', { name: 'Copy to clipboard' })).toBeInTheDocument();
100-
fireEvent.click(getByRole('button', { name: 'Copy to clipboard' }));
68+
expect(screen.getByRole('button', { name: 'Copy to clipboard' })).toBeInTheDocument();
69+
fireEvent.click(screen.getByRole('button', { name: 'Copy to clipboard' }));
10170

10271
expect(axiosMock.history.post.length).toBe(1);
10372
expect(axiosMock.history.post[0].data).toBe(
10473
JSON.stringify({ usage_key: contentHit.usageKey }),
10574
);
10675

10776
await waitFor(() => {
108-
expect(getByText('Component copied to clipboard')).toBeInTheDocument();
77+
expect(mockShowToast).toHaveBeenCalledWith('Component copied to clipboard');
10978
});
11079
});
11180

11281
it('should show error message if the api call fails', async () => {
82+
const { axiosMock, mockShowToast } = initializeMocks();
11383
axiosMock.onPost(getClipboardUrl()).reply(400);
114-
const { getByRole, getByTestId, getByText } = render(<RootWrapper />);
84+
render();
11585

11686
// Open menu
117-
expect(getByTestId('component-card-menu-toggle')).toBeInTheDocument();
118-
fireEvent.click(getByTestId('component-card-menu-toggle'));
87+
expect(screen.getByTestId('component-card-menu-toggle')).toBeInTheDocument();
88+
fireEvent.click(screen.getByTestId('component-card-menu-toggle'));
11989

12090
// Click copy to clipboard
121-
expect(getByRole('button', { name: 'Copy to clipboard' })).toBeInTheDocument();
122-
fireEvent.click(getByRole('button', { name: 'Copy to clipboard' }));
91+
expect(screen.getByRole('button', { name: 'Copy to clipboard' })).toBeInTheDocument();
92+
fireEvent.click(screen.getByRole('button', { name: 'Copy to clipboard' }));
12393

12494
expect(axiosMock.history.post.length).toBe(1);
12595
expect(axiosMock.history.post[0].data).toBe(
12696
JSON.stringify({ usage_key: contentHit.usageKey }),
12797
);
12898

12999
await waitFor(() => {
130-
expect(getByText('Failed to copy component to clipboard')).toBeInTheDocument();
100+
expect(mockShowToast).toHaveBeenCalledWith('Failed to copy component to clipboard');
131101
});
132102
});
133103
});

0 commit comments

Comments
 (0)