Files
frontend-app-authoring/src/library-authoring/collections/CollectionDetails.test.tsx
Rômulo Penido 69bbeda816 refactor: split up library context (#1539)
Split the library context into smaller contexts:

* LibraryContext
* ComponentPickerContext
* SidebarContext
2024-12-12 13:14:45 -05:00

179 lines
6.2 KiB
TypeScript

import type MockAdapter from 'axios-mock-adapter';
import fetchMock from 'fetch-mock-jest';
import { mockContentSearchConfig, mockGetBlockTypes } from '../../search-manager/data/api.mock';
import {
initializeMocks,
fireEvent,
render as baseRender,
screen,
waitFor,
within,
} from '../../testUtils';
import { LibraryProvider } from '../common/context/LibraryContext';
import { SidebarBodyComponentId, SidebarProvider } from '../common/context/SidebarContext';
import * as api from '../data/api';
import { mockContentLibrary, mockGetCollectionMetadata } from '../data/api.mocks';
import CollectionDetails from './CollectionDetails';
let axiosMock: MockAdapter;
let mockShowToast: (message: string) => void;
mockContentLibrary.applyMock();
mockGetCollectionMetadata.applyMock();
mockContentSearchConfig.applyMock();
mockGetBlockTypes.applyMock();
const { collectionId } = mockGetCollectionMetadata;
const { description: originalDescription } = mockGetCollectionMetadata.collectionData;
const library = mockContentLibrary.libraryData;
const render = () => baseRender(<CollectionDetails />, {
extraWrapper: ({ children }) => (
<LibraryProvider libraryId={library.id}>
<SidebarProvider
initialSidebarComponentInfo={{
id: collectionId,
type: SidebarBodyComponentId.CollectionInfo,
}}
>
{ children }
</SidebarProvider>
</LibraryProvider>
),
});
describe('<CollectionDetails />', () => {
beforeEach(() => {
const mocks = initializeMocks();
axiosMock = mocks.axiosMock;
mockShowToast = mocks.mockShowToast;
});
afterEach(() => {
fetchMock.mockReset();
});
it('should render Collection Details', async () => {
render();
// Collection Description
expect(await screen.findByText('Description / Card Preview Text')).toBeInTheDocument();
expect(screen.getByText(originalDescription)).toBeInTheDocument();
// Collection History
expect(screen.getByText('Collection History')).toBeInTheDocument();
// Modified date
expect(screen.getByText('September 20, 2024')).toBeInTheDocument();
// Created date
expect(screen.getByText('September 19, 2024')).toBeInTheDocument();
});
it('should allow modifying the description', async () => {
render();
expect(await screen.findByText('Description / Card Preview Text')).toBeInTheDocument();
expect(screen.getByText(originalDescription)).toBeInTheDocument();
const url = api.getLibraryCollectionApiUrl(library.id, collectionId);
axiosMock.onPatch(url).reply(200);
const textArea = screen.getByRole('textbox');
// Change the description to the same value
fireEvent.focus(textArea);
fireEvent.change(textArea, { target: { value: originalDescription } });
fireEvent.blur(textArea);
await waitFor(() => {
expect(axiosMock.history.patch).toHaveLength(0);
expect(mockShowToast).not.toHaveBeenCalled();
});
// Change the description to a new value
fireEvent.focus(textArea);
fireEvent.change(textArea, { target: { value: 'New description' } });
fireEvent.blur(textArea);
await waitFor(() => {
expect(axiosMock.history.patch).toHaveLength(1);
expect(axiosMock.history.patch[0].url).toEqual(url);
expect(axiosMock.history.patch[0].data).toEqual(JSON.stringify({ description: 'New description' }));
expect(mockShowToast).toHaveBeenCalledWith('Collection updated successfully.');
});
});
it('should show error while modifing the description', async () => {
render();
expect(await screen.findByText('Description / Card Preview Text')).toBeInTheDocument();
expect(screen.getByText(originalDescription)).toBeInTheDocument();
const url = api.getLibraryCollectionApiUrl(library.id, collectionId);
axiosMock.onPatch(url).reply(500);
const textArea = screen.getByRole('textbox');
// Change the description to a new value
fireEvent.focus(textArea);
fireEvent.change(textArea, { target: { value: 'New description' } });
fireEvent.blur(textArea);
await waitFor(() => {
expect(axiosMock.history.patch).toHaveLength(1);
expect(axiosMock.history.patch[0].url).toEqual(url);
expect(axiosMock.history.patch[0].data).toEqual(JSON.stringify({ description: 'New description' }));
expect(mockShowToast).toHaveBeenCalledWith('Failed to update collection.');
});
});
it('should render Collection stats', async () => {
mockGetBlockTypes('someBlocks');
render();
expect(await screen.findByText('Description / Card Preview Text')).toBeInTheDocument();
expect(screen.getByText('Collection Stats')).toBeInTheDocument();
expect(await screen.findByText('Total')).toBeInTheDocument();
[
{ blockType: 'Total', count: 3 },
{ blockType: 'Text', count: 2 },
{ blockType: 'Problem', count: 1 },
{ blockType: 'Video', count: 0 },
].forEach(({ blockType, count }) => {
const blockCount = screen.getByText(blockType).closest('div') as HTMLDivElement;
expect(within(blockCount).getByText(count.toString())).toBeInTheDocument();
});
});
it('should render Collection stats for empty collection', async () => {
mockGetBlockTypes('noBlocks');
render();
expect(await screen.findByText('Description / Card Preview Text')).toBeInTheDocument();
expect(screen.getByText('Collection Stats')).toBeInTheDocument();
expect(await screen.findByText('This collection is currently empty.')).toBeInTheDocument();
});
it('should render Collection stats for big collection', async () => {
mockGetBlockTypes('moreBlocks');
render();
expect(await screen.findByText('Description / Card Preview Text')).toBeInTheDocument();
expect(screen.getByText('Collection Stats')).toBeInTheDocument();
expect(await screen.findByText('36')).toBeInTheDocument();
[
{ blockType: 'Total', count: 36 },
{ blockType: 'Problem', count: 2 },
{ blockType: 'Text', count: 3 },
{ blockType: 'Video', count: 1 },
{ blockType: 'Other', count: 30 },
].forEach(({ blockType, count }) => {
const blockCount = screen.getByText(blockType).closest('div') as HTMLDivElement;
expect(within(blockCount).getByText(count.toString())).toBeInTheDocument();
});
});
});