-
-
Notifications
You must be signed in to change notification settings - Fork 844
/
OutlineItem.spec.tsx
128 lines (93 loc) · 4.12 KB
/
OutlineItem.spec.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
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);
});
});
});