@thepalaceproject/circulation-admin 1.19.0 → 1.20.0-post.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/circulation-admin.js +1 -1
- package/dist/circulation-admin.js.LICENSE.txt +30 -2
- package/jest.config.js +4 -0
- package/jest.polyfills.js +20 -0
- package/package.json +12 -4
- package/tests/jest/api/admin.test.ts +60 -0
- package/tests/jest/components/CustomLists.test.tsx +11 -12
- package/tests/jest/components/InventoryReportRequestModal.test.tsx +652 -0
- package/tests/jest/components/QuicksightDashboard.test.tsx +12 -12
- package/tests/jest/testUtils/withProviders.tsx +71 -0
|
@@ -0,0 +1,652 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { act, renderHook } from "@testing-library/react-hooks";
|
|
3
|
+
import { within } from "@testing-library/react";
|
|
4
|
+
import {
|
|
5
|
+
componentWithProviders,
|
|
6
|
+
renderWithProviders,
|
|
7
|
+
} from "../testUtils/withProviders";
|
|
8
|
+
import { QueryClient } from "@tanstack/react-query";
|
|
9
|
+
import { setupServer } from "msw/node";
|
|
10
|
+
import { http, HttpResponse } from "msw";
|
|
11
|
+
import {
|
|
12
|
+
ACK_RESPONSE_BUTTON_CONTENT,
|
|
13
|
+
ACK_RESPONSE_HEADING,
|
|
14
|
+
CANCEL_BUTTON_CONTENT,
|
|
15
|
+
CONFIRM_BUTTON_CONTENT,
|
|
16
|
+
CONFIRMATION_MODAL_HEADING,
|
|
17
|
+
useGenerateReport,
|
|
18
|
+
useReportInfo,
|
|
19
|
+
} from "../../../src/components/InventoryReportRequestModal";
|
|
20
|
+
import * as AdminAPI from "../../../src/api/admin";
|
|
21
|
+
import InventoryReportRequestModal, {
|
|
22
|
+
NO_COLLECTIONS_MESSAGE,
|
|
23
|
+
SOME_COLLECTIONS_MESSAGE,
|
|
24
|
+
UNKNOWN_COLLECTIONS_MESSAGE,
|
|
25
|
+
} from "../../../src/components/InventoryReportRequestModal";
|
|
26
|
+
import userEvent from "@testing-library/user-event";
|
|
27
|
+
import { InventoryReportInfo } from "../../../src/api/admin";
|
|
28
|
+
|
|
29
|
+
const MODAL_HEADING_LEVEL = 4;
|
|
30
|
+
const COLLECTION_NAME = "Collection A";
|
|
31
|
+
const INFO_SUCCESS_SOME_COLLECTIONS: InventoryReportInfo = Object.freeze({
|
|
32
|
+
collections: [{ id: 0, name: COLLECTION_NAME }],
|
|
33
|
+
});
|
|
34
|
+
const INFO_SUCCESS_NO_COLLECTIONS: InventoryReportInfo = Object.freeze({
|
|
35
|
+
collections: [],
|
|
36
|
+
});
|
|
37
|
+
const GENERATE_REPORT_SUCCESS = {
|
|
38
|
+
message: "We triggered report generation.",
|
|
39
|
+
};
|
|
40
|
+
const MOCK_SERVER_API_ENDPOINT_PATH =
|
|
41
|
+
"/admin/reports/inventory_report/:library_short_name";
|
|
42
|
+
const API_ENDPOINT_PARAMS: AdminAPI.InventoryReportRequestParams = {
|
|
43
|
+
library: "library-short-name",
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
const setupMockServer = () => {
|
|
47
|
+
return setupServer(
|
|
48
|
+
http.get(MOCK_SERVER_API_ENDPOINT_PATH, () =>
|
|
49
|
+
HttpResponse.json(INFO_SUCCESS_SOME_COLLECTIONS, { status: 200 })
|
|
50
|
+
),
|
|
51
|
+
http.post(MOCK_SERVER_API_ENDPOINT_PATH, () =>
|
|
52
|
+
HttpResponse.json(GENERATE_REPORT_SUCCESS, { status: 202 })
|
|
53
|
+
)
|
|
54
|
+
);
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
describe("InventoryReportRequestModal", () => {
|
|
58
|
+
/* eslint-disable @typescript-eslint/no-empty-function */
|
|
59
|
+
const queryClient = new QueryClient({
|
|
60
|
+
defaultOptions: {
|
|
61
|
+
queries: {
|
|
62
|
+
retry: false,
|
|
63
|
+
},
|
|
64
|
+
},
|
|
65
|
+
logger: {
|
|
66
|
+
log: console.log,
|
|
67
|
+
warn: console.warn,
|
|
68
|
+
error: process.env.NODE_ENV === "test" ? () => {} : console.error,
|
|
69
|
+
},
|
|
70
|
+
});
|
|
71
|
+
/* eslint-enable @typescript-eslint/no-empty-function */
|
|
72
|
+
|
|
73
|
+
describe("query hooks call correct api methods", () => {
|
|
74
|
+
const wrapper = componentWithProviders({ queryClient });
|
|
75
|
+
|
|
76
|
+
describe("get report information", () => {
|
|
77
|
+
const mock_info_api = jest.spyOn(AdminAPI, "getInventoryReportInfo");
|
|
78
|
+
|
|
79
|
+
afterEach(() => {
|
|
80
|
+
jest.clearAllMocks();
|
|
81
|
+
queryClient.clear();
|
|
82
|
+
});
|
|
83
|
+
afterAll(() => mock_info_api.mockRestore());
|
|
84
|
+
|
|
85
|
+
it("report info query hook performs fetch, when enabled", async () => {
|
|
86
|
+
const show = true;
|
|
87
|
+
|
|
88
|
+
mock_info_api.mockResolvedValue(INFO_SUCCESS_SOME_COLLECTIONS);
|
|
89
|
+
const { result, waitFor } = renderHook(
|
|
90
|
+
() => useReportInfo(show, API_ENDPOINT_PARAMS),
|
|
91
|
+
{ wrapper }
|
|
92
|
+
);
|
|
93
|
+
await waitFor(() => result.current.fetchStatus == "idle");
|
|
94
|
+
const { isSuccess, isError, error, collections } = result.current;
|
|
95
|
+
|
|
96
|
+
expect(mock_info_api).toHaveBeenCalledWith(API_ENDPOINT_PARAMS);
|
|
97
|
+
|
|
98
|
+
expect(isSuccess).toBe(true);
|
|
99
|
+
expect(isError).toBe(false);
|
|
100
|
+
expect(error).toBeNull();
|
|
101
|
+
expect(collections).toEqual(INFO_SUCCESS_SOME_COLLECTIONS.collections);
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
it("report info query hook doesn't fetch, when disabled", async () => {
|
|
105
|
+
const show = false;
|
|
106
|
+
|
|
107
|
+
mock_info_api.mockResolvedValue(INFO_SUCCESS_SOME_COLLECTIONS);
|
|
108
|
+
const { result, waitFor } = renderHook(
|
|
109
|
+
() => useReportInfo(show, API_ENDPOINT_PARAMS),
|
|
110
|
+
{ wrapper }
|
|
111
|
+
);
|
|
112
|
+
await waitFor(() => result.current.fetchStatus == "idle");
|
|
113
|
+
const { isSuccess, isError, error, collections } = result.current;
|
|
114
|
+
|
|
115
|
+
expect(mock_info_api).not.toHaveBeenCalled();
|
|
116
|
+
expect(isSuccess).toBe(false);
|
|
117
|
+
expect(isError).toBe(false);
|
|
118
|
+
expect(error).toBeNull();
|
|
119
|
+
expect(collections).not.toBeDefined();
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
it("report info query hook returns no collections, when api throws error", async () => {
|
|
123
|
+
const show = true;
|
|
124
|
+
|
|
125
|
+
mock_info_api.mockImplementation(() => {
|
|
126
|
+
throw new Error("an error occurred");
|
|
127
|
+
});
|
|
128
|
+
const { result, waitFor } = renderHook(
|
|
129
|
+
() => useReportInfo(show, API_ENDPOINT_PARAMS),
|
|
130
|
+
{ wrapper }
|
|
131
|
+
);
|
|
132
|
+
await waitFor(() => result.current.fetchStatus == "idle");
|
|
133
|
+
const { isSuccess, isError, error, collections } = result.current;
|
|
134
|
+
|
|
135
|
+
expect(mock_info_api).toHaveBeenCalledWith(API_ENDPOINT_PARAMS);
|
|
136
|
+
expect(isSuccess).toBe(false);
|
|
137
|
+
expect(isError).toBe(true);
|
|
138
|
+
expect((error as Error).message).toEqual("an error occurred");
|
|
139
|
+
expect(collections).not.toBeDefined();
|
|
140
|
+
});
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
describe("generate report", () => {
|
|
144
|
+
const mock_generate_api = jest.spyOn(AdminAPI, "requestInventoryReport");
|
|
145
|
+
|
|
146
|
+
const setResponseMessage = jest.fn();
|
|
147
|
+
const setShowConfirmationModal = jest.fn();
|
|
148
|
+
const setShowResponseModal = jest.fn();
|
|
149
|
+
|
|
150
|
+
afterEach(() => {
|
|
151
|
+
jest.clearAllMocks();
|
|
152
|
+
queryClient.clear();
|
|
153
|
+
});
|
|
154
|
+
afterAll(() => mock_generate_api.mockRestore());
|
|
155
|
+
|
|
156
|
+
it("handles api success", async () => {
|
|
157
|
+
mock_generate_api.mockResolvedValue(GENERATE_REPORT_SUCCESS);
|
|
158
|
+
const { result, waitFor } = renderHook(
|
|
159
|
+
() => {
|
|
160
|
+
const reportGenerator = useGenerateReport({
|
|
161
|
+
...API_ENDPOINT_PARAMS,
|
|
162
|
+
setResponseMessage,
|
|
163
|
+
setShowResponseModal,
|
|
164
|
+
setShowConfirmationModal,
|
|
165
|
+
});
|
|
166
|
+
return { reportGenerator };
|
|
167
|
+
},
|
|
168
|
+
{ wrapper }
|
|
169
|
+
);
|
|
170
|
+
|
|
171
|
+
expect(result.current.reportGenerator.isIdle).toBe(true);
|
|
172
|
+
expect(mock_generate_api).not.toHaveBeenCalled();
|
|
173
|
+
expect(setResponseMessage).not.toHaveBeenCalled();
|
|
174
|
+
expect(setShowResponseModal).not.toHaveBeenCalled();
|
|
175
|
+
expect(setShowConfirmationModal).not.toHaveBeenCalled();
|
|
176
|
+
|
|
177
|
+
act(() => result.current.reportGenerator.mutate());
|
|
178
|
+
await waitFor(
|
|
179
|
+
() =>
|
|
180
|
+
result.current.reportGenerator.isSuccess ||
|
|
181
|
+
result.current.reportGenerator.isError
|
|
182
|
+
);
|
|
183
|
+
const { isSuccess, isError, error } = result.current.reportGenerator;
|
|
184
|
+
|
|
185
|
+
expect(mock_generate_api).toHaveBeenCalledWith(API_ENDPOINT_PARAMS);
|
|
186
|
+
|
|
187
|
+
expect(isSuccess).toBe(true);
|
|
188
|
+
expect(isError).toBe(false);
|
|
189
|
+
expect(error).toBeNull();
|
|
190
|
+
expect(setResponseMessage).toHaveBeenCalledWith(
|
|
191
|
+
`✅ ${GENERATE_REPORT_SUCCESS.message}`
|
|
192
|
+
);
|
|
193
|
+
expect(setShowResponseModal).toHaveBeenCalledWith(true);
|
|
194
|
+
expect(setShowConfirmationModal).toHaveBeenCalledWith(false);
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
it("handles api error", async () => {
|
|
198
|
+
mock_generate_api.mockImplementation(() => {
|
|
199
|
+
throw new Error("an error occurred");
|
|
200
|
+
});
|
|
201
|
+
const { result, waitFor } = renderHook(
|
|
202
|
+
() => {
|
|
203
|
+
const reportGenerator = useGenerateReport({
|
|
204
|
+
...API_ENDPOINT_PARAMS,
|
|
205
|
+
setResponseMessage,
|
|
206
|
+
setShowResponseModal,
|
|
207
|
+
setShowConfirmationModal,
|
|
208
|
+
});
|
|
209
|
+
return { reportGenerator };
|
|
210
|
+
},
|
|
211
|
+
{ wrapper }
|
|
212
|
+
);
|
|
213
|
+
|
|
214
|
+
expect(result.current.reportGenerator.isIdle).toBe(true);
|
|
215
|
+
expect(mock_generate_api).not.toHaveBeenCalled();
|
|
216
|
+
expect(setResponseMessage).not.toHaveBeenCalled();
|
|
217
|
+
expect(setShowResponseModal).not.toHaveBeenCalled();
|
|
218
|
+
expect(setShowConfirmationModal).not.toHaveBeenCalled();
|
|
219
|
+
|
|
220
|
+
act(() => result.current.reportGenerator.mutate());
|
|
221
|
+
await waitFor(
|
|
222
|
+
() =>
|
|
223
|
+
result.current.reportGenerator.isSuccess ||
|
|
224
|
+
result.current.reportGenerator.isError
|
|
225
|
+
);
|
|
226
|
+
const { isSuccess, isError, error } = result.current.reportGenerator;
|
|
227
|
+
|
|
228
|
+
expect(mock_generate_api).toHaveBeenCalledWith(API_ENDPOINT_PARAMS);
|
|
229
|
+
|
|
230
|
+
expect(isSuccess).toBe(false);
|
|
231
|
+
expect(isError).toBe(true);
|
|
232
|
+
expect(error).not.toBeNull();
|
|
233
|
+
expect(setResponseMessage).toHaveBeenCalledWith(`❌ an error occurred`);
|
|
234
|
+
expect(setShowResponseModal).toHaveBeenCalledWith(true);
|
|
235
|
+
expect(setShowConfirmationModal).toHaveBeenCalledWith(false);
|
|
236
|
+
});
|
|
237
|
+
});
|
|
238
|
+
});
|
|
239
|
+
|
|
240
|
+
describe("mock server functionality", () => {
|
|
241
|
+
const server = setupMockServer();
|
|
242
|
+
beforeAll(() => server.listen());
|
|
243
|
+
afterAll(() => server.close());
|
|
244
|
+
afterEach(() => {
|
|
245
|
+
server.resetHandlers();
|
|
246
|
+
server.restoreHandlers();
|
|
247
|
+
});
|
|
248
|
+
|
|
249
|
+
it("returns the success value for successful report info (get) requests", async () => {
|
|
250
|
+
const result = await AdminAPI.getInventoryReportInfo(API_ENDPOINT_PARAMS);
|
|
251
|
+
expect(result).toEqual(INFO_SUCCESS_SOME_COLLECTIONS);
|
|
252
|
+
});
|
|
253
|
+
it("returns an error value for unsuccessful report info (get) requests", async () => {
|
|
254
|
+
server.use(
|
|
255
|
+
http.get(
|
|
256
|
+
MOCK_SERVER_API_ENDPOINT_PATH,
|
|
257
|
+
() => new HttpResponse(null, { status: 404 })
|
|
258
|
+
)
|
|
259
|
+
);
|
|
260
|
+
let error = undefined;
|
|
261
|
+
try {
|
|
262
|
+
await AdminAPI.getInventoryReportInfo(API_ENDPOINT_PARAMS);
|
|
263
|
+
} catch (e) {
|
|
264
|
+
error = await e;
|
|
265
|
+
}
|
|
266
|
+
expect(error?.message).toMatch("Request failed with status 404: GET ");
|
|
267
|
+
});
|
|
268
|
+
|
|
269
|
+
it("returns the expected value for generate report (post) requests", async () => {
|
|
270
|
+
const result = await AdminAPI.requestInventoryReport(API_ENDPOINT_PARAMS);
|
|
271
|
+
expect(result).toEqual(GENERATE_REPORT_SUCCESS);
|
|
272
|
+
});
|
|
273
|
+
it("returns an error value for unsuccessful generate report (post) requests", async () => {
|
|
274
|
+
server.use(
|
|
275
|
+
http.post(
|
|
276
|
+
MOCK_SERVER_API_ENDPOINT_PATH,
|
|
277
|
+
() => new HttpResponse(null, { status: 404 })
|
|
278
|
+
)
|
|
279
|
+
);
|
|
280
|
+
let error = undefined;
|
|
281
|
+
try {
|
|
282
|
+
await AdminAPI.requestInventoryReport(API_ENDPOINT_PARAMS);
|
|
283
|
+
} catch (e) {
|
|
284
|
+
error = await e;
|
|
285
|
+
}
|
|
286
|
+
expect(error?.message).toMatch("Request failed with status 404: POST ");
|
|
287
|
+
});
|
|
288
|
+
});
|
|
289
|
+
|
|
290
|
+
describe("component rendering", () => {
|
|
291
|
+
const onHide = jest.fn();
|
|
292
|
+
const server = setupMockServer();
|
|
293
|
+
|
|
294
|
+
beforeAll(() => server.listen());
|
|
295
|
+
afterAll(() => server.close());
|
|
296
|
+
afterEach(() => {
|
|
297
|
+
server.resetHandlers();
|
|
298
|
+
server.restoreHandlers();
|
|
299
|
+
onHide.mockReset();
|
|
300
|
+
queryClient.clear();
|
|
301
|
+
});
|
|
302
|
+
|
|
303
|
+
const LIBRARY = "library-short-name";
|
|
304
|
+
const email = "librarian@example.com";
|
|
305
|
+
const EMAIL_CONTEXT_PROVIDER_PROPS = { email };
|
|
306
|
+
const NO_EMAIL_CONTEXT_PROVIDER_PROPS = { email: undefined };
|
|
307
|
+
|
|
308
|
+
it("shows the modal when `show` is true", async () => {
|
|
309
|
+
const {
|
|
310
|
+
getAllByRole,
|
|
311
|
+
queryAllByRole,
|
|
312
|
+
rerender,
|
|
313
|
+
} = renderWithProviders(
|
|
314
|
+
<InventoryReportRequestModal
|
|
315
|
+
show={false}
|
|
316
|
+
onHide={onHide}
|
|
317
|
+
library={LIBRARY}
|
|
318
|
+
/>,
|
|
319
|
+
{ queryClient }
|
|
320
|
+
);
|
|
321
|
+
expect(queryAllByRole("dialog")).toHaveLength(0);
|
|
322
|
+
|
|
323
|
+
rerender(
|
|
324
|
+
<InventoryReportRequestModal
|
|
325
|
+
show={true}
|
|
326
|
+
onHide={onHide}
|
|
327
|
+
library={LIBRARY}
|
|
328
|
+
/>
|
|
329
|
+
);
|
|
330
|
+
getAllByRole("dialog");
|
|
331
|
+
});
|
|
332
|
+
|
|
333
|
+
it("initially shows a request confirmation", () => {
|
|
334
|
+
const { getByRole } = renderWithProviders(
|
|
335
|
+
<InventoryReportRequestModal
|
|
336
|
+
show={true}
|
|
337
|
+
onHide={onHide}
|
|
338
|
+
library={LIBRARY}
|
|
339
|
+
/>,
|
|
340
|
+
{ queryClient }
|
|
341
|
+
);
|
|
342
|
+
const modalContent = getByRole("document");
|
|
343
|
+
const heading = within(modalContent).getByRole("heading", {
|
|
344
|
+
level: MODAL_HEADING_LEVEL,
|
|
345
|
+
});
|
|
346
|
+
const modalBody = modalContent.querySelector(".modal-body");
|
|
347
|
+
|
|
348
|
+
getByRole("button", { name: CONFIRM_BUTTON_CONTENT });
|
|
349
|
+
getByRole("button", { name: CANCEL_BUTTON_CONTENT });
|
|
350
|
+
|
|
351
|
+
expect(heading).toHaveTextContent(CONFIRMATION_MODAL_HEADING);
|
|
352
|
+
expect(modalBody).toHaveTextContent("inventory report will be generated");
|
|
353
|
+
});
|
|
354
|
+
|
|
355
|
+
it("shows admin email, when present, in request confirmation", () => {
|
|
356
|
+
let { getByRole } = renderWithProviders(
|
|
357
|
+
<InventoryReportRequestModal
|
|
358
|
+
show={true}
|
|
359
|
+
onHide={onHide}
|
|
360
|
+
library={LIBRARY}
|
|
361
|
+
/>,
|
|
362
|
+
{ queryClient, contextProviderProps: EMAIL_CONTEXT_PROVIDER_PROPS }
|
|
363
|
+
);
|
|
364
|
+
let modalBody = getByRole("document").querySelector(".modal-body");
|
|
365
|
+
expect(modalBody).toHaveTextContent(
|
|
366
|
+
"will be generated in the background and emailed to you at"
|
|
367
|
+
);
|
|
368
|
+
expect(modalBody).toHaveTextContent(email);
|
|
369
|
+
|
|
370
|
+
({ getByRole } = renderWithProviders(
|
|
371
|
+
<InventoryReportRequestModal
|
|
372
|
+
show={true}
|
|
373
|
+
onHide={onHide}
|
|
374
|
+
library={LIBRARY}
|
|
375
|
+
/>,
|
|
376
|
+
{ queryClient, contextProviderProps: NO_EMAIL_CONTEXT_PROVIDER_PROPS }
|
|
377
|
+
));
|
|
378
|
+
modalBody = getByRole("document").querySelector(".modal-body");
|
|
379
|
+
expect(modalBody).toHaveTextContent(
|
|
380
|
+
"will be generated in the background and emailed to you"
|
|
381
|
+
);
|
|
382
|
+
expect(modalBody).not.toHaveTextContent(email);
|
|
383
|
+
});
|
|
384
|
+
|
|
385
|
+
it("clicking 'cancel' hides the component", async () => {
|
|
386
|
+
const user = userEvent.setup();
|
|
387
|
+
let show = true;
|
|
388
|
+
onHide.mockImplementation(() => (show = false));
|
|
389
|
+
|
|
390
|
+
const {
|
|
391
|
+
getAllByRole,
|
|
392
|
+
getByRole,
|
|
393
|
+
queryAllByRole,
|
|
394
|
+
rerender,
|
|
395
|
+
} = renderWithProviders(
|
|
396
|
+
<InventoryReportRequestModal
|
|
397
|
+
show={show}
|
|
398
|
+
onHide={onHide}
|
|
399
|
+
library={LIBRARY}
|
|
400
|
+
/>,
|
|
401
|
+
{ queryClient }
|
|
402
|
+
);
|
|
403
|
+
getAllByRole("dialog");
|
|
404
|
+
expect(show).toBe(true);
|
|
405
|
+
expect(onHide).not.toHaveBeenCalled();
|
|
406
|
+
|
|
407
|
+
const cancelButton = getByRole("button", { name: CANCEL_BUTTON_CONTENT });
|
|
408
|
+
await user.click(cancelButton);
|
|
409
|
+
|
|
410
|
+
// `onHide` was called and modal elements are gone on the next render.
|
|
411
|
+
expect(onHide).toHaveBeenCalled();
|
|
412
|
+
expect(show).toBe(false);
|
|
413
|
+
|
|
414
|
+
rerender(
|
|
415
|
+
<InventoryReportRequestModal
|
|
416
|
+
show={show}
|
|
417
|
+
onHide={onHide}
|
|
418
|
+
library={LIBRARY}
|
|
419
|
+
/>
|
|
420
|
+
);
|
|
421
|
+
expect(queryAllByRole("dialog")).toHaveLength(0);
|
|
422
|
+
});
|
|
423
|
+
|
|
424
|
+
it("updates confirmation message, if report info request arrives in time", async () => {
|
|
425
|
+
const {
|
|
426
|
+
getByRole,
|
|
427
|
+
rerender,
|
|
428
|
+
} = renderWithProviders(
|
|
429
|
+
<InventoryReportRequestModal
|
|
430
|
+
show={true}
|
|
431
|
+
onHide={onHide}
|
|
432
|
+
library={LIBRARY}
|
|
433
|
+
/>,
|
|
434
|
+
{ queryClient }
|
|
435
|
+
);
|
|
436
|
+
|
|
437
|
+
let modalBody = getByRole("document").querySelector(".modal-body");
|
|
438
|
+
expect(modalBody).toHaveTextContent(UNKNOWN_COLLECTIONS_MESSAGE);
|
|
439
|
+
expect(modalBody).not.toHaveTextContent(COLLECTION_NAME);
|
|
440
|
+
|
|
441
|
+
await new Promise(process.nextTick);
|
|
442
|
+
rerender(
|
|
443
|
+
<InventoryReportRequestModal
|
|
444
|
+
show={true}
|
|
445
|
+
onHide={onHide}
|
|
446
|
+
library={LIBRARY}
|
|
447
|
+
/>
|
|
448
|
+
);
|
|
449
|
+
|
|
450
|
+
modalBody = getByRole("document").querySelector(".modal-body");
|
|
451
|
+
expect(modalBody).toHaveTextContent(SOME_COLLECTIONS_MESSAGE);
|
|
452
|
+
expect(modalBody).toHaveTextContent(COLLECTION_NAME);
|
|
453
|
+
});
|
|
454
|
+
|
|
455
|
+
it("disables report generation, if info indicates no collections", async () => {
|
|
456
|
+
server.use(
|
|
457
|
+
http.get(MOCK_SERVER_API_ENDPOINT_PATH, () =>
|
|
458
|
+
HttpResponse.json(INFO_SUCCESS_NO_COLLECTIONS, { status: 200 })
|
|
459
|
+
)
|
|
460
|
+
);
|
|
461
|
+
|
|
462
|
+
const {
|
|
463
|
+
getByRole,
|
|
464
|
+
rerender,
|
|
465
|
+
} = renderWithProviders(
|
|
466
|
+
<InventoryReportRequestModal
|
|
467
|
+
show={true}
|
|
468
|
+
onHide={onHide}
|
|
469
|
+
library={LIBRARY}
|
|
470
|
+
/>,
|
|
471
|
+
{ queryClient }
|
|
472
|
+
);
|
|
473
|
+
|
|
474
|
+
let modalBody = getByRole("document").querySelector(".modal-body");
|
|
475
|
+
expect(modalBody).toHaveTextContent(UNKNOWN_COLLECTIONS_MESSAGE);
|
|
476
|
+
expect(modalBody).not.toHaveTextContent(COLLECTION_NAME);
|
|
477
|
+
|
|
478
|
+
let requestButton = getByRole("button", { name: CONFIRM_BUTTON_CONTENT });
|
|
479
|
+
let cancelButton = getByRole("button", { name: CANCEL_BUTTON_CONTENT });
|
|
480
|
+
expect(requestButton).toBeEnabled();
|
|
481
|
+
expect(cancelButton).toBeEnabled();
|
|
482
|
+
|
|
483
|
+
await new Promise(process.nextTick);
|
|
484
|
+
rerender(
|
|
485
|
+
<InventoryReportRequestModal
|
|
486
|
+
show={true}
|
|
487
|
+
onHide={onHide}
|
|
488
|
+
library={LIBRARY}
|
|
489
|
+
/>
|
|
490
|
+
);
|
|
491
|
+
|
|
492
|
+
modalBody = getByRole("document").querySelector(".modal-body");
|
|
493
|
+
expect(modalBody).toHaveTextContent(NO_COLLECTIONS_MESSAGE);
|
|
494
|
+
expect(modalBody).not.toHaveTextContent(COLLECTION_NAME);
|
|
495
|
+
|
|
496
|
+
requestButton = getByRole("button", { name: CONFIRM_BUTTON_CONTENT });
|
|
497
|
+
cancelButton = getByRole("button", { name: CANCEL_BUTTON_CONTENT });
|
|
498
|
+
expect(requestButton).not.toBeEnabled();
|
|
499
|
+
expect(cancelButton).toBeEnabled();
|
|
500
|
+
});
|
|
501
|
+
|
|
502
|
+
it("displays minimal confirmation message, if report info request unsuccessful", async () => {
|
|
503
|
+
server.use(
|
|
504
|
+
http.get(
|
|
505
|
+
MOCK_SERVER_API_ENDPOINT_PATH,
|
|
506
|
+
() => new HttpResponse(null, { status: 404 })
|
|
507
|
+
)
|
|
508
|
+
);
|
|
509
|
+
|
|
510
|
+
const {
|
|
511
|
+
getByRole,
|
|
512
|
+
rerender,
|
|
513
|
+
} = renderWithProviders(
|
|
514
|
+
<InventoryReportRequestModal
|
|
515
|
+
show={true}
|
|
516
|
+
onHide={onHide}
|
|
517
|
+
library={LIBRARY}
|
|
518
|
+
/>,
|
|
519
|
+
{ queryClient }
|
|
520
|
+
);
|
|
521
|
+
|
|
522
|
+
let modalBody = getByRole("document").querySelector(".modal-body");
|
|
523
|
+
expect(modalBody).toHaveTextContent(UNKNOWN_COLLECTIONS_MESSAGE);
|
|
524
|
+
expect(modalBody).not.toHaveTextContent(COLLECTION_NAME);
|
|
525
|
+
|
|
526
|
+
await new Promise(process.nextTick);
|
|
527
|
+
rerender(
|
|
528
|
+
<InventoryReportRequestModal
|
|
529
|
+
show={true}
|
|
530
|
+
onHide={onHide}
|
|
531
|
+
library={LIBRARY}
|
|
532
|
+
/>
|
|
533
|
+
);
|
|
534
|
+
|
|
535
|
+
modalBody = getByRole("document").querySelector(".modal-body");
|
|
536
|
+
expect(modalBody).toHaveTextContent(UNKNOWN_COLLECTIONS_MESSAGE);
|
|
537
|
+
expect(modalBody).not.toHaveTextContent(COLLECTION_NAME);
|
|
538
|
+
});
|
|
539
|
+
|
|
540
|
+
it("requests report generation, if request confirmed", async () => {
|
|
541
|
+
const user = userEvent.setup();
|
|
542
|
+
|
|
543
|
+
const {
|
|
544
|
+
getByRole,
|
|
545
|
+
rerender,
|
|
546
|
+
} = renderWithProviders(
|
|
547
|
+
<InventoryReportRequestModal
|
|
548
|
+
show={true}
|
|
549
|
+
onHide={onHide}
|
|
550
|
+
library={LIBRARY}
|
|
551
|
+
/>,
|
|
552
|
+
{ queryClient }
|
|
553
|
+
);
|
|
554
|
+
|
|
555
|
+
const confirmationButton = getByRole("button", {
|
|
556
|
+
name: CONFIRM_BUTTON_CONTENT,
|
|
557
|
+
});
|
|
558
|
+
let modalHeading = getByRole("heading", { level: MODAL_HEADING_LEVEL });
|
|
559
|
+
expect(modalHeading).toHaveTextContent(CONFIRMATION_MODAL_HEADING);
|
|
560
|
+
|
|
561
|
+
await user.click(confirmationButton);
|
|
562
|
+
|
|
563
|
+
rerender(
|
|
564
|
+
<InventoryReportRequestModal
|
|
565
|
+
show={true}
|
|
566
|
+
onHide={onHide}
|
|
567
|
+
library={LIBRARY}
|
|
568
|
+
/>
|
|
569
|
+
);
|
|
570
|
+
|
|
571
|
+
getByRole("button", { name: ACK_RESPONSE_BUTTON_CONTENT });
|
|
572
|
+
modalHeading = getByRole("heading", { level: MODAL_HEADING_LEVEL });
|
|
573
|
+
expect(modalHeading).toHaveTextContent(ACK_RESPONSE_HEADING);
|
|
574
|
+
});
|
|
575
|
+
|
|
576
|
+
it("displays success message, when request is successful", async () => {
|
|
577
|
+
const user = userEvent.setup();
|
|
578
|
+
|
|
579
|
+
const {
|
|
580
|
+
getByRole,
|
|
581
|
+
rerender,
|
|
582
|
+
} = renderWithProviders(
|
|
583
|
+
<InventoryReportRequestModal
|
|
584
|
+
show={true}
|
|
585
|
+
onHide={onHide}
|
|
586
|
+
library={LIBRARY}
|
|
587
|
+
/>,
|
|
588
|
+
{ queryClient }
|
|
589
|
+
);
|
|
590
|
+
|
|
591
|
+
const confirmationButton = getByRole("button", {
|
|
592
|
+
name: CONFIRM_BUTTON_CONTENT,
|
|
593
|
+
});
|
|
594
|
+
await user.click(confirmationButton);
|
|
595
|
+
|
|
596
|
+
rerender(
|
|
597
|
+
<InventoryReportRequestModal
|
|
598
|
+
show={true}
|
|
599
|
+
onHide={onHide}
|
|
600
|
+
library={LIBRARY}
|
|
601
|
+
/>
|
|
602
|
+
);
|
|
603
|
+
|
|
604
|
+
getByRole("button", { name: ACK_RESPONSE_BUTTON_CONTENT });
|
|
605
|
+
const modalBody = getByRole("document").querySelector(".modal-body");
|
|
606
|
+
expect(modalBody).toHaveTextContent(
|
|
607
|
+
`✅ ${GENERATE_REPORT_SUCCESS.message}`
|
|
608
|
+
);
|
|
609
|
+
});
|
|
610
|
+
|
|
611
|
+
it("displays error message, when request is unsuccessful", async () => {
|
|
612
|
+
server.use(
|
|
613
|
+
http.post(
|
|
614
|
+
MOCK_SERVER_API_ENDPOINT_PATH,
|
|
615
|
+
() => new HttpResponse(null, { status: 404 })
|
|
616
|
+
)
|
|
617
|
+
);
|
|
618
|
+
const user = userEvent.setup();
|
|
619
|
+
|
|
620
|
+
const {
|
|
621
|
+
getByRole,
|
|
622
|
+
rerender,
|
|
623
|
+
} = renderWithProviders(
|
|
624
|
+
<InventoryReportRequestModal
|
|
625
|
+
show={true}
|
|
626
|
+
onHide={onHide}
|
|
627
|
+
library={LIBRARY}
|
|
628
|
+
/>,
|
|
629
|
+
{ queryClient }
|
|
630
|
+
);
|
|
631
|
+
|
|
632
|
+
const confirmationButton = getByRole("button", {
|
|
633
|
+
name: CONFIRM_BUTTON_CONTENT,
|
|
634
|
+
});
|
|
635
|
+
await user.click(confirmationButton);
|
|
636
|
+
|
|
637
|
+
rerender(
|
|
638
|
+
<InventoryReportRequestModal
|
|
639
|
+
show={true}
|
|
640
|
+
onHide={onHide}
|
|
641
|
+
library={LIBRARY}
|
|
642
|
+
/>
|
|
643
|
+
);
|
|
644
|
+
|
|
645
|
+
getByRole("button", { name: ACK_RESPONSE_BUTTON_CONTENT });
|
|
646
|
+
const modalBody = getByRole("document").querySelector(".modal-body");
|
|
647
|
+
expect(modalBody).toHaveTextContent(
|
|
648
|
+
"❌ Request failed with status 404: POST"
|
|
649
|
+
);
|
|
650
|
+
});
|
|
651
|
+
});
|
|
652
|
+
});
|
|
@@ -2,10 +2,10 @@ import * as React from "react";
|
|
|
2
2
|
import { screen, waitFor } from "@testing-library/react";
|
|
3
3
|
|
|
4
4
|
import QuicksightDashboard from "../../../src/components/QuicksightDashboard";
|
|
5
|
-
import { LibrariesData
|
|
6
|
-
import buildStore
|
|
5
|
+
import { LibrariesData } from "../../../src/interfaces";
|
|
6
|
+
import buildStore from "../../../src/store";
|
|
7
7
|
import { setupServer } from "msw/node";
|
|
8
|
-
import {
|
|
8
|
+
import { http, HttpResponse } from "msw";
|
|
9
9
|
import renderWithContext from "../testUtils/renderWithContext";
|
|
10
10
|
|
|
11
11
|
const libraries: LibrariesData = { libraries: [{ uuid: "my-uuid" }] };
|
|
@@ -15,15 +15,15 @@ const dashboardUrlData = { embedUrl: embedUrl };
|
|
|
15
15
|
|
|
16
16
|
describe("QuicksightDashboard", () => {
|
|
17
17
|
const server = setupServer(
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
"
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
)
|
|
18
|
+
http.get("/admin/libraries", () => HttpResponse.json(libraries)),
|
|
19
|
+
http.get(`/admin/quicksight_embed/${dashboardId}`, ({ request }) => {
|
|
20
|
+
const url = new URL(request.url);
|
|
21
|
+
const libraryUuids = url.searchParams.get("libraryUuids");
|
|
22
|
+
|
|
23
|
+
if (libraryUuids === libraries["libraries"][0]["uuid"]) {
|
|
24
|
+
return HttpResponse.json(dashboardUrlData);
|
|
25
|
+
}
|
|
26
|
+
})
|
|
27
27
|
);
|
|
28
28
|
|
|
29
29
|
beforeAll(() => {
|