@thepalaceproject/circulation-admin 1.45.0 → 1.46.0-post.2
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
|
@@ -364,4 +364,19 @@ describe("CustomListEditor", () => {
|
|
|
364
364
|
container.querySelector(".sharing-info button")
|
|
365
365
|
).not.toBeInTheDocument();
|
|
366
366
|
});
|
|
367
|
+
|
|
368
|
+
it("does not render a share button once the list is already shared, and shows the shared-state copy", () => {
|
|
369
|
+
const { container } = renderEditor({ isShared: true });
|
|
370
|
+
|
|
371
|
+
expect(
|
|
372
|
+
container.querySelector(".sharing-info button")
|
|
373
|
+
).not.toBeInTheDocument();
|
|
374
|
+
|
|
375
|
+
expect(
|
|
376
|
+
screen.getByText(
|
|
377
|
+
"This list has been shared with other libraries, and will automatically be made available to any libraries registered in this Collection Manager, including libraries registered in the future.",
|
|
378
|
+
{ exact: false }
|
|
379
|
+
)
|
|
380
|
+
).toBeInTheDocument();
|
|
381
|
+
});
|
|
367
382
|
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
|
-
import { render, screen, waitFor } from "@testing-library/react";
|
|
2
|
+
import { render, screen, waitFor, within } from "@testing-library/react";
|
|
3
3
|
import userEvent from "@testing-library/user-event";
|
|
4
4
|
import * as fetchMock from "fetch-mock-jest";
|
|
5
5
|
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
|
|
@@ -217,8 +217,11 @@ describe("PatronAuthServiceEditForm – serialization", () => {
|
|
|
217
217
|
|
|
218
218
|
await user.click(saveButton);
|
|
219
219
|
|
|
220
|
-
//
|
|
220
|
+
// Saving collapses the library. Reopening it shows the rule was stored in
|
|
221
|
+
// library state, not just read from the editor.
|
|
221
222
|
expect(screen.queryByRole("button", { name: /Add Rule/i })).toBeNull();
|
|
223
|
+
await user.click(screen.getByRole("button", { name: /Edit/i }));
|
|
224
|
+
expect(screen.getByLabelText(/Rule Name/i)).toHaveValue("Test Rule");
|
|
222
225
|
});
|
|
223
226
|
|
|
224
227
|
it("includes patron_blocking_rules in payload when adding a new library", async () => {
|
|
@@ -253,8 +256,99 @@ describe("PatronAuthServiceEditForm – serialization", () => {
|
|
|
253
256
|
|
|
254
257
|
await user.click(addButton);
|
|
255
258
|
|
|
256
|
-
//
|
|
259
|
+
// The new-library editor is gone. Opening the added library shows the rule
|
|
260
|
+
// was stored in library state.
|
|
257
261
|
expect(screen.queryByLabelText(/Rule Name/i)).toBeNull();
|
|
262
|
+
await user.click(screen.getByRole("button", { name: /Edit/i }));
|
|
263
|
+
expect(screen.getByLabelText(/Rule Name/i)).toHaveValue("New Rule");
|
|
264
|
+
});
|
|
265
|
+
});
|
|
266
|
+
|
|
267
|
+
describe("PatronAuthServiceEditForm – per-library settings", () => {
|
|
268
|
+
const LIB_SETTING_KEY = "lib_setting";
|
|
269
|
+
const protocolWithLibrarySettings = {
|
|
270
|
+
...SIP2_PROTOCOL_DATA,
|
|
271
|
+
library_settings: [{ key: LIB_SETTING_KEY, label: "Library setting" }],
|
|
272
|
+
};
|
|
273
|
+
const dataWithLibrarySettings: PatronAuthServicesData = {
|
|
274
|
+
...servicesData,
|
|
275
|
+
protocols: [protocolWithLibrarySettings, OTHER_PROTOCOL_DATA],
|
|
276
|
+
};
|
|
277
|
+
const settingInput = (root: HTMLElement) =>
|
|
278
|
+
within(root).getByRole("textbox", {
|
|
279
|
+
name: /Library setting/i,
|
|
280
|
+
}) as HTMLInputElement;
|
|
281
|
+
|
|
282
|
+
it("keeps a library setting entered when adding a new library", async () => {
|
|
283
|
+
const user = userEvent.setup();
|
|
284
|
+
const item = {
|
|
285
|
+
id: 3,
|
|
286
|
+
protocol: SIP2_PROTOCOL,
|
|
287
|
+
settings: {},
|
|
288
|
+
libraries: [],
|
|
289
|
+
};
|
|
290
|
+
const { container } = renderForm(
|
|
291
|
+
<PatronAuthServiceEditForm
|
|
292
|
+
{...baseProps}
|
|
293
|
+
data={dataWithLibrarySettings}
|
|
294
|
+
item={item}
|
|
295
|
+
/>
|
|
296
|
+
);
|
|
297
|
+
|
|
298
|
+
await expandLibrariesPanel(user);
|
|
299
|
+
await user.selectOptions(
|
|
300
|
+
screen.getByRole("combobox", { name: /Add Library/i }),
|
|
301
|
+
LIBRARY_SHORT_NAME
|
|
302
|
+
);
|
|
303
|
+
await user.type(settingInput(container), "added value");
|
|
304
|
+
await user.click(screen.getByRole("button", { name: /Add Library/i }));
|
|
305
|
+
|
|
306
|
+
// Reopen the new library's settings; the value entered on add is there.
|
|
307
|
+
await user.click(screen.getByRole("button", { name: /Edit/i }));
|
|
308
|
+
const editSection = container.querySelector(
|
|
309
|
+
".edit-library-settings"
|
|
310
|
+
) as HTMLElement;
|
|
311
|
+
expect(settingInput(editSection).value).toBe("added value");
|
|
312
|
+
});
|
|
313
|
+
|
|
314
|
+
it("keeps a library setting changed when editing an existing library", async () => {
|
|
315
|
+
const user = userEvent.setup();
|
|
316
|
+
const item = {
|
|
317
|
+
...buildSIP2Item(),
|
|
318
|
+
libraries: [
|
|
319
|
+
{ short_name: LIBRARY_SHORT_NAME, [LIB_SETTING_KEY]: "old value" },
|
|
320
|
+
],
|
|
321
|
+
};
|
|
322
|
+
const { container } = renderForm(
|
|
323
|
+
<PatronAuthServiceEditForm
|
|
324
|
+
{...baseProps}
|
|
325
|
+
data={dataWithLibrarySettings}
|
|
326
|
+
item={item}
|
|
327
|
+
/>
|
|
328
|
+
);
|
|
329
|
+
|
|
330
|
+
await expandLibrariesPanel(user);
|
|
331
|
+
const clickEdit = () =>
|
|
332
|
+
user.click(screen.getByRole("button", { name: /Edit/i }));
|
|
333
|
+
await clickEdit();
|
|
334
|
+
let editSection = container.querySelector(
|
|
335
|
+
".edit-library-settings"
|
|
336
|
+
) as HTMLElement;
|
|
337
|
+
expect(settingInput(editSection).value).toBe("old value");
|
|
338
|
+
|
|
339
|
+
await user.clear(settingInput(editSection));
|
|
340
|
+
await user.type(settingInput(editSection), "new value");
|
|
341
|
+
await user.click(
|
|
342
|
+
editSection.querySelector("button.edit-library") as HTMLElement
|
|
343
|
+
);
|
|
344
|
+
|
|
345
|
+
// Saving collapses the library; reopening shows the saved value.
|
|
346
|
+
expect(container.querySelector(".edit-library-settings")).toBeNull();
|
|
347
|
+
await clickEdit();
|
|
348
|
+
editSection = container.querySelector(
|
|
349
|
+
".edit-library-settings"
|
|
350
|
+
) as HTMLElement;
|
|
351
|
+
expect(settingInput(editSection).value).toBe("new value");
|
|
258
352
|
});
|
|
259
353
|
});
|
|
260
354
|
|
|
@@ -4,6 +4,7 @@ import { render, within } from "@testing-library/react";
|
|
|
4
4
|
import userEvent from "@testing-library/user-event";
|
|
5
5
|
|
|
6
6
|
import ServiceEditForm, {
|
|
7
|
+
libraryRefKey,
|
|
7
8
|
ServiceEditFormProps,
|
|
8
9
|
ServiceEditFormState,
|
|
9
10
|
} from "../../../src/components/ServiceEditForm";
|
|
@@ -896,6 +897,27 @@ describe("ServiceEditForm", () => {
|
|
|
896
897
|
expect(libraries).toHaveLength(0);
|
|
897
898
|
});
|
|
898
899
|
|
|
900
|
+
it("removes an expanded library and closes its settings", async () => {
|
|
901
|
+
const user = userEvent.setup();
|
|
902
|
+
const { container } = renderForm({ item: serviceData });
|
|
903
|
+
const libraryItem = container.querySelector(
|
|
904
|
+
".with-remove-button"
|
|
905
|
+
) as HTMLElement;
|
|
906
|
+
|
|
907
|
+
await user.click(
|
|
908
|
+
libraryItem.querySelector("button.edit-btn") as HTMLElement
|
|
909
|
+
);
|
|
910
|
+
expect(
|
|
911
|
+
container.querySelector(".edit-library-settings")
|
|
912
|
+
).toBeInTheDocument();
|
|
913
|
+
|
|
914
|
+
await user.click(
|
|
915
|
+
libraryItem.querySelector("button.remove-btn") as HTMLElement
|
|
916
|
+
);
|
|
917
|
+
expect(container.querySelectorAll(".with-remove-button")).toHaveLength(0);
|
|
918
|
+
expect(container.querySelector(".edit-library-settings")).toBeNull();
|
|
919
|
+
});
|
|
920
|
+
|
|
899
921
|
it("edits a library", async () => {
|
|
900
922
|
const user = userEvent.setup();
|
|
901
923
|
const { container } = renderForm({ item: serviceData });
|
|
@@ -978,6 +1000,15 @@ describe("ServiceEditForm", () => {
|
|
|
978
1000
|
).toBe("option3");
|
|
979
1001
|
});
|
|
980
1002
|
|
|
1003
|
+
it("builds library ref keys for add and edit mode", () => {
|
|
1004
|
+
expect(libraryRefKey("key", "add")).toBe("key");
|
|
1005
|
+
expect(libraryRefKey("key", "edit", "nypl")).toBe("nypl_key");
|
|
1006
|
+
// Compile-time guard: ts-jest fails this file if the overloads stop
|
|
1007
|
+
// rejecting an edit-mode call with no short name.
|
|
1008
|
+
// @ts-expect-error edit mode must pass the library short name
|
|
1009
|
+
libraryRefKey("key", "edit");
|
|
1010
|
+
});
|
|
1011
|
+
|
|
981
1012
|
it("calls save when the form is submitted", async () => {
|
|
982
1013
|
// The reusable Form wires submission solely through its submit button's
|
|
983
1014
|
// onClick, so clicking it is the only way to submit; assert the resulting
|
|
@@ -1059,6 +1090,28 @@ describe("ServiceEditForm", () => {
|
|
|
1059
1090
|
expect(nameInput().value).toBe("");
|
|
1060
1091
|
});
|
|
1061
1092
|
|
|
1093
|
+
it("clears every associated library after a successful save (PP-5153)", () => {
|
|
1094
|
+
const threeLibraries = {
|
|
1095
|
+
...serviceData,
|
|
1096
|
+
libraries: [
|
|
1097
|
+
{ short_name: "nypl" },
|
|
1098
|
+
{ short_name: "bpl" },
|
|
1099
|
+
{ short_name: "qpl" },
|
|
1100
|
+
],
|
|
1101
|
+
};
|
|
1102
|
+
const { container, rerender } = renderForm({ item: threeLibraries });
|
|
1103
|
+
expect(container.querySelectorAll(".with-remove-button")).toHaveLength(3);
|
|
1104
|
+
|
|
1105
|
+
// clearForm fires onRemove once per library inside one React batch.
|
|
1106
|
+
// Each removal must build on the previous one, otherwise only the last
|
|
1107
|
+
// one survives and the other libraries stay in the list.
|
|
1108
|
+
rerenderForm(rerender, {
|
|
1109
|
+
item: threeLibraries,
|
|
1110
|
+
responseBody: "new service",
|
|
1111
|
+
});
|
|
1112
|
+
expect(container.querySelectorAll(".with-remove-button")).toHaveLength(0);
|
|
1113
|
+
});
|
|
1114
|
+
|
|
1062
1115
|
it("doesn't clear the form if there's an error message", async () => {
|
|
1063
1116
|
const user = userEvent.setup();
|
|
1064
1117
|
const { container, rerender } = renderForm();
|