@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
@@ -149,5 +149,5 @@
149
149
  "*.{js,jsx,ts,tsx,css,md}": "prettier --write",
150
150
  "*.{js,css,md}": "prettier --write"
151
151
  },
152
- "version": "1.22.0-post.4"
152
+ "version": "1.22.0-post.5"
153
153
  }
@@ -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
- const assertLoadingState = ({ getByRole }) => {
161
- getByRole("dialog", { name: "Loading" });
162
- getByRole("heading", { level: 1, name: "Loading" });
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
- it("shows/hides the loading indicator", async () => {
175
- // We haven't tried to fetch anything yet.
176
- expect(fetchMock.calls()).toHaveLength(0);
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
- const { rerender, getByRole, queryByRole } = renderWithProviders(
179
- <Stats />
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
- // We should start in the loading state.
183
- assertLoadingState({ getByRole });
188
+ const { rerender, getByRole, queryByRole } = renderWithProviders(
189
+ <Stats />
190
+ );
184
191
 
185
- // Wait a tick for the statistics to render.
186
- await new Promise(process.nextTick);
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
- rerender(<Stats />);
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
- // We should show our content without the loading state.
193
- assertNotLoadingState({ queryByRole });
194
- getByRole("heading", { level: 2, name: ALL_LIBRARIES_HEADING });
200
+ rerender(<Stats />);
195
201
 
196
- // We haven't made another call, since the response is cached.
197
- expect(fetchMock.calls()).toHaveLength(1);
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
- it("doesn't fetch again, because response is cached", async () => {
201
- const { getByRole, queryByRole } = renderWithProviders(<Stats />);
206
+ // We haven't made another call, since the response is cached.
207
+ expect(fetchMock.calls()).toHaveLength(1);
208
+ });
202
209
 
203
- // We should show our content immediately, without entering the loading state.
204
- assertNotLoadingState({ queryByRole });
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
- // We never tried to fetch anything because the result is cached.
208
- expect(fetchMock.calls()).toHaveLength(0);
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
- it("show stats for a library, if a library is specified", async () => {
212
- const { getByRole, queryByRole, getByText } = renderWithProviders(
213
- <Stats library={sampleLibraryKey} />
214
- );
217
+ // We never tried to fetch anything because the result is cached.
218
+ expect(fetchMock.calls()).toHaveLength(0);
219
+ });
215
220
 
216
- // We should show our content immediately, without entering the loading state.
217
- assertNotLoadingState({ queryByRole });
218
- getByRole("heading", {
219
- level: 2,
220
- name: `${sampleLibraryName} Dashboard`,
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
- // We never tried to fetch anything because the result is cached.
226
- expect(fetchMock.calls()).toHaveLength(0);
227
- });
239
+ it("shows site-wide stats when no library specified", async () => {
240
+ const { getByRole, getByText, queryByRole } = renderWithProviders(
241
+ <Stats />
242
+ );
228
243
 
229
- it("shows site-wide stats when no library specified", async () => {
230
- const { getByRole, getByText, queryByRole } = renderWithProviders(
231
- <Stats />
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
- // We should show our content immediately, without entering the loading state.
235
- assertNotLoadingState({ queryByRole });
254
+ // We never tried to fetch anything because the result is cached.
255
+ expect(fetchMock.calls()).toHaveLength(0);
256
+ });
257
+ });
236
258
 
237
- getByRole("heading", { level: 2, name: ALL_LIBRARIES_HEADING });
238
- getByRole("heading", { level: 3, name: "Current Circulation Activity" });
239
- getByText("1.6k");
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
- // We never tried to fetch anything because the result is cached.
242
- expect(fetchMock.calls()).toHaveLength(0);
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 { container, queryByRole } = renderWithProviders(
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
- const result = queryByRole("button", { name: "⬇︎" });
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;