@thepalaceproject/circulation-admin 1.45.0-post.7 → 1.46.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/package.json CHANGED
@@ -139,5 +139,5 @@
139
139
  "*.{js,jsx,ts,tsx,css,md}": "prettier --write",
140
140
  "*.{js,css,md}": "prettier --write"
141
141
  },
142
- "version": "1.45.0-post.7"
142
+ "version": "1.46.0-post.1"
143
143
  }
@@ -258,6 +258,92 @@ describe("PatronAuthServiceEditForm – serialization", () => {
258
258
  });
259
259
  });
260
260
 
261
+ describe("PatronAuthServiceEditForm – per-library settings", () => {
262
+ const LIB_SETTING_KEY = "lib_setting";
263
+ const protocolWithLibrarySettings = {
264
+ ...SIP2_PROTOCOL_DATA,
265
+ library_settings: [{ key: LIB_SETTING_KEY, label: "Library setting" }],
266
+ };
267
+ const dataWithLibrarySettings: PatronAuthServicesData = {
268
+ ...servicesData,
269
+ protocols: [protocolWithLibrarySettings, OTHER_PROTOCOL_DATA],
270
+ };
271
+ const settingInput = (root: ParentNode) =>
272
+ root.querySelector(`input[name="${LIB_SETTING_KEY}"]`) as HTMLInputElement;
273
+
274
+ it("keeps a library setting entered when adding a new library", async () => {
275
+ const user = userEvent.setup();
276
+ const item = {
277
+ id: 3,
278
+ protocol: SIP2_PROTOCOL,
279
+ settings: {},
280
+ libraries: [],
281
+ };
282
+ const { container } = renderForm(
283
+ <PatronAuthServiceEditForm
284
+ {...baseProps}
285
+ data={dataWithLibrarySettings}
286
+ item={item}
287
+ />
288
+ );
289
+
290
+ await expandLibrariesPanel(user);
291
+ await user.selectOptions(
292
+ screen.getByRole("combobox", { name: /Add Library/i }),
293
+ LIBRARY_SHORT_NAME
294
+ );
295
+ await user.type(settingInput(container), "added value");
296
+ await user.click(screen.getByRole("button", { name: /Add Library/i }));
297
+
298
+ // Reopen the new library's settings; the value entered on add is there.
299
+ await user.click(screen.getByRole("button", { name: /Edit/i }));
300
+ const editSection = container.querySelector(
301
+ ".edit-library-settings"
302
+ ) as HTMLElement;
303
+ expect(settingInput(editSection).value).toBe("added value");
304
+ });
305
+
306
+ it("keeps a library setting changed when editing an existing library", async () => {
307
+ const user = userEvent.setup();
308
+ const item = {
309
+ ...buildSIP2Item(),
310
+ libraries: [
311
+ { short_name: LIBRARY_SHORT_NAME, [LIB_SETTING_KEY]: "old value" },
312
+ ],
313
+ };
314
+ const { container } = renderForm(
315
+ <PatronAuthServiceEditForm
316
+ {...baseProps}
317
+ data={dataWithLibrarySettings}
318
+ item={item}
319
+ />
320
+ );
321
+
322
+ await expandLibrariesPanel(user);
323
+ const clickEdit = () =>
324
+ user.click(screen.getByRole("button", { name: /Edit/i }));
325
+ await clickEdit();
326
+ let editSection = container.querySelector(
327
+ ".edit-library-settings"
328
+ ) as HTMLElement;
329
+ expect(settingInput(editSection).value).toBe("old value");
330
+
331
+ await user.clear(settingInput(editSection));
332
+ await user.type(settingInput(editSection), "new value");
333
+ await user.click(
334
+ editSection.querySelector("button.edit-library") as HTMLElement
335
+ );
336
+
337
+ // Saving collapses the library; reopening shows the saved value.
338
+ expect(container.querySelector(".edit-library-settings")).toBeNull();
339
+ await clickEdit();
340
+ editSection = container.querySelector(
341
+ ".edit-library-settings"
342
+ ) as HTMLElement;
343
+ expect(settingInput(editSection).value).toBe("new value");
344
+ });
345
+ });
346
+
261
347
  describe("PatronAuthServiceEditForm – save button gating", () => {
262
348
  it("disables the per-library Save button immediately when a new rule is added", async () => {
263
349
  const user = userEvent.setup();
@@ -896,6 +896,27 @@ describe("ServiceEditForm", () => {
896
896
  expect(libraries).toHaveLength(0);
897
897
  });
898
898
 
899
+ it("removes an expanded library and closes its settings", async () => {
900
+ const user = userEvent.setup();
901
+ const { container } = renderForm({ item: serviceData });
902
+ const libraryItem = container.querySelector(
903
+ ".with-remove-button"
904
+ ) as HTMLElement;
905
+
906
+ await user.click(
907
+ libraryItem.querySelector("button.edit-btn") as HTMLElement
908
+ );
909
+ expect(
910
+ container.querySelector(".edit-library-settings")
911
+ ).toBeInTheDocument();
912
+
913
+ await user.click(
914
+ libraryItem.querySelector("button.remove-btn") as HTMLElement
915
+ );
916
+ expect(container.querySelectorAll(".with-remove-button")).toHaveLength(0);
917
+ expect(container.querySelector(".edit-library-settings")).toBeNull();
918
+ });
919
+
899
920
  it("edits a library", async () => {
900
921
  const user = userEvent.setup();
901
922
  const { container } = renderForm({ item: serviceData });
@@ -1059,6 +1080,28 @@ describe("ServiceEditForm", () => {
1059
1080
  expect(nameInput().value).toBe("");
1060
1081
  });
1061
1082
 
1083
+ it("clears every associated library after a successful save (PP-5153)", () => {
1084
+ const threeLibraries = {
1085
+ ...serviceData,
1086
+ libraries: [
1087
+ { short_name: "nypl" },
1088
+ { short_name: "bpl" },
1089
+ { short_name: "qpl" },
1090
+ ],
1091
+ };
1092
+ const { container, rerender } = renderForm({ item: threeLibraries });
1093
+ expect(container.querySelectorAll(".with-remove-button")).toHaveLength(3);
1094
+
1095
+ // clearForm fires onRemove once per library inside one React batch.
1096
+ // Each removal must build on the previous one, otherwise only the last
1097
+ // one survives and the other libraries stay in the list.
1098
+ rerenderForm(rerender, {
1099
+ item: threeLibraries,
1100
+ responseBody: "new service",
1101
+ });
1102
+ expect(container.querySelectorAll(".with-remove-button")).toHaveLength(0);
1103
+ });
1104
+
1062
1105
  it("doesn't clear the form if there's an error message", async () => {
1063
1106
  const user = userEvent.setup();
1064
1107
  const { container, rerender } = renderForm();