When using the library component picker, show the correct number on component count (published components) in collection cards.
159 lines
6.5 KiB
TypeScript
159 lines
6.5 KiB
TypeScript
import userEvent from '@testing-library/user-event';
|
|
import type MockAdapter from 'axios-mock-adapter';
|
|
|
|
import {
|
|
initializeMocks, render as baseRender, screen, waitFor, waitForElementToBeRemoved, within,
|
|
} from '../../testUtils';
|
|
import { LibraryProvider } from '../common/context';
|
|
import { type CollectionHit } from '../../search-manager';
|
|
import CollectionCard from './CollectionCard';
|
|
import messages from './messages';
|
|
import { getLibraryCollectionApiUrl, getLibraryCollectionRestoreApiUrl } from '../data/api';
|
|
|
|
const CollectionHitSample: CollectionHit = {
|
|
id: 'lib-collectionorg1democourse-collection-display-name',
|
|
type: 'collection',
|
|
contextKey: 'lb:org1:Demo_Course',
|
|
usageKey: 'lib-collection:org1:Demo_Course:collection-display-name',
|
|
org: 'org1',
|
|
blockId: 'collection-display-name',
|
|
breadcrumbs: [{ displayName: 'Demo Lib' }],
|
|
displayName: 'Collection Display Name',
|
|
description: 'Collection description',
|
|
formatted: {
|
|
displayName: 'Collection Display Formated Name',
|
|
description: 'Collection description',
|
|
},
|
|
created: 1722434322294,
|
|
modified: 1722434322294,
|
|
numChildren: 2,
|
|
published: {
|
|
numChildren: 1,
|
|
},
|
|
tags: {},
|
|
};
|
|
|
|
let axiosMock: MockAdapter;
|
|
let mockShowToast;
|
|
|
|
const render = (ui: React.ReactElement, showOnlyPublished: boolean = false) => baseRender(ui, {
|
|
extraWrapper: ({ children }) => (
|
|
<LibraryProvider
|
|
libraryId="lib:Axim:TEST"
|
|
showOnlyPublished={showOnlyPublished}
|
|
>
|
|
{ children }
|
|
</LibraryProvider>
|
|
),
|
|
});
|
|
|
|
describe('<CollectionCard />', () => {
|
|
beforeEach(() => {
|
|
const mocks = initializeMocks();
|
|
axiosMock = mocks.axiosMock;
|
|
mockShowToast = mocks.mockShowToast;
|
|
});
|
|
|
|
it('should render the card with title and description', () => {
|
|
render(<CollectionCard collectionHit={CollectionHitSample} />);
|
|
|
|
expect(screen.queryByText('Collection Display Formated Name')).toBeInTheDocument();
|
|
expect(screen.queryByText('Collection description')).toBeInTheDocument();
|
|
expect(screen.queryByText('Collection (2)')).toBeInTheDocument();
|
|
});
|
|
|
|
it('should render published content', () => {
|
|
render(<CollectionCard collectionHit={CollectionHitSample} />, true);
|
|
|
|
expect(screen.queryByText('Collection Display Formated Name')).toBeInTheDocument();
|
|
expect(screen.queryByText('Collection description')).toBeInTheDocument();
|
|
expect(screen.queryByText('Collection (1)')).toBeInTheDocument();
|
|
});
|
|
|
|
it('should navigate to the collection if the open menu clicked', async () => {
|
|
render(<CollectionCard collectionHit={CollectionHitSample} />);
|
|
|
|
// Open menu
|
|
expect(screen.getByTestId('collection-card-menu-toggle')).toBeInTheDocument();
|
|
userEvent.click(screen.getByTestId('collection-card-menu-toggle'));
|
|
|
|
// Open menu item
|
|
const openMenuItem = screen.getByRole('link', { name: 'Open' });
|
|
expect(openMenuItem).toBeInTheDocument();
|
|
|
|
expect(openMenuItem).toHaveAttribute('href', '/library/lb:org1:Demo_Course/collection/collection-display-name/');
|
|
});
|
|
|
|
it('should show confirmation box, delete collection and show toast to undo deletion', async () => {
|
|
const url = getLibraryCollectionApiUrl(CollectionHitSample.contextKey, CollectionHitSample.blockId);
|
|
axiosMock.onDelete(url).reply(204);
|
|
render(<CollectionCard collectionHit={CollectionHitSample} />);
|
|
|
|
expect(screen.queryByText('Collection Display Formated Name')).toBeInTheDocument();
|
|
// Open menu
|
|
let menuBtn = await screen.findByRole('button', { name: messages.collectionCardMenuAlt.defaultMessage });
|
|
userEvent.click(menuBtn);
|
|
// find and click delete menu option.
|
|
expect(screen.queryByText('Delete')).toBeInTheDocument();
|
|
let deleteBtn = await screen.findByRole('button', { name: 'Delete' });
|
|
userEvent.click(deleteBtn);
|
|
// verify confirmation dialog and click on cancel button
|
|
let dialog = await screen.findByRole('dialog', { name: 'Delete this collection?' });
|
|
expect(dialog).toBeInTheDocument();
|
|
const cancelBtn = await screen.findByRole('button', { name: 'Cancel' });
|
|
userEvent.click(cancelBtn);
|
|
expect(axiosMock.history.delete.length).toEqual(0);
|
|
expect(cancelBtn).not.toBeInTheDocument();
|
|
|
|
// Open menu
|
|
menuBtn = await screen.findByRole('button', { name: messages.collectionCardMenuAlt.defaultMessage });
|
|
userEvent.click(menuBtn);
|
|
// click on confirm button to delete
|
|
deleteBtn = await screen.findByRole('button', { name: 'Delete' });
|
|
userEvent.click(deleteBtn);
|
|
dialog = await screen.findByRole('dialog', { name: 'Delete this collection?' });
|
|
const confirmBtn = await within(dialog).findByRole('button', { name: 'Delete' });
|
|
userEvent.click(confirmBtn);
|
|
await waitForElementToBeRemoved(() => screen.queryByRole('dialog', { name: 'Delete this collection?' }));
|
|
|
|
await waitFor(() => {
|
|
expect(axiosMock.history.delete.length).toEqual(1);
|
|
expect(mockShowToast).toHaveBeenCalled();
|
|
});
|
|
// Get restore / undo func from the toast
|
|
const restoreFn = mockShowToast.mock.calls[0][1].onClick;
|
|
|
|
const restoreUrl = getLibraryCollectionRestoreApiUrl(CollectionHitSample.contextKey, CollectionHitSample.blockId);
|
|
axiosMock.onPost(restoreUrl).reply(200);
|
|
// restore collection
|
|
restoreFn();
|
|
await waitFor(() => {
|
|
expect(axiosMock.history.post.length).toEqual(1);
|
|
expect(mockShowToast).toHaveBeenCalledWith('Undo successful');
|
|
});
|
|
});
|
|
|
|
it('should show failed toast on delete collection failure', async () => {
|
|
const url = getLibraryCollectionApiUrl(CollectionHitSample.contextKey, CollectionHitSample.blockId);
|
|
axiosMock.onDelete(url).reply(404);
|
|
render(<CollectionCard collectionHit={CollectionHitSample} />);
|
|
|
|
expect(screen.queryByText('Collection Display Formated Name')).toBeInTheDocument();
|
|
// Open menu
|
|
const menuBtn = await screen.findByRole('button', { name: messages.collectionCardMenuAlt.defaultMessage });
|
|
userEvent.click(menuBtn);
|
|
// find and click delete menu option.
|
|
const deleteBtn = await screen.findByRole('button', { name: 'Delete' });
|
|
userEvent.click(deleteBtn);
|
|
const dialog = await screen.findByRole('dialog', { name: 'Delete this collection?' });
|
|
const confirmBtn = await within(dialog).findByRole('button', { name: 'Delete' });
|
|
userEvent.click(confirmBtn);
|
|
await waitForElementToBeRemoved(() => screen.queryByRole('dialog', { name: 'Delete this collection?' }));
|
|
|
|
await waitFor(() => {
|
|
expect(axiosMock.history.delete.length).toEqual(1);
|
|
expect(mockShowToast).toHaveBeenCalledWith('Failed to delete collection');
|
|
});
|
|
});
|
|
});
|