@thepalaceproject/circulation-admin 1.43.0 → 1.44.0

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.
Files changed (133) hide show
  1. package/CLAUDE.md +28 -7
  2. package/README.md +11 -5
  3. package/dist/circulation-admin.js +1 -1
  4. package/eslint.config.mjs +9 -1
  5. package/jest.config.js +22 -8
  6. package/package.json +6 -20
  7. package/tests/jest/actions.test.ts +962 -0
  8. package/tests/jest/components/AccountPage.test.tsx +41 -0
  9. package/tests/jest/components/AdvancedSearchBooleanFilter.test.tsx +231 -0
  10. package/tests/jest/components/AdvancedSearchBuilder.test.tsx +93 -20
  11. package/tests/jest/components/AdvancedSearchFilter.test.tsx +142 -0
  12. package/tests/jest/components/AdvancedSearchFilterInput.test.tsx +212 -0
  13. package/tests/jest/components/AdvancedSearchFilterViewer.test.tsx +52 -0
  14. package/tests/jest/components/AdvancedSearchValueFilter.test.tsx +123 -0
  15. package/tests/jest/components/Announcement.test.tsx +76 -0
  16. package/tests/jest/components/AnnouncementForm.test.tsx +229 -0
  17. package/tests/jest/components/AnnouncementsSection.test.tsx +146 -0
  18. package/tests/jest/components/Autocomplete.test.tsx +67 -0
  19. package/tests/jest/components/BookCoverEditor.test.tsx +393 -0
  20. package/tests/jest/components/BookDetails.test.tsx +133 -0
  21. package/tests/jest/components/BookDetailsContainer.test.tsx +116 -0
  22. package/tests/jest/components/BookDetailsEditor.test.tsx +275 -0
  23. package/tests/jest/components/BookDetailsTabContainer.test.tsx +237 -0
  24. package/tests/jest/components/BookEditForm.test.tsx +352 -0
  25. package/tests/jest/components/BookEditor.test.tsx +20 -21
  26. package/tests/jest/components/CatalogPage.test.tsx +158 -0
  27. package/tests/jest/components/CatalogServices.test.tsx +100 -0
  28. package/tests/jest/components/ChangePasswordForm.test.tsx +163 -0
  29. package/tests/jest/components/CirculationEventsDownloadForm.test.tsx +41 -0
  30. package/tests/jest/components/Classifications.test.tsx +166 -0
  31. package/tests/jest/components/ClassificationsForm.test.tsx +458 -0
  32. package/tests/jest/components/ClassificationsTable.test.tsx +57 -0
  33. package/tests/jest/components/Collections.test.tsx +335 -7
  34. package/tests/jest/components/ColorPicker.test.tsx +58 -0
  35. package/tests/jest/components/ComplaintForm.test.tsx +171 -0
  36. package/tests/jest/components/Complaints.test.tsx +259 -0
  37. package/tests/jest/components/ConfigPage.test.tsx +58 -0
  38. package/tests/jest/components/ConfigTabContainer.test.tsx +196 -0
  39. package/tests/jest/components/ContextProvider.test.tsx +138 -0
  40. package/tests/jest/components/Contributors.test.tsx +157 -0
  41. package/tests/jest/components/CustomListEditor.test.tsx +367 -0
  42. package/tests/jest/components/CustomListEntriesEditor.test.tsx +1240 -0
  43. package/tests/jest/components/CustomListPage.test.tsx +57 -0
  44. package/tests/jest/components/CustomListSearch.test.tsx +275 -0
  45. package/tests/jest/components/CustomLists.test.tsx +621 -4
  46. package/tests/jest/components/CustomListsForBook.test.tsx +353 -0
  47. package/tests/jest/components/CustomListsSidebar.test.tsx +251 -0
  48. package/tests/jest/components/DashboardPage.test.tsx +76 -0
  49. package/tests/jest/components/DebugAuthentication.test.tsx +1 -5
  50. package/tests/jest/components/DiagnosticsServiceTabs.test.tsx +141 -0
  51. package/tests/jest/components/DiagnosticsServiceType.test.tsx +75 -0
  52. package/tests/jest/components/DiagnosticsTabContainer.test.tsx +147 -0
  53. package/tests/jest/components/DiscoveryServices.test.tsx +154 -7
  54. package/tests/jest/components/EditableConfigList.test.tsx +606 -9
  55. package/tests/jest/components/EditableInput.test.tsx +250 -1
  56. package/tests/jest/components/EditorField.test.tsx +95 -0
  57. package/tests/jest/components/EntryPointsContainer.test.tsx +97 -0
  58. package/tests/jest/components/EntryPointsTabs.test.tsx +88 -0
  59. package/tests/jest/components/ErrorMessage.test.tsx +97 -0
  60. package/tests/jest/components/Footer.test.tsx +141 -0
  61. package/tests/jest/components/GenreForm.test.tsx +152 -0
  62. package/tests/jest/components/Header.test.tsx +421 -0
  63. package/tests/jest/components/IndividualAdminEditForm.test.tsx +506 -1
  64. package/tests/jest/components/IndividualAdmins.test.tsx +124 -8
  65. package/tests/jest/components/InputList.test.tsx +493 -0
  66. package/tests/jest/components/InventoryReportRequestModal.test.tsx +16 -42
  67. package/tests/jest/components/JsonField.test.tsx +20 -0
  68. package/tests/jest/components/Lane.test.tsx +132 -10
  69. package/tests/jest/components/LaneCustomListsEditor.test.tsx +450 -0
  70. package/tests/jest/components/LaneEditor.test.tsx +377 -13
  71. package/tests/jest/components/LanePage.test.tsx +68 -0
  72. package/tests/jest/components/Lanes.test.tsx +446 -0
  73. package/tests/jest/components/LanesSidebar.test.tsx +621 -0
  74. package/tests/jest/components/LanguageField.test.tsx +40 -0
  75. package/tests/jest/components/Libraries.test.tsx +48 -0
  76. package/tests/jest/components/LibraryEditForm.test.tsx +383 -0
  77. package/tests/jest/components/LibraryRegistration.test.tsx +354 -0
  78. package/tests/jest/components/LibraryRegistrationForm.test.tsx +203 -0
  79. package/tests/jest/components/LoadButton.test.tsx +49 -0
  80. package/tests/jest/components/ManagePatrons.test.tsx +73 -0
  81. package/tests/jest/components/ManagePatronsForm.test.tsx +180 -0
  82. package/tests/jest/components/ManagePatronsTabContainer.test.tsx +143 -0
  83. package/tests/jest/components/MetadataServices.test.tsx +95 -0
  84. package/tests/jest/components/NeighborhoodAnalyticsForm.test.tsx +167 -0
  85. package/tests/jest/components/PairedMenus.test.tsx +220 -0
  86. package/tests/jest/components/PatronAuthServices.test.tsx +114 -0
  87. package/tests/jest/components/PatronBlockingRulesEditor.test.tsx +3 -1
  88. package/tests/jest/components/PatronInfo.test.tsx +54 -0
  89. package/tests/jest/components/ProtocolFormField.test.tsx +479 -7
  90. package/tests/jest/components/ResetAdobeId.test.tsx +302 -0
  91. package/tests/jest/components/SaveButton.test.tsx +47 -0
  92. package/tests/jest/components/SelfTestResult.test.tsx +164 -0
  93. package/tests/jest/components/SelfTests.test.tsx +601 -0
  94. package/tests/jest/components/SelfTestsCategory.test.tsx +200 -0
  95. package/tests/jest/components/SelfTestsTabContainer.test.tsx +216 -0
  96. package/tests/jest/components/ServiceEditForm.test.tsx +1092 -0
  97. package/tests/jest/components/ServiceWithRegistrationsEditForm.test.tsx +110 -0
  98. package/tests/jest/components/SetupPage.test.tsx +41 -0
  99. package/tests/jest/components/SingleStatListItem.test.tsx +62 -0
  100. package/tests/jest/components/SitewideAnnouncements.test.tsx +134 -0
  101. package/tests/jest/components/Stats.test.tsx +4 -15
  102. package/tests/jest/components/TabContainer.test.tsx +68 -0
  103. package/tests/jest/components/TextWithEditMode.test.tsx +218 -0
  104. package/tests/jest/components/Timestamp.test.tsx +74 -0
  105. package/tests/jest/components/ToolTip.test.tsx +46 -0
  106. package/tests/jest/components/TroubleshootingCategoryPage.test.tsx +69 -0
  107. package/tests/jest/components/TroubleshootingPage.test.tsx +94 -0
  108. package/tests/jest/components/TroubleshootingTabContainer.test.tsx +68 -0
  109. package/tests/jest/components/UpdatingLoader.test.tsx +36 -0
  110. package/tests/jest/components/WelcomePage.test.tsx +43 -0
  111. package/tests/jest/components/WithEditButton.test.tsx +55 -0
  112. package/tests/jest/components/WithRemoveButton.test.tsx +95 -0
  113. package/tests/jest/editorAdapter.test.ts +245 -0
  114. package/tests/jest/features/book.test.ts +75 -80
  115. package/tests/jest/fixtures/classificationsData.ts +45 -0
  116. package/tests/jest/fixtures/genreData.ts +811 -0
  117. package/tests/jest/index.test.tsx +50 -0
  118. package/tests/jest/models/Admin.test.ts +206 -0
  119. package/tests/jest/reducers/bookCoverPreview.test.ts +81 -0
  120. package/tests/jest/reducers/classifications.test.ts +161 -0
  121. package/tests/jest/reducers/collections.test.ts +96 -0
  122. package/tests/jest/reducers/complaints.test.ts +166 -0
  123. package/tests/jest/reducers/createFetchEditReducer.test.ts +220 -0
  124. package/tests/jest/reducers/createRegisterLibraryReducer.test.ts +51 -0
  125. package/tests/jest/reducers/customListDetails.test.ts +120 -0
  126. package/tests/jest/reducers/customListEditor.test.ts +2823 -0
  127. package/tests/jest/reducers/managePatrons.test.ts +71 -0
  128. package/tests/jest/testUtils/formDataShim.test.ts +135 -0
  129. package/tests/jest/testUtils/formDataShim.ts +112 -0
  130. package/tests/jest/utils/sharedFunctions.test.ts +121 -0
  131. package/tsconfig.json +3 -4
  132. package/testReporter.js +0 -29
  133. package/tests/jest/README.md +0 -6
@@ -0,0 +1,245 @@
1
+ import adapter from "../../src/editorAdapter";
2
+ import {
3
+ OPDSEntry,
4
+ Contributor,
5
+ Series,
6
+ Category,
7
+ Summary,
8
+ } from "opds-feed-parser";
9
+
10
+ describe("editorAdapter", () => {
11
+ it("adapts valid OPDS entry", () => {
12
+ const entry = new OPDSEntry({
13
+ id: "id",
14
+ updated: "updated",
15
+ title: "title",
16
+ authors: [new Contributor({ name: "name", uri: "uri", role: "role" })],
17
+ subtitle: "subtitle",
18
+ contributors: [
19
+ new Contributor({ name: "name2", uri: "uri2", role: "role2" }),
20
+ ],
21
+ series: new Series({ name: "series", position: 2 }),
22
+ categories: [
23
+ new Category({ term: "term", scheme: "scheme", label: "label" }),
24
+ new Category({
25
+ term: "13-16",
26
+ scheme: "http://schema.org/typicalAgeRange",
27
+ label: "age",
28
+ }),
29
+ new Category({
30
+ term: "ya",
31
+ scheme: "http://schema.org/audience",
32
+ label: "ya",
33
+ }),
34
+ new Category({
35
+ term: "fiction",
36
+ scheme: "http://librarysimplified.org/terms/fiction/",
37
+ label: "Fiction",
38
+ }),
39
+ ],
40
+ identifiers: [],
41
+ links: [
42
+ {
43
+ href: "hide",
44
+ rel: "http://librarysimplified.org/terms/rel/hide",
45
+ type: "type",
46
+ title: "title",
47
+ role: "role",
48
+ },
49
+ {
50
+ href: "restore",
51
+ rel: "http://librarysimplified.org/terms/rel/restore",
52
+ type: "type",
53
+ title: "title",
54
+ role: "role",
55
+ },
56
+ {
57
+ href: "refresh",
58
+ rel: "http://librarysimplified.org/terms/rel/refresh",
59
+ type: "type",
60
+ title: "title",
61
+ role: "role",
62
+ },
63
+ {
64
+ href: "edit",
65
+ rel: "edit",
66
+ type: "type",
67
+ title: "title",
68
+ role: "role",
69
+ },
70
+ {
71
+ href: "issues",
72
+ rel: "issues",
73
+ type: "type",
74
+ title: "title",
75
+ role: "role",
76
+ },
77
+ {
78
+ href: "change-cover",
79
+ rel: "http://librarysimplified.org/terms/rel/change_cover",
80
+ type: "type",
81
+ title: "title",
82
+ role: "role",
83
+ },
84
+ {
85
+ href: "cover",
86
+ rel: "http://opds-spec.org/image",
87
+ type: "image/png",
88
+ title: "title",
89
+ role: "role",
90
+ },
91
+ ],
92
+ issued: "issued",
93
+ language: "language",
94
+ rights: "rights",
95
+ publisher: "publisher",
96
+ published: "published",
97
+ summary: new Summary({ content: "content", link: "link" }),
98
+ unparsed: {
99
+ "schema:alternativeHeadline": [{ _: "subtitle" }],
100
+ $: {
101
+ "schema:additionalType": { value: "medium" },
102
+ },
103
+ "bib:publisherImprint": [{ _: "imprint" }],
104
+ "schema:Rating": [
105
+ {
106
+ $: {
107
+ "schema:ratingValue": { value: "0.3" },
108
+ "schema:additionalType": {
109
+ value: "http://librarysimplified.org/terms/rel/quality",
110
+ },
111
+ },
112
+ },
113
+ {
114
+ $: {
115
+ "schema:ratingValue": { value: "4" },
116
+ "schema:additionalType": {
117
+ value: "http://schema.org/ratingValue",
118
+ },
119
+ },
120
+ },
121
+ ],
122
+ },
123
+ });
124
+
125
+ const adapted = adapter(entry);
126
+ expect(adapted.title).toBe("title");
127
+ expect(adapted.authors).toStrictEqual([
128
+ { name: "name", uri: "uri", role: "aut" },
129
+ ]);
130
+ // The adapter flattens `Contributor` instances into plain objects, so assert
131
+ // the shape it produces rather than comparing against `entry.contributors`.
132
+ expect(adapted.contributors).toStrictEqual([
133
+ { name: "name2", uri: "uri2", role: "role2" },
134
+ ]);
135
+ expect(adapted.subtitle).toBe("subtitle");
136
+ expect(adapted.summary).toBe("content");
137
+ expect(adapted.audience).toBe("ya");
138
+ expect(adapted.targetAgeRange).toStrictEqual(["13", "16"]);
139
+ expect(adapted.fiction).toBe(true);
140
+ expect(adapted.categories).toStrictEqual(["label", "age", "ya", "Fiction"]);
141
+ expect(adapted.hideLink).toStrictEqual(entry.links[0]);
142
+ expect(adapted.restoreLink).toStrictEqual(entry.links[1]);
143
+ expect(adapted.refreshLink).toStrictEqual(entry.links[2]);
144
+ expect(adapted.editLink).toStrictEqual(entry.links[3]);
145
+ expect(adapted.issuesLink).toStrictEqual(entry.links[4]);
146
+ expect(adapted.changeCoverLink).toStrictEqual(entry.links[5]);
147
+ expect(adapted.coverUrl).toBe(entry.links[6].href);
148
+ expect(adapted.series).toBe("series");
149
+ expect(adapted.seriesPosition).toBe(2);
150
+ expect(adapted.medium).toBe("medium");
151
+ expect(adapted.language).toBe("language");
152
+ expect(adapted.publisher).toBe("publisher");
153
+ expect(adapted.imprint).toBe("imprint");
154
+ expect(adapted.issued).toBe("issued");
155
+ expect(adapted.rating).toBe("4");
156
+ });
157
+
158
+ it("adapts visibility status from categories", () => {
159
+ const entry = new OPDSEntry({
160
+ id: "id",
161
+ updated: "updated",
162
+ title: "title",
163
+ subtitle: "subtitle",
164
+ authors: [],
165
+ contributors: [],
166
+ series: new Series({ name: "series", position: 2 }),
167
+ categories: [
168
+ new Category({ term: "term", scheme: "scheme", label: "label" }),
169
+ new Category({
170
+ term: "manually-suppressed",
171
+ scheme: "http://palaceproject.io/terms/visibility-status",
172
+ label: "Manually Suppressed",
173
+ }),
174
+ ],
175
+ identifiers: [],
176
+ links: [],
177
+ issued: "issued",
178
+ language: "language",
179
+ rights: "rights",
180
+ publisher: "publisher",
181
+ published: "published",
182
+ summary: new Summary({ content: "content", link: "link" }),
183
+ unparsed: {},
184
+ });
185
+
186
+ const adapted = adapter(entry);
187
+ expect(adapted.visibilityStatus).toBe("manually-suppressed");
188
+ });
189
+
190
+ it("adapts policy-filtered visibility status", () => {
191
+ const entry = new OPDSEntry({
192
+ id: "id",
193
+ updated: "updated",
194
+ title: "title",
195
+ subtitle: "subtitle",
196
+ authors: [],
197
+ contributors: [],
198
+ series: new Series({ name: "series", position: 2 }),
199
+ categories: [
200
+ new Category({
201
+ term: "policy-filtered",
202
+ scheme: "http://palaceproject.io/terms/visibility-status",
203
+ label: "Policy Filtered",
204
+ }),
205
+ ],
206
+ identifiers: [],
207
+ links: [],
208
+ issued: "issued",
209
+ language: "language",
210
+ rights: "rights",
211
+ publisher: "publisher",
212
+ published: "published",
213
+ summary: new Summary({ content: "content", link: "link" }),
214
+ unparsed: {},
215
+ });
216
+
217
+ const adapted = adapter(entry);
218
+ expect(adapted.visibilityStatus).toBe("policy-filtered");
219
+ });
220
+
221
+ it("doesn't crash when expected data is missing", () => {
222
+ const entry = new OPDSEntry({
223
+ id: "id",
224
+ updated: "updated",
225
+ title: "title",
226
+ subtitle: "subtitle",
227
+ authors: [],
228
+ contributors: [],
229
+ series: new Series({ name: "series", position: 2 }),
230
+ categories: [],
231
+ identifiers: [],
232
+ links: [],
233
+ issued: "issued",
234
+ language: "language",
235
+ rights: "rights",
236
+ publisher: "publisher",
237
+ published: "published",
238
+ summary: new Summary({ content: "content", link: "link" }),
239
+ unparsed: {},
240
+ });
241
+
242
+ const adapted = adapter(entry);
243
+ expect(adapted.title).toBe("title");
244
+ });
245
+ });
@@ -3,7 +3,6 @@ import reducer, {
3
3
  getBookData,
4
4
  submitBookData,
5
5
  } from "../../../src/features/book/bookEditorSlice";
6
- import { expect } from "chai";
7
6
  import * as fetchMock from "fetch-mock-jest";
8
7
  import { BookData } from "@thepalaceproject/web-opds-client/lib/interfaces";
9
8
  import { RequestError } from "@thepalaceproject/web-opds-client/lib/DataFetcher";
@@ -57,12 +56,12 @@ describe("Redux bookEditorSlice...", () => {
57
56
 
58
57
  describe("reducers...", () => {
59
58
  it("should return the initial state from undefined, if no action is passed", () => {
60
- expect(reducer(undefined, { type: "unknown" })).to.deep.equal(
59
+ expect(reducer(undefined, { type: "unknown" })).toStrictEqual(
61
60
  initialState
62
61
  );
63
62
  });
64
63
  it("should return the initial state from initialState, if no action is passed", () => {
65
- expect(reducer(initialState, { type: "unknown" })).to.deep.equal(
64
+ expect(reducer(initialState, { type: "unknown" })).toStrictEqual(
66
65
  initialState
67
66
  );
68
67
  });
@@ -70,7 +69,7 @@ describe("Redux bookEditorSlice...", () => {
70
69
  // This is dispatched by `web-opds`client`, but we need to handle it, too.
71
70
  const action = { type: ActionCreator.BOOK_CLEAR };
72
71
 
73
- expect(reducer(fetchedState, action)).to.deep.equal(initialState);
72
+ expect(reducer(fetchedState, action)).toStrictEqual(initialState);
74
73
  });
75
74
 
76
75
  it("should handle getBookData.pending", () => {
@@ -81,11 +80,11 @@ describe("Redux bookEditorSlice...", () => {
81
80
  const previousState = { ...initialState, url: null, isFetching: false };
82
81
  const state = reducer(previousState, action);
83
82
 
84
- expect(state.url).to.equal("https://example.com/book");
85
- expect(state.data).to.be.null;
86
- expect(state.isFetching).to.equal(true);
87
- expect(state.fetchError).to.be.null;
88
- expect(state.editError).to.be.null;
83
+ expect(state.url).toBe("https://example.com/book");
84
+ expect(state.data).toBeNull();
85
+ expect(state.isFetching).toBe(true);
86
+ expect(state.fetchError).toBeNull();
87
+ expect(state.editError).toBeNull();
89
88
  });
90
89
  it("should handle getBookData.fulfilled", () => {
91
90
  const action = {
@@ -101,11 +100,11 @@ describe("Redux bookEditorSlice...", () => {
101
100
  };
102
101
  const state = reducer(previousState, action);
103
102
 
104
- expect(state.url).to.equal("https://example.com/book");
105
- expect(state.data).to.deep.equal(bookData);
106
- expect(state.isFetching).to.equal(false);
107
- expect(state.fetchError).to.be.null;
108
- expect(state.editError).to.be.null;
103
+ expect(state.url).toBe("https://example.com/book");
104
+ expect(state.data).toStrictEqual(bookData);
105
+ expect(state.isFetching).toBe(false);
106
+ expect(state.fetchError).toBeNull();
107
+ expect(state.editError).toBeNull();
109
108
  });
110
109
  it("should handle getBookData.rejected", () => {
111
110
  const errorObject = { error: "some error object" };
@@ -122,11 +121,11 @@ describe("Redux bookEditorSlice...", () => {
122
121
  };
123
122
  const state = reducer(previousState, action);
124
123
 
125
- expect(state.url).to.equal("https://example.com/book");
126
- expect(state.data).to.be.null;
127
- expect(state.isFetching).to.equal(false);
128
- expect(state.fetchError).to.deep.equal(errorObject);
129
- expect(state.editError).to.be.null;
124
+ expect(state.url).toBe("https://example.com/book");
125
+ expect(state.data).toBeNull();
126
+ expect(state.isFetching).toBe(false);
127
+ expect(state.fetchError).toStrictEqual(errorObject);
128
+ expect(state.editError).toBeNull();
130
129
  });
131
130
 
132
131
  it("should handle submitBookData.pending", () => {
@@ -134,7 +133,7 @@ describe("Redux bookEditorSlice...", () => {
134
133
  const previousState = { ...fetchedState, isFetching: false };
135
134
  const state = reducer(previousState, action);
136
135
 
137
- expect(state).to.deep.equal({ ...fetchedState, isFetching: true });
136
+ expect(state).toStrictEqual({ ...fetchedState, isFetching: true });
138
137
  });
139
138
  it("should handle submitBookData.fulfilled", () => {
140
139
  const action = {
@@ -144,7 +143,7 @@ describe("Redux bookEditorSlice...", () => {
144
143
  const previousState = { ...fetchedState, isFetching: true };
145
144
  const state = reducer(previousState, action);
146
145
 
147
- expect(state).to.deep.equal({
146
+ expect(state).toStrictEqual({
148
147
  ...fetchedState,
149
148
  isFetching: false,
150
149
  editError: null,
@@ -158,7 +157,7 @@ describe("Redux bookEditorSlice...", () => {
158
157
  const previousState = { ...fetchedState, isFetching: true };
159
158
  const state = reducer(previousState, action);
160
159
 
161
- expect(state).to.deep.equal({
160
+ expect(state).toStrictEqual({
162
161
  ...fetchedState,
163
162
  isFetching: false,
164
163
  editError: "some value",
@@ -200,22 +199,22 @@ describe("Redux bookEditorSlice...", () => {
200
199
  const dispatchCalls = dispatch.mock.calls;
201
200
 
202
201
  const payload = result.payload as BookData;
203
- expect(payload.id).to.equal(
202
+ expect(payload.id).toBe(
204
203
  "urn:uuid:1cca9468-c447-4303-bc5a-c57470b85cb1"
205
204
  );
206
- expect(payload.title).to.equal(
205
+ expect(payload.title).toBe(
207
206
  "Tea-Cup Reading and Fortune-Telling by Tea Leaves"
208
207
  );
209
208
 
210
- expect(dispatchCalls.length).to.equal(2);
211
- expect(dispatchCalls[0][0].type).to.equal(getBookData.pending.type);
212
- expect(dispatchCalls[0][0].payload).to.equal(undefined);
213
- expect(dispatchCalls[0][0].meta.arg).to.deep.equal({
209
+ expect(dispatchCalls.length).toBe(2);
210
+ expect(dispatchCalls[0][0].type).toBe(getBookData.pending.type);
211
+ expect(dispatchCalls[0][0].payload).toBe(undefined);
212
+ expect(dispatchCalls[0][0].meta.arg).toStrictEqual({
214
213
  url: goodBookUrl,
215
214
  });
216
- expect(dispatchCalls[1][0].type).to.equal(getBookData.fulfilled.type);
217
- expect(dispatchCalls[1][0].payload).to.deep.equal(payload);
218
- expect(dispatchCalls[1][0].meta.arg).to.deep.equal({
215
+ expect(dispatchCalls[1][0].type).toBe(getBookData.fulfilled.type);
216
+ expect(dispatchCalls[1][0].payload).toStrictEqual(payload);
217
+ expect(dispatchCalls[1][0].meta.arg).toStrictEqual({
219
218
  url: goodBookUrl,
220
219
  });
221
220
  });
@@ -226,18 +225,18 @@ describe("Redux bookEditorSlice...", () => {
226
225
  const dispatchCalls = dispatch.mock.calls;
227
226
 
228
227
  const payload = result.payload as RequestError;
229
- expect(payload.response).to.equal(FETCH_OPDS_PARSE_ERROR_MESSAGE);
230
- expect(payload.url).to.equal(brokenBookUrl);
228
+ expect(payload.response).toBe(FETCH_OPDS_PARSE_ERROR_MESSAGE);
229
+ expect(payload.url).toBe(brokenBookUrl);
231
230
 
232
- expect(dispatchCalls.length).to.equal(2);
233
- expect(dispatchCalls[0][0].type).to.equal(getBookData.pending.type);
234
- expect(dispatchCalls[0][0].payload).to.equal(undefined);
235
- expect(dispatchCalls[0][0].meta.arg).to.deep.equal({
231
+ expect(dispatchCalls.length).toBe(2);
232
+ expect(dispatchCalls[0][0].type).toBe(getBookData.pending.type);
233
+ expect(dispatchCalls[0][0].payload).toBe(undefined);
234
+ expect(dispatchCalls[0][0].meta.arg).toStrictEqual({
236
235
  url: brokenBookUrl,
237
236
  });
238
- expect(dispatchCalls[1][0].type).to.equal(getBookData.rejected.type);
239
- expect(dispatchCalls[1][0].payload).to.deep.equal(payload);
240
- expect(dispatchCalls[1][0].meta.arg).to.deep.equal({
237
+ expect(dispatchCalls[1][0].type).toBe(getBookData.rejected.type);
238
+ expect(dispatchCalls[1][0].payload).toStrictEqual(payload);
239
+ expect(dispatchCalls[1][0].meta.arg).toStrictEqual({
241
240
  url: brokenBookUrl,
242
241
  });
243
242
  });
@@ -249,20 +248,20 @@ describe("Redux bookEditorSlice...", () => {
249
248
 
250
249
  const payload = result.payload as RequestError;
251
250
 
252
- expect(result.type).to.equal(getBookData.rejected.type);
253
- expect(result.meta.arg).to.deep.equal({ url: errorBookUrl });
254
- expect(payload.response).to.equal("Internal server error");
255
- expect(payload.url).to.equal(errorBookUrl);
251
+ expect(result.type).toBe(getBookData.rejected.type);
252
+ expect(result.meta.arg).toStrictEqual({ url: errorBookUrl });
253
+ expect(payload.response).toBe("Internal server error");
254
+ expect(payload.url).toBe(errorBookUrl);
256
255
 
257
- expect(dispatchCalls.length).to.equal(2);
258
- expect(dispatchCalls[0][0].type).to.equal(getBookData.pending.type);
259
- expect(dispatchCalls[0][0].payload).to.equal(undefined);
260
- expect(dispatchCalls[0][0].meta.arg).to.deep.equal({
256
+ expect(dispatchCalls.length).toBe(2);
257
+ expect(dispatchCalls[0][0].type).toBe(getBookData.pending.type);
258
+ expect(dispatchCalls[0][0].payload).toBe(undefined);
259
+ expect(dispatchCalls[0][0].meta.arg).toStrictEqual({
261
260
  url: errorBookUrl,
262
261
  });
263
- expect(dispatchCalls[1][0].type).to.equal(getBookData.rejected.type);
264
- expect(dispatchCalls[1][0].payload).to.deep.equal(payload);
265
- expect(dispatchCalls[1][0].meta.arg).to.deep.equal({
262
+ expect(dispatchCalls[1][0].type).toBe(getBookData.rejected.type);
263
+ expect(dispatchCalls[1][0].payload).toStrictEqual(payload);
264
+ expect(dispatchCalls[1][0].meta.arg).toStrictEqual({
266
265
  url: errorBookUrl,
267
266
  });
268
267
  });
@@ -327,27 +326,23 @@ describe("Redux bookEditorSlice...", () => {
327
326
  const dispatchCalls = dispatch.mock.calls;
328
327
  const fetchCalls = fetchMock.calls();
329
328
 
330
- expect(fetchCalls.length).to.equal(1);
331
- expect(fetchCalls[0].identifier).to.equal("valid-csrf-token-post");
332
- expect(
333
- (fetchCalls[0][1].headers as Headers).get(csrfTokenHeader)
334
- ).to.equal(validCsrfToken);
329
+ expect(fetchCalls.length).toBe(1);
330
+ expect(fetchCalls[0].identifier).toBe("valid-csrf-token-post");
331
+ expect((fetchCalls[0][1].headers as Headers).get(csrfTokenHeader)).toBe(
332
+ validCsrfToken
333
+ );
335
334
 
336
- expect(fetchCalls[0][0]).to.equal(editBookUrl);
337
- expect(fetchCalls[0][1].method).to.equal("POST");
338
- expect(fetchCalls[0][1].body).to.equal(formData);
335
+ expect(fetchCalls[0][0]).toBe(editBookUrl);
336
+ expect(fetchCalls[0][1].method).toBe("POST");
337
+ expect(fetchCalls[0][1].body).toBe(formData);
339
338
 
340
- expect(dispatchCalls.length).to.equal(3);
341
- expect(dispatchCalls[0][0].type).to.equal(submitBookData.pending.type);
342
- expect(dispatchCalls[0][0].payload).to.equal(undefined);
339
+ expect(dispatchCalls.length).toBe(3);
340
+ expect(dispatchCalls[0][0].type).toBe(submitBookData.pending.type);
341
+ expect(dispatchCalls[0][0].payload).toBe(undefined);
343
342
  // On a successful update, the second dispatch is to re-fetch the updated book data.
344
343
  // The third dispatch is for the fulfilled action.
345
- expect(dispatchCalls[2][0].type).to.equal(
346
- submitBookData.fulfilled.type
347
- );
348
- expect(dispatchCalls[2][0].payload.body.toString()).to.equal(
349
- "Success!"
350
- );
344
+ expect(dispatchCalls[2][0].type).toBe(submitBookData.fulfilled.type);
345
+ expect(dispatchCalls[2][0].payload.body.toString()).toBe("Success!");
351
346
  });
352
347
  it("should fail, if the user is unauthorized", async () => {
353
348
  const csrfToken = "invalid-token";
@@ -365,24 +360,24 @@ describe("Redux bookEditorSlice...", () => {
365
360
  const dispatchCalls = dispatch.mock.calls;
366
361
  const fetchCalls = fetchMock.calls();
367
362
 
368
- expect(fetchCalls.length).to.equal(1);
369
- expect(fetchCalls[0].identifier).to.equal("invalid-csrf-token-post");
363
+ expect(fetchCalls.length).toBe(1);
364
+ expect(fetchCalls[0].identifier).toBe("invalid-csrf-token-post");
370
365
  expect(
371
366
  (fetchCalls[0][1].headers as Headers).get(csrfTokenHeader)
372
- ).not.to.equal(validCsrfToken);
367
+ ).not.toBe(validCsrfToken);
373
368
 
374
- expect(fetchCalls[0][0]).to.equal(editBookUrl);
375
- expect(fetchCalls[0][1].method).to.equal("POST");
376
- expect(fetchCalls[0][1].body).to.equal(formData);
369
+ expect(fetchCalls[0][0]).toBe(editBookUrl);
370
+ expect(fetchCalls[0][1].method).toBe("POST");
371
+ expect(fetchCalls[0][1].body).toBe(formData);
377
372
 
378
- expect(dispatchCalls.length).to.equal(2);
379
- expect(dispatchCalls[0][0].type).to.equal(submitBookData.pending.type);
380
- expect(dispatchCalls[0][0].payload).to.equal(undefined);
373
+ expect(dispatchCalls.length).toBe(2);
374
+ expect(dispatchCalls[0][0].type).toBe(submitBookData.pending.type);
375
+ expect(dispatchCalls[0][0].payload).toBe(undefined);
381
376
  // There is no re-fetch on a failed request, ...
382
377
  // ...so the second dispatch is for the rejected action.
383
- expect(dispatchCalls[1][0].type).to.equal(submitBookData.rejected.type);
384
- expect(dispatchCalls[1][0].payload.status).to.equal(400);
385
- expect(dispatchCalls[1][0].payload.response).to.equal(
378
+ expect(dispatchCalls[1][0].type).toBe(submitBookData.rejected.type);
379
+ expect(dispatchCalls[1][0].payload.status).toBe(400);
380
+ expect(dispatchCalls[1][0].payload.response).toBe(
386
381
  "There was an error saving your changes."
387
382
  );
388
383
  });
@@ -0,0 +1,45 @@
1
+ // prettier-ignore
2
+ export default [
3
+ {
4
+ "name": "Fiction",
5
+ "source": "Library staff",
6
+ "type": "http://librarysimplified.org/terms/fiction/",
7
+ "weight": 10000000
8
+ },
9
+ {
10
+ "name": "Horror",
11
+ "source": "Library staff",
12
+ "type": "http://librarysimplified.org/terms/genres/Simplified/",
13
+ "weight": 100000
14
+ },
15
+ {
16
+ "name": "Adult",
17
+ "source": "Library staff",
18
+ "type": "schema:audience",
19
+ "weight": 100000
20
+ },
21
+ {
22
+ "name": "FICTION / Ghost",
23
+ "source": "Axis 360",
24
+ "type": "BISAC",
25
+ "weight": 1
26
+ },
27
+ {
28
+ "name": "FICTION / Horror",
29
+ "source": "Axis 360",
30
+ "type": "BISAC",
31
+ "weight": 1
32
+ },
33
+ {
34
+ "name": "General Adult",
35
+ "source": "Axis 360",
36
+ "type": "Axis 360 Audience",
37
+ "weight": 1
38
+ },
39
+ {
40
+ "name": "FICTION / Anthologies (multiple authors)",
41
+ "source": "Axis 360",
42
+ "type": "BISAC",
43
+ "weight": 1
44
+ },
45
+ ];