Skip to content

Commit d87d3af

Browse files
committed
[test]: show selected row attachment
1 parent 1669426 commit d87d3af

1 file changed

Lines changed: 192 additions & 0 deletions

File tree

Lines changed: 192 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,192 @@
1+
import type Handsontable from 'handsontable';
2+
import { act } from '@testing-library/react';
3+
import React from 'react';
4+
import type { LocalizedString } from 'typesafe-i18n';
5+
6+
import { clearIdStore } from '../../../hooks/useId';
7+
import { overrideAjax } from '../../../tests/ajax';
8+
import { requireContext } from '../../../tests/helpers';
9+
import { mount } from '../../../tests/reactUtils';
10+
import { f } from '../../../utils/functools';
11+
import * as Attachments from '../../Attachments/attachments';
12+
import { testAttachment } from '../../Attachments/__tests__/utils';
13+
import { LoadingContext } from '../../Core/Contexts';
14+
import type { Dataset } from '../../WbPlanView/Wrapped';
15+
import { ATTACHMENTS_COLUMN } from '../attachmentHelpers';
16+
import { WbAttachmentsPreview } from '../WbAttachmentsPreview';
17+
18+
requireContext();
19+
20+
const firstDataSetAttachmentId = 201;
21+
const secondDataSetAttachmentId = 202;
22+
23+
const firstAttachment = {
24+
...testAttachment,
25+
id: 101,
26+
title: 'First row attachment',
27+
origFilename: 'first-row.jpg',
28+
attachmentLocation: 'first-row.jpg',
29+
resource_uri: '/api/specify/attachment/101/',
30+
};
31+
32+
const secondAttachment = {
33+
...testAttachment,
34+
id: 102,
35+
title: 'Second row attachment',
36+
origFilename: 'second-row.jpg',
37+
attachmentLocation: 'second-row.jpg',
38+
resource_uri: '/api/specify/attachment/102/',
39+
};
40+
41+
const firstDataSetAttachmentRequest = jest.fn(() => ({
42+
id: firstDataSetAttachmentId,
43+
ordinal: 0,
44+
attachment: firstAttachment,
45+
spdataset: '/api/specify/spdataset/123/',
46+
resource_uri: `/api/specify/spdatasetattachment/${firstDataSetAttachmentId}/`,
47+
}));
48+
49+
const secondDataSetAttachmentRequest = jest.fn(() => ({
50+
id: secondDataSetAttachmentId,
51+
ordinal: 0,
52+
attachment: secondAttachment,
53+
spdataset: '/api/specify/spdataset/123/',
54+
resource_uri: `/api/specify/spdatasetattachment/${secondDataSetAttachmentId}/`,
55+
}));
56+
57+
overrideAjax(
58+
`/api/specify/spdatasetattachment/${firstDataSetAttachmentId}/`,
59+
firstDataSetAttachmentRequest
60+
);
61+
62+
overrideAjax(
63+
`/api/specify/spdatasetattachment/${secondDataSetAttachmentId}/`,
64+
secondDataSetAttachmentRequest
65+
);
66+
67+
beforeEach(() => {
68+
jest.clearAllMocks();
69+
clearIdStore();
70+
});
71+
72+
afterEach(() => {
73+
jest.restoreAllMocks();
74+
});
75+
76+
// [WorkBench] Show the matching attachment for the selected row
77+
test('shows the selected row attachment', async () => {
78+
jest
79+
.spyOn(Attachments, 'fetchThumbnail')
80+
.mockImplementation(async (attachment) => ({
81+
src: `thumbnail-${attachment.id}`,
82+
alt: attachment.title ?? undefined,
83+
width: 64,
84+
height: 64,
85+
}));
86+
87+
const addHook = jest.fn();
88+
const getDataAtCell = jest.fn((row: number) =>
89+
row === 0
90+
? JSON.stringify({
91+
attachments: [
92+
{
93+
id: firstDataSetAttachmentId,
94+
table: 'baseTable',
95+
},
96+
],
97+
formatted: 'first-row.jpg',
98+
})
99+
: JSON.stringify({
100+
attachments: [
101+
{
102+
id: secondDataSetAttachmentId,
103+
table: 'baseTable',
104+
},
105+
],
106+
formatted: 'second-row.jpg',
107+
})
108+
);
109+
110+
const hot = {
111+
addHook,
112+
getDataAtCell,
113+
getSelectedLast: jest.fn(() => [0, 0, 0, 0]),
114+
toVisualColumn: jest.fn((column: number) => column),
115+
} as unknown as Handsontable;
116+
117+
const dataset: Dataset = {
118+
id: 123,
119+
name: 'Attachment test data set' as LocalizedString,
120+
timestampcreated: '2026-01-01T00:00:00Z',
121+
timestampmodified: '2026-01-01T00:00:00Z',
122+
createdbyagent: '/api/specify/agent/1/',
123+
importedfilename: 'attachments.csv',
124+
modifiedbyagent: null,
125+
remarks: '',
126+
uploadresult: null,
127+
uploaderstatus: null,
128+
columns: ['catalogNumber', ATTACHMENTS_COLUMN],
129+
rowresults: null,
130+
rows: [],
131+
uploadplan: null,
132+
visualorder: null,
133+
isupdate: false,
134+
rolledback: false,
135+
usesattachments: true,
136+
attachments: null,
137+
};
138+
139+
const { findByRole, queryByRole } = mount(
140+
<LoadingContext.Provider value={f.void}>
141+
<WbAttachmentsPreview
142+
checkDeletedFail={jest.fn()}
143+
dataset={dataset}
144+
hot={hot}
145+
isUploaded
146+
searchRef={{ current: null }}
147+
showPanel
148+
workbench={{} as never}
149+
onClose={jest.fn()}
150+
onSpreadsheetUpToDate={jest.fn()}
151+
/>
152+
</LoadingContext.Provider>
153+
);
154+
155+
expect(
156+
await findByRole('img', {
157+
name: 'First row attachment',
158+
})
159+
).toBeInTheDocument();
160+
161+
expect(firstDataSetAttachmentRequest).toHaveBeenCalledTimes(1);
162+
expect(secondDataSetAttachmentRequest).not.toHaveBeenCalled();
163+
164+
expect(addHook).toHaveBeenCalledWith(
165+
'afterSelectionEnd',
166+
expect.any(Function)
167+
);
168+
169+
const selectRow = addHook.mock.calls[0][1] as (row: number) => void;
170+
171+
await act(async () => {
172+
selectRow(1);
173+
});
174+
175+
expect(
176+
await findByRole('img', {
177+
name: 'Second row attachment',
178+
})
179+
).toBeInTheDocument();
180+
181+
expect(
182+
queryByRole('img', {
183+
name: 'First row attachment',
184+
})
185+
).not.toBeInTheDocument();
186+
187+
expect(firstDataSetAttachmentRequest).toHaveBeenCalledTimes(1);
188+
expect(secondDataSetAttachmentRequest).toHaveBeenCalledTimes(1);
189+
190+
expect(getDataAtCell).toHaveBeenCalledWith(0, 1);
191+
expect(getDataAtCell).toHaveBeenCalledWith(1, 1);
192+
});

0 commit comments

Comments
 (0)