@thepalaceproject/circulation-admin 1.43.0-post.2 → 1.43.0-post.20
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/CLAUDE.md +26 -12
- package/README.md +11 -5
- package/dist/circulation-admin.js +1 -1
- package/jest.config.js +17 -18
- package/package.json +4 -22
- package/tests/jest/actions.test.ts +962 -0
- package/tests/jest/components/AccountPage.test.tsx +41 -0
- package/tests/jest/components/AdvancedSearchBooleanFilter.test.tsx +231 -0
- package/tests/jest/components/AdvancedSearchBuilder.test.tsx +93 -20
- package/tests/jest/components/AdvancedSearchFilter.test.tsx +142 -0
- package/tests/jest/components/AdvancedSearchFilterInput.test.tsx +212 -0
- package/tests/jest/components/AdvancedSearchFilterViewer.test.tsx +52 -0
- package/tests/jest/components/AdvancedSearchValueFilter.test.tsx +123 -0
- package/tests/jest/components/Announcement.test.tsx +76 -0
- package/tests/jest/components/AnnouncementForm.test.tsx +229 -0
- package/tests/jest/components/AnnouncementsSection.test.tsx +146 -0
- package/tests/jest/components/Autocomplete.test.tsx +67 -0
- package/tests/jest/components/BookCoverEditor.test.tsx +393 -0
- package/tests/jest/components/BookDetails.test.tsx +133 -0
- package/tests/jest/components/BookDetailsContainer.test.tsx +116 -0
- package/tests/jest/components/BookDetailsEditor.test.tsx +275 -0
- package/tests/jest/components/BookDetailsTabContainer.test.tsx +237 -0
- package/tests/jest/components/BookEditForm.test.tsx +352 -0
- package/tests/jest/components/BookEditor.test.tsx +20 -21
- package/tests/jest/components/CatalogPage.test.tsx +158 -0
- package/tests/jest/components/CatalogServices.test.tsx +100 -0
- package/tests/jest/components/ChangePasswordForm.test.tsx +163 -0
- package/tests/jest/components/CirculationEventsDownloadForm.test.tsx +41 -0
- package/tests/jest/components/Classifications.test.tsx +166 -0
- package/tests/jest/components/ClassificationsForm.test.tsx +458 -0
- package/tests/jest/components/ClassificationsTable.test.tsx +57 -0
- package/tests/jest/components/Collections.test.tsx +335 -7
- package/tests/jest/components/ColorPicker.test.tsx +58 -0
- package/tests/jest/components/ComplaintForm.test.tsx +171 -0
- package/tests/jest/components/Complaints.test.tsx +259 -0
- package/tests/jest/components/ConfigPage.test.tsx +58 -0
- package/tests/jest/components/ConfigTabContainer.test.tsx +196 -0
- package/tests/jest/components/ContextProvider.test.tsx +138 -0
- package/tests/jest/components/Contributors.test.tsx +157 -0
- package/tests/jest/components/CustomListEditor.test.tsx +367 -0
- package/tests/jest/components/CustomListEntriesEditor.test.tsx +1240 -0
- package/tests/jest/components/CustomListPage.test.tsx +57 -0
- package/tests/jest/components/CustomListSearch.test.tsx +275 -0
- package/tests/jest/components/CustomLists.test.tsx +621 -4
- package/tests/jest/components/CustomListsForBook.test.tsx +353 -0
- package/tests/jest/components/CustomListsSidebar.test.tsx +251 -0
- package/tests/jest/components/DashboardPage.test.tsx +76 -0
- package/tests/jest/components/DebugAuthentication.test.tsx +1 -5
- package/tests/jest/components/DiagnosticsServiceTabs.test.tsx +141 -0
- package/tests/jest/components/DiagnosticsServiceType.test.tsx +75 -0
- package/tests/jest/components/DiagnosticsTabContainer.test.tsx +147 -0
- package/tests/jest/components/DiscoveryServices.test.tsx +154 -7
- package/tests/jest/components/EditableConfigList.test.tsx +606 -9
- package/tests/jest/components/EditableInput.test.tsx +250 -1
- package/tests/jest/components/EditorField.test.tsx +95 -0
- package/tests/jest/components/EntryPointsContainer.test.tsx +97 -0
- package/tests/jest/components/EntryPointsTabs.test.tsx +88 -0
- package/tests/jest/components/ErrorMessage.test.tsx +97 -0
- package/tests/jest/components/Footer.test.tsx +141 -0
- package/tests/jest/components/GenreForm.test.tsx +152 -0
- package/tests/jest/components/Header.test.tsx +421 -0
- package/tests/jest/components/IndividualAdminEditForm.test.tsx +506 -1
- package/tests/jest/components/IndividualAdmins.test.tsx +124 -8
- package/tests/jest/components/InputList.test.tsx +493 -0
- package/tests/jest/components/InventoryReportRequestModal.test.tsx +16 -42
- package/tests/jest/components/Lane.test.tsx +132 -10
- package/tests/jest/components/LaneCustomListsEditor.test.tsx +450 -0
- package/tests/jest/components/LaneEditor.test.tsx +377 -13
- package/tests/jest/components/LanePage.test.tsx +68 -0
- package/tests/jest/components/Lanes.test.tsx +446 -0
- package/tests/jest/components/LanesSidebar.test.tsx +621 -0
- package/tests/jest/components/LanguageField.test.tsx +40 -0
- package/tests/jest/components/Libraries.test.tsx +48 -0
- package/tests/jest/components/LibraryEditForm.test.tsx +383 -0
- package/tests/jest/components/LibraryRegistration.test.tsx +354 -0
- package/tests/jest/components/LibraryRegistrationForm.test.tsx +203 -0
- package/tests/jest/components/LoadButton.test.tsx +49 -0
- package/tests/jest/components/ManagePatrons.test.tsx +73 -0
- package/tests/jest/components/ManagePatronsForm.test.tsx +180 -0
- package/tests/jest/components/ManagePatronsTabContainer.test.tsx +143 -0
- package/tests/jest/components/MetadataServices.test.tsx +95 -0
- package/tests/jest/components/NeighborhoodAnalyticsForm.test.tsx +167 -0
- package/tests/jest/components/PairedMenus.test.tsx +220 -0
- package/tests/jest/components/PatronAuthServices.test.tsx +114 -0
- package/tests/jest/components/PatronBlockingRulesEditor.test.tsx +3 -1
- package/tests/jest/components/PatronInfo.test.tsx +54 -0
- package/tests/jest/components/ProtocolFormField.test.tsx +443 -7
- package/tests/jest/components/ResetAdobeId.test.tsx +302 -0
- package/tests/jest/components/SaveButton.test.tsx +47 -0
- package/tests/jest/components/SelfTestResult.test.tsx +164 -0
- package/tests/jest/components/SelfTests.test.tsx +601 -0
- package/tests/jest/components/SelfTestsCategory.test.tsx +200 -0
- package/tests/jest/components/SelfTestsTabContainer.test.tsx +216 -0
- package/tests/jest/components/ServiceEditForm.test.tsx +1092 -0
- package/tests/jest/components/ServiceWithRegistrationsEditForm.test.tsx +110 -0
- package/tests/jest/components/SetupPage.test.tsx +41 -0
- package/tests/jest/components/SingleStatListItem.test.tsx +62 -0
- package/tests/jest/components/SitewideAnnouncements.test.tsx +134 -0
- package/tests/jest/components/Stats.test.tsx +4 -15
- package/tests/jest/components/TabContainer.test.tsx +68 -0
- package/tests/jest/components/TextWithEditMode.test.tsx +218 -0
- package/tests/jest/components/Timestamp.test.tsx +74 -0
- package/tests/jest/components/ToolTip.test.tsx +46 -0
- package/tests/jest/components/TroubleshootingCategoryPage.test.tsx +69 -0
- package/tests/jest/components/TroubleshootingPage.test.tsx +94 -0
- package/tests/jest/components/TroubleshootingTabContainer.test.tsx +68 -0
- package/tests/jest/components/UpdatingLoader.test.tsx +36 -0
- package/tests/jest/components/WelcomePage.test.tsx +43 -0
- package/tests/jest/components/WithEditButton.test.tsx +55 -0
- package/tests/jest/components/WithRemoveButton.test.tsx +95 -0
- package/tests/jest/editorAdapter.test.ts +245 -0
- package/tests/jest/features/book.test.ts +75 -80
- package/tests/jest/fixtures/classificationsData.ts +45 -0
- package/tests/jest/fixtures/genreData.ts +811 -0
- package/tests/jest/index.test.tsx +50 -0
- package/tests/jest/models/Admin.test.ts +206 -0
- package/tests/jest/reducers/bookCoverPreview.test.ts +81 -0
- package/tests/jest/reducers/classifications.test.ts +161 -0
- package/tests/jest/reducers/collections.test.ts +96 -0
- package/tests/jest/reducers/complaints.test.ts +166 -0
- package/tests/jest/reducers/createFetchEditReducer.test.ts +220 -0
- package/tests/jest/reducers/createRegisterLibraryReducer.test.ts +51 -0
- package/tests/jest/reducers/customListDetails.test.ts +120 -0
- package/tests/jest/reducers/customListEditor.test.ts +2823 -0
- package/tests/jest/reducers/managePatrons.test.ts +71 -0
- package/tests/jest/testUtils/formDataShim.test.ts +135 -0
- package/tests/jest/testUtils/formDataShim.ts +112 -0
- package/tests/jest/utils/sharedFunctions.test.ts +121 -0
- package/tsconfig.json +3 -4
- package/.nycrc.json +0 -8
- package/testReporter.js +0 -29
- package/tests/jest/README.md +0 -6
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { screen } from "@testing-library/react";
|
|
3
|
+
|
|
4
|
+
import { renderWithProviders } from "../testUtils/withProviders";
|
|
5
|
+
import buildStore from "../../../src/store";
|
|
6
|
+
|
|
7
|
+
// `SelfTests` is a connected component that fetches self-test results on mount.
|
|
8
|
+
// It is incidental to what `SelfTestsCategory` itself does (build one panel per
|
|
9
|
+
// item, color-code them, decide `openByDefault`, and compute `sortByCollection`),
|
|
10
|
+
// so mock it to a marker that exposes the props the category passes down.
|
|
11
|
+
jest.mock("../../../src/components/SelfTests", () => ({
|
|
12
|
+
__esModule: true,
|
|
13
|
+
default: (props: any) => (
|
|
14
|
+
<div
|
|
15
|
+
data-testid="self-tests"
|
|
16
|
+
data-type={props.type}
|
|
17
|
+
data-item-id={props.item?.id}
|
|
18
|
+
data-item-name={props.item?.name}
|
|
19
|
+
data-sort-by-collection={String(props.sortByCollection)}
|
|
20
|
+
/>
|
|
21
|
+
),
|
|
22
|
+
}));
|
|
23
|
+
|
|
24
|
+
import SelfTestsCategory from "../../../src/components/SelfTestsCategory";
|
|
25
|
+
|
|
26
|
+
const initialSetupResult = {
|
|
27
|
+
duration: 0.000119,
|
|
28
|
+
end: "2018-08-07T19:34:54Z",
|
|
29
|
+
exception: null,
|
|
30
|
+
name: "Initial setup.",
|
|
31
|
+
result: null,
|
|
32
|
+
start: "2018-08-07T19:34:54Z",
|
|
33
|
+
success: true,
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
const collections: any[] = [
|
|
37
|
+
{
|
|
38
|
+
id: 1,
|
|
39
|
+
name: "collection with success",
|
|
40
|
+
protocol: "protocol",
|
|
41
|
+
self_test_results: {
|
|
42
|
+
duration: 1.75,
|
|
43
|
+
start: "2018-08-07T19:34:54Z",
|
|
44
|
+
end: "2018-08-07T19:34:55Z",
|
|
45
|
+
results: [initialSetupResult],
|
|
46
|
+
},
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
id: 2,
|
|
50
|
+
name: "collection with failure",
|
|
51
|
+
protocol: "protocol",
|
|
52
|
+
self_test_results: {
|
|
53
|
+
duration: 1.75,
|
|
54
|
+
start: "2018-08-07T19:34:54Z",
|
|
55
|
+
end: "2018-08-07T19:34:55Z",
|
|
56
|
+
results: [
|
|
57
|
+
initialSetupResult,
|
|
58
|
+
{
|
|
59
|
+
duration: 0,
|
|
60
|
+
end: "2018-08-07T19:34:55Z",
|
|
61
|
+
exception: {
|
|
62
|
+
class: "IntegrationException",
|
|
63
|
+
debug_message:
|
|
64
|
+
"Add the collection to a library that has a patron authentication service.",
|
|
65
|
+
message: "Collection is not associated with any libraries.",
|
|
66
|
+
},
|
|
67
|
+
name: "Acquiring test patron credentials.",
|
|
68
|
+
result: null,
|
|
69
|
+
start: "2018-08-07T19:34:55Z",
|
|
70
|
+
success: false,
|
|
71
|
+
},
|
|
72
|
+
],
|
|
73
|
+
},
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
id: 3,
|
|
77
|
+
name: "collection with no results",
|
|
78
|
+
protocol: "protocol",
|
|
79
|
+
},
|
|
80
|
+
];
|
|
81
|
+
|
|
82
|
+
const renderCategory = (items: any[] = collections) =>
|
|
83
|
+
renderWithProviders(
|
|
84
|
+
<SelfTestsCategory
|
|
85
|
+
type="collection"
|
|
86
|
+
linkName="collections"
|
|
87
|
+
csrfToken="token"
|
|
88
|
+
items={items}
|
|
89
|
+
store={buildStore()}
|
|
90
|
+
/>
|
|
91
|
+
);
|
|
92
|
+
|
|
93
|
+
describe("SelfTestsCategory", () => {
|
|
94
|
+
it("renders a list of items", () => {
|
|
95
|
+
const { container } = renderCategory();
|
|
96
|
+
|
|
97
|
+
const root = container.querySelector(".self-tests-category");
|
|
98
|
+
expect(root).toBeInTheDocument();
|
|
99
|
+
expect(root).toHaveClass("has-additional-content");
|
|
100
|
+
|
|
101
|
+
const titles = Array.from(
|
|
102
|
+
container.querySelectorAll("ul .panel-title")
|
|
103
|
+
).map((el) => el.textContent);
|
|
104
|
+
expect(titles).toStrictEqual([
|
|
105
|
+
"collection with success",
|
|
106
|
+
"collection with failure",
|
|
107
|
+
"collection with no results",
|
|
108
|
+
]);
|
|
109
|
+
|
|
110
|
+
// One SelfTests per item, each carrying the category's type and its item.
|
|
111
|
+
const selfTests = screen.getAllByTestId("self-tests");
|
|
112
|
+
expect(selfTests).toHaveLength(3);
|
|
113
|
+
selfTests.forEach((el, idx) => {
|
|
114
|
+
expect(el).toHaveAttribute("data-type", "collection");
|
|
115
|
+
expect(el).toHaveAttribute("data-item-id", String(collections[idx].id));
|
|
116
|
+
});
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
it("color-codes", () => {
|
|
120
|
+
const { container } = renderCategory();
|
|
121
|
+
const panels = container.querySelectorAll(".panel");
|
|
122
|
+
expect(panels[0]).toHaveClass("panel-success");
|
|
123
|
+
expect(panels[1]).toHaveClass("panel-danger");
|
|
124
|
+
expect(panels[2]).toHaveClass("panel-default");
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
it("opens the panel by default if there's only one", () => {
|
|
128
|
+
// With multiple items, none are open by default.
|
|
129
|
+
const multi = renderCategory();
|
|
130
|
+
expect(
|
|
131
|
+
Array.from(multi.container.querySelectorAll(".panel-heading")).some(
|
|
132
|
+
(h) => h.getAttribute("aria-expanded") === "true"
|
|
133
|
+
)
|
|
134
|
+
).toBe(false);
|
|
135
|
+
multi.unmount();
|
|
136
|
+
|
|
137
|
+
// A fresh render with a single item opens that panel by default.
|
|
138
|
+
// (`openByDefault` seeds the panel's initial state, so a new mount is needed.)
|
|
139
|
+
const single = renderCategory([collections[0]]);
|
|
140
|
+
const singleHeaders = single.container.querySelectorAll(".panel-heading");
|
|
141
|
+
expect(singleHeaders).toHaveLength(1);
|
|
142
|
+
expect(singleHeaders[0]).toHaveAttribute("aria-expanded", "true");
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
it("passes the sortByCollection prop to SelfTests", () => {
|
|
146
|
+
const { rerender } = renderCategory();
|
|
147
|
+
expect(screen.getAllByTestId("self-tests")[0]).toHaveAttribute(
|
|
148
|
+
"data-sort-by-collection",
|
|
149
|
+
"false"
|
|
150
|
+
);
|
|
151
|
+
|
|
152
|
+
const withCollection = {
|
|
153
|
+
id: 99,
|
|
154
|
+
name: "collection with sorting",
|
|
155
|
+
protocol: "protocol",
|
|
156
|
+
self_test_results: {
|
|
157
|
+
duration: 1.75,
|
|
158
|
+
start: "2018-08-07T19:34:54Z",
|
|
159
|
+
end: "2018-08-07T19:34:55Z",
|
|
160
|
+
results: [{ ...initialSetupResult, collection: "sort!" }],
|
|
161
|
+
},
|
|
162
|
+
};
|
|
163
|
+
|
|
164
|
+
rerender(
|
|
165
|
+
<SelfTestsCategory
|
|
166
|
+
type="collection"
|
|
167
|
+
linkName="collections"
|
|
168
|
+
csrfToken="token"
|
|
169
|
+
items={[withCollection, ...collections]}
|
|
170
|
+
store={buildStore()}
|
|
171
|
+
/>
|
|
172
|
+
);
|
|
173
|
+
|
|
174
|
+
expect(screen.getAllByTestId("self-tests")[0]).toHaveAttribute(
|
|
175
|
+
"data-sort-by-collection",
|
|
176
|
+
"true"
|
|
177
|
+
);
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
it("handles unnamed items", () => {
|
|
181
|
+
const nameless: any = {
|
|
182
|
+
id: 1,
|
|
183
|
+
name: null,
|
|
184
|
+
protocol: "protocol",
|
|
185
|
+
self_test_results: {
|
|
186
|
+
duration: 1.75,
|
|
187
|
+
start: "2018-08-07T19:34:54Z",
|
|
188
|
+
end: "2018-08-07T19:34:55Z",
|
|
189
|
+
results: [initialSetupResult],
|
|
190
|
+
},
|
|
191
|
+
};
|
|
192
|
+
const { container } = renderCategory([nameless]);
|
|
193
|
+
|
|
194
|
+
expect(screen.getByText("Unnamed collection")).toHaveClass("panel-title");
|
|
195
|
+
// Panel id becomes `${name-without-spaces}-${id}`; its body id appends "-panel".
|
|
196
|
+
expect(
|
|
197
|
+
container.querySelector("#Unnamedcollection-1-panel")
|
|
198
|
+
).toBeInTheDocument();
|
|
199
|
+
});
|
|
200
|
+
});
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import * as PropTypes from "prop-types";
|
|
3
|
+
import { render, screen, waitFor } from "@testing-library/react";
|
|
4
|
+
import userEvent from "@testing-library/user-event";
|
|
5
|
+
|
|
6
|
+
import buildStore from "../../../src/store";
|
|
7
|
+
|
|
8
|
+
// Each active tab renders the connected SelfTestsCategory, which fetches on mount
|
|
9
|
+
// and recurses into the self-tests machinery. This container's behavior is which
|
|
10
|
+
// slice of the store each category gets and under what type/link name, so mock it
|
|
11
|
+
// to a marker echoing those. `data-items` names the slice's contents so passing
|
|
12
|
+
// the wrong category's items — or the whole items object — is visible.
|
|
13
|
+
jest.mock("../../../src/components/SelfTestsCategory", () => ({
|
|
14
|
+
__esModule: true,
|
|
15
|
+
default: (props: any) => (
|
|
16
|
+
<div
|
|
17
|
+
data-testid="self-tests-category"
|
|
18
|
+
data-type={props.type}
|
|
19
|
+
data-link-name={props.linkName}
|
|
20
|
+
data-items={
|
|
21
|
+
Array.isArray(props.items)
|
|
22
|
+
? props.items.map((item: any) => item.name).join(",")
|
|
23
|
+
: `not-an-array:${typeof props.items}`
|
|
24
|
+
}
|
|
25
|
+
/>
|
|
26
|
+
),
|
|
27
|
+
}));
|
|
28
|
+
|
|
29
|
+
import { SelfTestsTabContainer } from "../../../src/components/SelfTestsTabContainer";
|
|
30
|
+
|
|
31
|
+
// SelfTestsTabContainer reads `router` and `pathFor` from legacy react-router
|
|
32
|
+
// context via static contextTypes (handleSelect calls router.push). Supply them
|
|
33
|
+
// through a tiny legacy-context provider.
|
|
34
|
+
class LegacyContextProvider extends React.Component<{
|
|
35
|
+
router: { push: jest.Mock };
|
|
36
|
+
pathFor: jest.Mock;
|
|
37
|
+
children: React.ReactNode;
|
|
38
|
+
}> {
|
|
39
|
+
static childContextTypes = {
|
|
40
|
+
router: PropTypes.object,
|
|
41
|
+
pathFor: PropTypes.func,
|
|
42
|
+
};
|
|
43
|
+
getChildContext() {
|
|
44
|
+
return { router: this.props.router, pathFor: this.props.pathFor };
|
|
45
|
+
}
|
|
46
|
+
render() {
|
|
47
|
+
return <>{this.props.children}</>;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
describe("SelfTestsTabContainer", () => {
|
|
52
|
+
let goToTab: jest.Mock;
|
|
53
|
+
let fetchItems: jest.Mock;
|
|
54
|
+
let router: { push: jest.Mock };
|
|
55
|
+
let pathFor: jest.Mock;
|
|
56
|
+
let store;
|
|
57
|
+
|
|
58
|
+
const collections = [
|
|
59
|
+
{
|
|
60
|
+
id: 1,
|
|
61
|
+
name: "collection 1",
|
|
62
|
+
protocol: "protocol",
|
|
63
|
+
self_test_results: {
|
|
64
|
+
duration: 1.75,
|
|
65
|
+
start: "2018-08-07T19:34:54Z",
|
|
66
|
+
end: "2018-08-07T19:34:55Z",
|
|
67
|
+
results: [
|
|
68
|
+
{
|
|
69
|
+
duration: 0.000119,
|
|
70
|
+
end: "2018-08-07T19:34:54Z",
|
|
71
|
+
exception: null,
|
|
72
|
+
name: "Initial setup.",
|
|
73
|
+
result: null,
|
|
74
|
+
start: "2018-08-07T19:34:54Z",
|
|
75
|
+
success: true,
|
|
76
|
+
},
|
|
77
|
+
],
|
|
78
|
+
},
|
|
79
|
+
},
|
|
80
|
+
];
|
|
81
|
+
|
|
82
|
+
beforeEach(() => {
|
|
83
|
+
store = buildStore();
|
|
84
|
+
goToTab = jest.fn();
|
|
85
|
+
fetchItems = jest.fn();
|
|
86
|
+
router = { push: jest.fn() };
|
|
87
|
+
pathFor = jest.fn();
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
const element = (overrides = {}) => {
|
|
91
|
+
const props = {
|
|
92
|
+
store,
|
|
93
|
+
goToTab,
|
|
94
|
+
fetchItems,
|
|
95
|
+
tab: "collections",
|
|
96
|
+
items: { protocols: [], collections },
|
|
97
|
+
...overrides,
|
|
98
|
+
};
|
|
99
|
+
return (
|
|
100
|
+
<LegacyContextProvider router={router} pathFor={pathFor}>
|
|
101
|
+
<SelfTestsTabContainer {...props} />
|
|
102
|
+
</LegacyContextProvider>
|
|
103
|
+
);
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
const renderContainer = (overrides = {}) => render(element(overrides));
|
|
107
|
+
|
|
108
|
+
it("renders a tab container", () => {
|
|
109
|
+
const { container } = renderContainer();
|
|
110
|
+
expect(container.firstChild).toHaveClass("tab-container");
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
it("renders tabs and defaults to showing the Collections tab", () => {
|
|
114
|
+
const { container } = renderContainer();
|
|
115
|
+
const tabs = container.querySelectorAll("ul.nav-tabs li");
|
|
116
|
+
expect(tabs).toHaveLength(3);
|
|
117
|
+
|
|
118
|
+
expect(tabs[0]).toHaveTextContent("Collections");
|
|
119
|
+
expect(tabs[0]).toHaveClass("active");
|
|
120
|
+
|
|
121
|
+
expect(tabs[1]).toHaveTextContent("Patron Authentication");
|
|
122
|
+
expect(tabs[1]).not.toHaveClass("active");
|
|
123
|
+
|
|
124
|
+
expect(tabs[2]).toHaveTextContent("Metadata Services");
|
|
125
|
+
expect(tabs[2]).not.toHaveClass("active");
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
it("renders tab content", () => {
|
|
129
|
+
const { container } = renderContainer();
|
|
130
|
+
|
|
131
|
+
// Only the collections data is present, so its category renders; the other
|
|
132
|
+
// two tabs fall back to a loading indicator.
|
|
133
|
+
const markers = screen.getAllByTestId("self-tests-category");
|
|
134
|
+
expect(markers).toHaveLength(1);
|
|
135
|
+
expect(markers[0]).toHaveAttribute("data-type", "collection");
|
|
136
|
+
expect(markers[0]).toHaveAttribute("data-link-name", "collections");
|
|
137
|
+
expect(markers[0]).toHaveAttribute("data-items", "collection 1");
|
|
138
|
+
|
|
139
|
+
expect(container.querySelectorAll(".loading")).toHaveLength(2);
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
it("calls fetchItems on mount", () => {
|
|
143
|
+
renderContainer();
|
|
144
|
+
expect(fetchItems).toHaveBeenCalled();
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
it("shows an error message", () => {
|
|
148
|
+
const { container, rerender } = renderContainer();
|
|
149
|
+
expect(container.querySelectorAll(".alert-danger")).toHaveLength(0);
|
|
150
|
+
|
|
151
|
+
rerender(
|
|
152
|
+
element({
|
|
153
|
+
fetchError: { status: 401, response: "error fetching diagnostics" },
|
|
154
|
+
})
|
|
155
|
+
);
|
|
156
|
+
|
|
157
|
+
expect(container.querySelectorAll(".alert-danger")).toHaveLength(3);
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
it("calls goToTab and pushes to the router when a tab is clicked", async () => {
|
|
161
|
+
renderContainer();
|
|
162
|
+
|
|
163
|
+
await userEvent.click(
|
|
164
|
+
screen.getByRole("link", { name: "Patron Authentication" })
|
|
165
|
+
);
|
|
166
|
+
|
|
167
|
+
expect(goToTab).toHaveBeenCalledTimes(1);
|
|
168
|
+
expect(goToTab).toHaveBeenCalledWith("patronAuthServices");
|
|
169
|
+
await waitFor(() =>
|
|
170
|
+
expect(router.push).toHaveBeenCalledWith(
|
|
171
|
+
"/admin/web/troubleshooting/self-tests/patronAuthServices"
|
|
172
|
+
)
|
|
173
|
+
);
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
it("switches tabs when the tab prop changes", () => {
|
|
177
|
+
const { container, rerender } = renderContainer();
|
|
178
|
+
let tabs = container.querySelectorAll("ul.nav-tabs li");
|
|
179
|
+
expect(tabs[0]).toHaveClass("active");
|
|
180
|
+
expect(tabs[1]).not.toHaveClass("active");
|
|
181
|
+
|
|
182
|
+
rerender(element({ tab: "patronAuthServices" }));
|
|
183
|
+
|
|
184
|
+
tabs = container.querySelectorAll("ul.nav-tabs li");
|
|
185
|
+
expect(tabs[0]).not.toHaveClass("active");
|
|
186
|
+
expect(tabs[1]).toHaveClass("active");
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
it("derives the store key, type, and link name for each category", () => {
|
|
190
|
+
// A category only renders once its store key holds items, so populate all
|
|
191
|
+
// three with distinctly named items: the key each category is looked up
|
|
192
|
+
// under is then observable in the items its marker receives.
|
|
193
|
+
renderContainer({
|
|
194
|
+
items: {
|
|
195
|
+
collections: [{ id: 1, name: "a collection" }],
|
|
196
|
+
patron_auth_services: [{ id: 2, name: "a patron auth service" }],
|
|
197
|
+
metadata_services: [{ id: 3, name: "a metadata service" }],
|
|
198
|
+
},
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
const markers = screen.getAllByTestId("self-tests-category");
|
|
202
|
+
expect(markers).toHaveLength(3);
|
|
203
|
+
|
|
204
|
+
expect(markers[0]).toHaveAttribute("data-type", "collection");
|
|
205
|
+
expect(markers[0]).toHaveAttribute("data-link-name", "collections");
|
|
206
|
+
expect(markers[0]).toHaveAttribute("data-items", "a collection");
|
|
207
|
+
|
|
208
|
+
expect(markers[1]).toHaveAttribute("data-type", "patron_auth_service");
|
|
209
|
+
expect(markers[1]).toHaveAttribute("data-link-name", "patronAuth");
|
|
210
|
+
expect(markers[1]).toHaveAttribute("data-items", "a patron auth service");
|
|
211
|
+
|
|
212
|
+
expect(markers[2]).toHaveAttribute("data-type", "metadata_service");
|
|
213
|
+
expect(markers[2]).toHaveAttribute("data-link-name", "metadata");
|
|
214
|
+
expect(markers[2]).toHaveAttribute("data-items", "a metadata service");
|
|
215
|
+
});
|
|
216
|
+
});
|