@thepalaceproject/circulation-admin 1.22.0-post.4 → 1.22.0-post.5
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/package.json
CHANGED
|
@@ -44,6 +44,14 @@ describe("Dashboard Statistics", () => {
|
|
|
44
44
|
Response,
|
|
45
45
|
});
|
|
46
46
|
|
|
47
|
+
const statGroupToHeading = {
|
|
48
|
+
patrons: "Current Circulation Activity",
|
|
49
|
+
circulations: "Circulation Totals",
|
|
50
|
+
inventory: "Inventory",
|
|
51
|
+
usageReports: "Usage and Reports",
|
|
52
|
+
collections: "Configured Collections",
|
|
53
|
+
};
|
|
54
|
+
|
|
47
55
|
describe("query hook correctly handles fetch responses", () => {
|
|
48
56
|
const wrapper = componentWithProviders();
|
|
49
57
|
|
|
@@ -153,93 +161,134 @@ describe("Dashboard Statistics", () => {
|
|
|
153
161
|
afterAll(() => {
|
|
154
162
|
fetchMock.restore();
|
|
155
163
|
});
|
|
156
|
-
afterEach(() => {
|
|
157
|
-
fetchMock.resetHistory();
|
|
158
|
-
});
|
|
159
164
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
};
|
|
164
|
-
const assertNotLoadingState = ({ queryByRole }) => {
|
|
165
|
-
const missingLoadingDialog = queryByRole("dialog", { name: "Loading" });
|
|
166
|
-
const missingLoadingHeading = queryByRole("heading", {
|
|
167
|
-
level: 1,
|
|
168
|
-
name: "Loading",
|
|
165
|
+
describe("correctly handles fetching and caching", () => {
|
|
166
|
+
afterEach(() => {
|
|
167
|
+
fetchMock.resetHistory();
|
|
169
168
|
});
|
|
170
|
-
expect(missingLoadingDialog).not.toBeInTheDocument();
|
|
171
|
-
expect(missingLoadingHeading).not.toBeInTheDocument();
|
|
172
|
-
};
|
|
173
169
|
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
170
|
+
const assertLoadingState = ({ getByRole }) => {
|
|
171
|
+
getByRole("dialog", { name: "Loading" });
|
|
172
|
+
getByRole("heading", { level: 1, name: "Loading" });
|
|
173
|
+
};
|
|
174
|
+
const assertNotLoadingState = ({ queryByRole }) => {
|
|
175
|
+
const missingLoadingDialog = queryByRole("dialog", { name: "Loading" });
|
|
176
|
+
const missingLoadingHeading = queryByRole("heading", {
|
|
177
|
+
level: 1,
|
|
178
|
+
name: "Loading",
|
|
179
|
+
});
|
|
180
|
+
expect(missingLoadingDialog).not.toBeInTheDocument();
|
|
181
|
+
expect(missingLoadingHeading).not.toBeInTheDocument();
|
|
182
|
+
};
|
|
177
183
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
184
|
+
it("shows/hides the loading indicator", async () => {
|
|
185
|
+
// We haven't tried to fetch anything yet.
|
|
186
|
+
expect(fetchMock.calls()).toHaveLength(0);
|
|
181
187
|
|
|
182
|
-
|
|
183
|
-
|
|
188
|
+
const { rerender, getByRole, queryByRole } = renderWithProviders(
|
|
189
|
+
<Stats />
|
|
190
|
+
);
|
|
184
191
|
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
// Now we've fetched something.
|
|
188
|
-
expect(fetchMock.calls()).toHaveLength(1);
|
|
192
|
+
// We should start in the loading state.
|
|
193
|
+
assertLoadingState({ getByRole });
|
|
189
194
|
|
|
190
|
-
|
|
195
|
+
// Wait a tick for the statistics to render.
|
|
196
|
+
await new Promise(process.nextTick);
|
|
197
|
+
// Now we've fetched something.
|
|
198
|
+
expect(fetchMock.calls()).toHaveLength(1);
|
|
191
199
|
|
|
192
|
-
|
|
193
|
-
assertNotLoadingState({ queryByRole });
|
|
194
|
-
getByRole("heading", { level: 2, name: ALL_LIBRARIES_HEADING });
|
|
200
|
+
rerender(<Stats />);
|
|
195
201
|
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
202
|
+
// We should show our content without the loading state.
|
|
203
|
+
assertNotLoadingState({ queryByRole });
|
|
204
|
+
getByRole("heading", { level: 2, name: ALL_LIBRARIES_HEADING });
|
|
199
205
|
|
|
200
|
-
|
|
201
|
-
|
|
206
|
+
// We haven't made another call, since the response is cached.
|
|
207
|
+
expect(fetchMock.calls()).toHaveLength(1);
|
|
208
|
+
});
|
|
202
209
|
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
getByRole("heading", { level: 2, name: ALL_LIBRARIES_HEADING });
|
|
210
|
+
it("doesn't fetch again, because response is cached", async () => {
|
|
211
|
+
const { getByRole, queryByRole } = renderWithProviders(<Stats />);
|
|
206
212
|
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
213
|
+
// We should show our content immediately, without entering the loading state.
|
|
214
|
+
assertNotLoadingState({ queryByRole });
|
|
215
|
+
getByRole("heading", { level: 2, name: ALL_LIBRARIES_HEADING });
|
|
210
216
|
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
);
|
|
217
|
+
// We never tried to fetch anything because the result is cached.
|
|
218
|
+
expect(fetchMock.calls()).toHaveLength(0);
|
|
219
|
+
});
|
|
215
220
|
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
+
it("show stats for a library, if a library is specified", async () => {
|
|
222
|
+
const { getByRole, queryByRole, getByText } = renderWithProviders(
|
|
223
|
+
<Stats library={sampleLibraryKey} />
|
|
224
|
+
);
|
|
225
|
+
|
|
226
|
+
// We should show our content immediately, without entering the loading state.
|
|
227
|
+
assertNotLoadingState({ queryByRole });
|
|
228
|
+
getByRole("heading", {
|
|
229
|
+
level: 2,
|
|
230
|
+
name: `${sampleLibraryName} Dashboard`,
|
|
231
|
+
});
|
|
232
|
+
getByRole("heading", { level: 3, name: statGroupToHeading.patrons });
|
|
233
|
+
getByText("21");
|
|
234
|
+
|
|
235
|
+
// We never tried to fetch anything because the result is cached.
|
|
236
|
+
expect(fetchMock.calls()).toHaveLength(0);
|
|
221
237
|
});
|
|
222
|
-
getByRole("heading", { level: 3, name: "Current Circulation Activity" });
|
|
223
|
-
getByText("623");
|
|
224
238
|
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
239
|
+
it("shows site-wide stats when no library specified", async () => {
|
|
240
|
+
const { getByRole, getByText, queryByRole } = renderWithProviders(
|
|
241
|
+
<Stats />
|
|
242
|
+
);
|
|
228
243
|
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
244
|
+
// We should show our content immediately, without entering the loading state.
|
|
245
|
+
assertNotLoadingState({ queryByRole });
|
|
246
|
+
|
|
247
|
+
getByRole("heading", { level: 2, name: ALL_LIBRARIES_HEADING });
|
|
248
|
+
getByRole("heading", {
|
|
249
|
+
level: 3,
|
|
250
|
+
name: "Current Circulation Activity",
|
|
251
|
+
});
|
|
252
|
+
getByText("1.6k");
|
|
233
253
|
|
|
234
|
-
|
|
235
|
-
|
|
254
|
+
// We never tried to fetch anything because the result is cached.
|
|
255
|
+
expect(fetchMock.calls()).toHaveLength(0);
|
|
256
|
+
});
|
|
257
|
+
});
|
|
236
258
|
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
259
|
+
describe("has correct statistics groups", () => {
|
|
260
|
+
it("shows the right groups with a library", () => {
|
|
261
|
+
const { getAllByRole } = renderWithProviders(
|
|
262
|
+
<Stats library={sampleLibraryKey} />
|
|
263
|
+
);
|
|
264
|
+
|
|
265
|
+
const groupHeadings = getAllByRole("heading", { level: 3 });
|
|
266
|
+
const expectedHeadings = [
|
|
267
|
+
statGroupToHeading.patrons,
|
|
268
|
+
statGroupToHeading.usageReports,
|
|
269
|
+
statGroupToHeading.collections,
|
|
270
|
+
];
|
|
271
|
+
expect(groupHeadings).toHaveLength(3);
|
|
272
|
+
groupHeadings.forEach((heading, index) => {
|
|
273
|
+
expect(heading).toHaveTextContent(expectedHeadings[index]);
|
|
274
|
+
});
|
|
275
|
+
});
|
|
240
276
|
|
|
241
|
-
|
|
242
|
-
|
|
277
|
+
it("shows the right groups without a library", () => {
|
|
278
|
+
const { getAllByRole } = renderWithProviders(<Stats />);
|
|
279
|
+
|
|
280
|
+
const groupHeadings = getAllByRole("heading", { level: 3 });
|
|
281
|
+
const expectedHeadings = [
|
|
282
|
+
statGroupToHeading.patrons,
|
|
283
|
+
statGroupToHeading.circulations,
|
|
284
|
+
statGroupToHeading.inventory,
|
|
285
|
+
statGroupToHeading.collections,
|
|
286
|
+
];
|
|
287
|
+
expect(groupHeadings).toHaveLength(4);
|
|
288
|
+
groupHeadings.forEach((heading, index) => {
|
|
289
|
+
expect(heading).toHaveTextContent(expectedHeadings[index]);
|
|
290
|
+
});
|
|
291
|
+
});
|
|
243
292
|
});
|
|
244
293
|
});
|
|
245
294
|
|
|
@@ -256,9 +305,11 @@ describe("Dashboard Statistics", () => {
|
|
|
256
305
|
const managerAll = [{ role: "manager-all" }];
|
|
257
306
|
const librarianAll = [{ role: "librarian-all" }];
|
|
258
307
|
|
|
308
|
+
const fakeQuickSightHref = "https://example.com/fakeQS";
|
|
259
309
|
const baseContextProviderProps = {
|
|
260
310
|
csrfToken: "",
|
|
261
311
|
featureFlags: { reportsOnlyForSysadmins: false },
|
|
312
|
+
quicksightPagePath: fakeQuickSightHref,
|
|
262
313
|
};
|
|
263
314
|
|
|
264
315
|
const renderFor = (
|
|
@@ -271,12 +322,21 @@ describe("Dashboard Statistics", () => {
|
|
|
271
322
|
roles,
|
|
272
323
|
};
|
|
273
324
|
|
|
274
|
-
const {
|
|
325
|
+
const {
|
|
326
|
+
container,
|
|
327
|
+
getByRole,
|
|
328
|
+
queryByRole,
|
|
329
|
+
} = renderWithProviders(
|
|
275
330
|
<LibraryStats stats={sampleStatsData} library={sampleLibraryKey} />,
|
|
276
331
|
{ contextProviderProps }
|
|
277
332
|
);
|
|
278
333
|
|
|
279
|
-
|
|
334
|
+
// We should always render a Usage reports group when a library is specified.
|
|
335
|
+
getByRole("heading", { level: 3, name: statGroupToHeading.usageReports });
|
|
336
|
+
const usageReportLink = getByRole("link", { name: /View Usage/i });
|
|
337
|
+
expect(usageReportLink).toHaveAttribute("href", fakeQuickSightHref);
|
|
338
|
+
|
|
339
|
+
const result = queryByRole("button", { name: /Request Report/i });
|
|
280
340
|
// Clean up the container after each render.
|
|
281
341
|
document.body.removeChild(container);
|
|
282
342
|
return result;
|