import { beforeAll, describe, expect, it } from 'vitest'; import React from 'react'; import { render } from '@testing-library/react'; import { pdfjs } from './index.test.js'; import StructTree from './StructTree.js'; import failingPage from '../../../__mocks__/_failing_page.js'; import { loadPDF, makeAsyncCallback, muteConsole, restoreConsole } from '../../../test-utils.js'; import PageContext from './PageContext.js'; import type { PDFPageProxy } from 'pdfjs-dist'; import type { PageContextType } from './shared/types.js'; import type { StructTreeNode } from 'pdfjs-dist/types/src/display/api.js'; const pdfFile = loadPDF('./../../__mocks__/_pdf.pdf'); function renderWithContext(children: React.ReactNode, context: Partial) { const { rerender, ...otherResult } = render( {children}, ); return { ...otherResult, rerender: (nextChildren: React.ReactNode, nextContext: Partial = context) => rerender( {nextChildren} , ), }; } describe('StructTree', () => { // Loaded page let page: PDFPageProxy; let page2: PDFPageProxy; // Loaded structure tree let desiredStructTree: StructTreeNode; let desiredStructTree2: StructTreeNode; beforeAll(async () => { const pdf = await pdfjs.getDocument({ data: pdfFile.arrayBuffer }).promise; page = await pdf.getPage(1); desiredStructTree = await page.getStructTree(); page2 = await pdf.getPage(2); desiredStructTree2 = await page2.getStructTree(); }); describe('loading', () => { it('loads structure tree and calls onGetStructTreeSuccess callback properly', async () => { const { func: onGetStructTreeSuccess, promise: onGetStructTreeSuccessPromise } = makeAsyncCallback(); renderWithContext(, { onGetStructTreeSuccess, page, }); expect.assertions(1); await expect(onGetStructTreeSuccessPromise).resolves.toMatchObject([desiredStructTree]); }); it('calls onGetStructTreeError when failed to load annotations', async () => { const { func: onGetStructTreeError, promise: onGetStructTreeErrorPromise } = makeAsyncCallback(); muteConsole(); renderWithContext(, { onGetStructTreeError, page: failingPage, }); expect.assertions(1); await expect(onGetStructTreeErrorPromise).resolves.toMatchObject([expect.any(Error)]); restoreConsole(); }); it('replaces structure tree properly when page is changed', async () => { const { func: onGetStructTreeSuccess, promise: onGetStructTreeSuccessPromise } = makeAsyncCallback(); const { rerender } = renderWithContext(, { onGetStructTreeSuccess, page, }); expect.assertions(2); await expect(onGetStructTreeSuccessPromise).resolves.toMatchObject([desiredStructTree]); const { func: onGetStructTreeSuccess2, promise: onGetStructTreeSuccessPromise2 } = makeAsyncCallback(); rerender(, { onGetStructTreeSuccess: onGetStructTreeSuccess2, page: page2, }); await expect(onGetStructTreeSuccessPromise2).resolves.toMatchObject([desiredStructTree2]); }); it('throws an error when placed outside Page', () => { muteConsole(); expect(() => render()).toThrow(); restoreConsole(); }); }); describe('rendering', () => { it('renders structure tree properly', async () => { const { func: onGetStructTreeSuccess, promise: onGetStructTreeSuccessPromise } = makeAsyncCallback(); const { container } = renderWithContext(, { onGetStructTreeSuccess, page, }); expect.assertions(1); await onGetStructTreeSuccessPromise; const wrapper = container.firstElementChild as HTMLSpanElement; expect(wrapper.outerHTML).toBe( '', ); }); }); });