129 lines
4.1 KiB
TypeScript
129 lines
4.1 KiB
TypeScript
import { beforeAll, describe, expect, it, vi } from 'vitest';
|
|
import { fireEvent, getAllByRole, render, screen } from '@testing-library/react';
|
|
|
|
import { pdfjs } from './index.test.js';
|
|
import OutlineItem from './OutlineItem.js';
|
|
|
|
import { loadPDF, makeAsyncCallback } from '../../../test-utils.js';
|
|
|
|
import DocumentContext from './DocumentContext.js';
|
|
import OutlineContext from './OutlineContext.js';
|
|
|
|
import type { PDFDocumentProxy } from 'pdfjs-dist';
|
|
import type { DocumentContextType, OutlineContextType } from './shared/types.js';
|
|
|
|
const pdfFile = loadPDF('./../../__mocks__/_pdf.pdf');
|
|
|
|
type PDFOutline = Awaited<ReturnType<PDFDocumentProxy['getOutline']>>;
|
|
type PDFOutlineItem = PDFOutline[number];
|
|
|
|
function renderWithContext(
|
|
children: React.ReactNode,
|
|
documentContext: Partial<DocumentContextType>,
|
|
outlineContext: Partial<OutlineContextType>,
|
|
) {
|
|
const { rerender, ...otherResult } = render(
|
|
<DocumentContext.Provider value={documentContext as DocumentContextType}>
|
|
<OutlineContext.Provider value={outlineContext as OutlineContextType}>
|
|
{children}
|
|
</OutlineContext.Provider>
|
|
</DocumentContext.Provider>,
|
|
);
|
|
|
|
return {
|
|
...otherResult,
|
|
rerender: (
|
|
nextChildren: React.ReactNode,
|
|
nextDocumentContext: Partial<DocumentContextType> = documentContext,
|
|
nextOutlineContext: Partial<OutlineContextType> = outlineContext,
|
|
) =>
|
|
rerender(
|
|
<DocumentContext.Provider value={nextDocumentContext as DocumentContextType}>
|
|
<OutlineContext.Provider value={nextOutlineContext as OutlineContextType}>
|
|
{nextChildren}
|
|
</OutlineContext.Provider>
|
|
</DocumentContext.Provider>,
|
|
),
|
|
};
|
|
}
|
|
|
|
describe('OutlineItem', () => {
|
|
// Loaded PDF file
|
|
let pdf: PDFDocumentProxy;
|
|
|
|
// Object with basic loaded outline item information
|
|
let outlineItem: PDFOutlineItem;
|
|
|
|
beforeAll(async () => {
|
|
pdf = await pdfjs.getDocument({ data: pdfFile.arrayBuffer }).promise;
|
|
|
|
const outlineItems = await pdf.getOutline();
|
|
[outlineItem] = outlineItems as [PDFOutlineItem];
|
|
});
|
|
|
|
describe('rendering', () => {
|
|
it('renders an item properly', () => {
|
|
const onItemClick = vi.fn();
|
|
|
|
renderWithContext(<OutlineItem item={outlineItem} />, { pdf }, { onItemClick });
|
|
|
|
const item = screen.getAllByRole('listitem')[0];
|
|
|
|
expect(item).toHaveTextContent(outlineItem.title);
|
|
});
|
|
|
|
it("renders item's subitems properly", () => {
|
|
const onItemClick = vi.fn();
|
|
|
|
renderWithContext(<OutlineItem item={outlineItem} />, { pdf }, { onItemClick });
|
|
|
|
const item = screen.getAllByRole('listitem')[0] as HTMLElement;
|
|
const subitems = getAllByRole(item, 'listitem');
|
|
|
|
expect(subitems).toHaveLength(outlineItem.items.length);
|
|
});
|
|
|
|
it('calls onItemClick with proper arguments when clicked a link', async () => {
|
|
const { func: onItemClick, promise: onItemClickPromise } = makeAsyncCallback();
|
|
|
|
renderWithContext(<OutlineItem item={outlineItem} />, { pdf }, { onItemClick });
|
|
|
|
const item = screen.getAllByRole('listitem')[0] as HTMLElement;
|
|
const link = getAllByRole(item, 'link')[0] as HTMLAnchorElement;
|
|
fireEvent.click(link);
|
|
|
|
await onItemClickPromise;
|
|
|
|
expect(onItemClick).toHaveBeenCalled();
|
|
});
|
|
|
|
it('calls onItemClick with proper arguments multiple times when clicked a link multiple times', async () => {
|
|
const { func: onItemClick, promise: onItemClickPromise } = makeAsyncCallback();
|
|
|
|
const { rerender } = renderWithContext(
|
|
<OutlineItem item={outlineItem} />,
|
|
{ pdf },
|
|
{ onItemClick },
|
|
);
|
|
|
|
const item = screen.getAllByRole('listitem')[0] as HTMLElement;
|
|
const link = getAllByRole(item, 'link')[0] as HTMLAnchorElement;
|
|
fireEvent.click(link);
|
|
|
|
await onItemClickPromise;
|
|
|
|
expect(onItemClick).toHaveBeenCalledTimes(1);
|
|
|
|
const { func: onItemClick2, promise: onItemClickPromise2 } = makeAsyncCallback();
|
|
|
|
rerender(<OutlineItem item={outlineItem} />, { pdf }, { onItemClick: onItemClick2 });
|
|
|
|
fireEvent.click(link);
|
|
|
|
await onItemClickPromise2;
|
|
|
|
expect(onItemClick2).toHaveBeenCalledTimes(1);
|
|
});
|
|
});
|
|
});
|