Skip to content

Commit 368ada5

Browse files
committed
test: add tests
1 parent 3eb1582 commit 368ada5

File tree

4 files changed

+136
-2
lines changed

4 files changed

+136
-2
lines changed

src/library-authoring/data/api.mocks.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@ export const mockGetContentLibraryV2List = {
1717
applyMock: () => jest.spyOn(api, 'getContentLibraryV2List').mockResolvedValue(
1818
camelCaseObject(contentLibrariesListV2),
1919
),
20+
applyMockNoPagination: () => jest.spyOn(api, 'getContentLibraryV2List').mockResolvedValue(
21+
camelCaseObject(contentLibrariesListV2.results),
22+
),
23+
applyMockNoPaginationEmpty: () => jest.spyOn(api, 'getContentLibraryV2List').mockResolvedValue([] as api.ContentLibrary[]),
2024
applyMockError: () => jest.spyOn(api, 'getContentLibraryV2List').mockRejectedValue(
2125
createAxiosError({ code: 500, message: 'Internal Error.', path: api.getContentLibraryV2ListApiUrl() }),
2226
),

src/library-authoring/data/api.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -409,7 +409,7 @@ export async function getContentLibraryV2List(
409409
): Promise<LibrariesV2Response>;
410410
export async function getContentLibraryV2List(
411411
customParams: GetLibrariesV2CustomParams
412-
): Promise<LibrariesV2Response>;
412+
): Promise<LibrariesV2Response | ContentLibrary[]>;
413413
export async function getContentLibraryV2List(
414414
customParams: GetLibrariesV2CustomParams,
415415
): Promise<LibrariesV2Response | ContentLibrary[]> {
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
import { mockContentLibrary, mockGetContentLibraryV2List } from '@src/library-authoring/data/api.mocks';
2+
import {
3+
initializeMocks, render, screen, waitFor,
4+
} from '@src/testUtils';
5+
import { userEvent } from '@testing-library/user-event';
6+
import { LibraryDropdownFilter } from './LibraryDropdownFilter';
7+
8+
mockContentLibrary.applyMock();
9+
10+
const mockSetValue = jest.fn();
11+
let mockValue: string[] = [];
12+
jest.mock('@src/library-authoring/common/context/LibraryContext', () => ({
13+
useLibraryContext: () => ({
14+
selectedLibraries: mockValue,
15+
setSelectedLibraries: mockSetValue,
16+
}),
17+
}));
18+
19+
const renderComponent = () => render(<LibraryDropdownFilter />);
20+
21+
describe('LibraryDropdownFilter', () => {
22+
beforeEach(() => {
23+
initializeMocks();
24+
mockValue = [];
25+
});
26+
27+
it('should render the loading status', async () => {
28+
const user = userEvent.setup();
29+
mockGetContentLibraryV2List.applyMockLoading();
30+
renderComponent();
31+
32+
const dropdownTrigger = await screen.findByRole('button', { name: 'All libraries' });
33+
expect(dropdownTrigger).toBeInTheDocument();
34+
await user.click(dropdownTrigger);
35+
36+
expect(await screen.findByText('Loading...')).toBeInTheDocument();
37+
});
38+
39+
it('should render the empty list', async () => {
40+
const user = userEvent.setup();
41+
mockGetContentLibraryV2List.applyMockNoPaginationEmpty();
42+
renderComponent();
43+
44+
const dropdownTrigger = await screen.findByRole('button', { name: 'All libraries' });
45+
expect(dropdownTrigger).toBeInTheDocument();
46+
await user.click(dropdownTrigger);
47+
48+
expect(await screen.findByText('No libraries found!')).toBeInTheDocument();
49+
});
50+
51+
it('should render LibraryDropdownFilter with dropdown options', async () => {
52+
const user = userEvent.setup();
53+
mockGetContentLibraryV2List.applyMockNoPagination();
54+
renderComponent();
55+
56+
const dropdownTrigger = await screen.findByRole('button', { name: 'All libraries' });
57+
expect(dropdownTrigger).toBeInTheDocument();
58+
await user.click(dropdownTrigger);
59+
60+
const item = await screen.findByRole('checkbox', { name: 'Test Library 1' });
61+
expect(item).toBeInTheDocument();
62+
await user.click(item);
63+
const passedFunction = mockSetValue.mock.calls[0][0];
64+
expect(passedFunction([])).toEqual(['lib:SampleTaxonomyOrg1:TL1']);
65+
});
66+
67+
it('toggle selected value', async () => {
68+
const user = userEvent.setup();
69+
mockGetContentLibraryV2List.applyMockNoPagination();
70+
renderComponent();
71+
72+
const dropdownTrigger = await screen.findByRole('button', { name: 'All libraries' });
73+
await user.click(dropdownTrigger);
74+
75+
const item = await screen.findByRole('checkbox', { name: 'Test Library 1' });
76+
await user.click(item);
77+
const passedFunction = mockSetValue.mock.calls[0][0];
78+
// Should remove it from list if already selected, i.e., it means user unselected it.
79+
expect(passedFunction([
80+
'lib:SampleTaxonomyOrg1:TL1',
81+
'lib:SampleTaxonomyOrg1:TL2',
82+
])).toEqual(['lib:SampleTaxonomyOrg1:TL2']);
83+
});
84+
85+
it('should update label to library if one is selected', async () => {
86+
mockGetContentLibraryV2List.applyMockNoPagination();
87+
mockValue = ['lib:SampleTaxonomyOrg1:TL1'];
88+
renderComponent();
89+
90+
const dropdownTrigger = await screen.findByRole('button', { name: 'Test Library 1' });
91+
expect(dropdownTrigger).toBeInTheDocument();
92+
});
93+
94+
it('should update label to n libraries if more than one is selected', async () => {
95+
mockGetContentLibraryV2List.applyMockNoPagination();
96+
mockValue = ['lib:SampleTaxonomyOrg1:TL1', 'lib:SampleTaxonomyOrg1:AL1'];
97+
renderComponent();
98+
99+
const dropdownTrigger = await screen.findByRole('button', { name: '2 Libraries' });
100+
expect(dropdownTrigger).toBeInTheDocument();
101+
});
102+
103+
it('should filter list by search', async () => {
104+
const user = userEvent.setup();
105+
const mockApi = mockGetContentLibraryV2List.applyMockNoPagination();
106+
renderComponent();
107+
108+
const dropdownTrigger = await screen.findByRole('button', { name: 'All libraries' });
109+
expect(dropdownTrigger).toBeInTheDocument();
110+
await user.click(dropdownTrigger);
111+
112+
const searchInput = await screen.findByPlaceholderText('Search Library Name');
113+
await user.type(searchInput, 'Test Library');
114+
115+
await waitFor(() => expect(mockApi).toHaveBeenLastCalledWith({
116+
pagination: false,
117+
search: 'Test Library',
118+
}), { timeout: 600 });
119+
120+
const clearBtn = await screen.findByRole('button', { name: 'clear search' });
121+
await user.click(clearBtn);
122+
123+
await waitFor(() => expect(mockApi).toHaveBeenLastCalledWith({
124+
pagination: false,
125+
search: '',
126+
}), { timeout: 600 });
127+
});
128+
});

src/library-authoring/library-filters/LibraryDropdownFilter.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ const LibraryItems = ({ isPending, data, onChange }: LibraryItemsProps) => {
3535
className="m-0 p-0"
3636
style={{ 'max-height': '25vh' }}
3737
>
38-
{data?.map((library) => (
38+
{data.map((library) => (
3939
<Dropdown.Item
4040
key={library.id}
4141
as={Form.Checkbox}
@@ -87,6 +87,7 @@ export const LibraryDropdownFilter = () => {
8787

8888
return (
8989
<Dropdown
90+
id="library-filter-dropdown"
9091
as={ButtonGroup}
9192
autoClose="outside"
9293
>
@@ -99,6 +100,7 @@ export const LibraryDropdownFilter = () => {
99100
)}
100101
>
101102
<Dropdown.Toggle
103+
id="library-filter-dropdown-toggle"
102104
iconBefore={Newsstand}
103105
className="text-overflow text-primary-500 p-2 px-4 mr-2"
104106
>

0 commit comments

Comments
 (0)