@thepalaceproject/circulation-admin 1.43.0-post.15 → 1.43.0-post.16
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 +1 -1
- package/tests/jest/components/AnnouncementForm.test.tsx +229 -0
- package/tests/jest/components/AnnouncementsSection.test.tsx +146 -0
- package/tests/jest/components/ChangePasswordForm.test.tsx +163 -0
- package/tests/jest/components/DiscoveryServices.test.tsx +154 -7
- package/tests/jest/components/EditableInput.test.tsx +250 -1
- 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/LibraryRegistration.test.tsx +354 -0
- package/tests/jest/components/NeighborhoodAnalyticsForm.test.tsx +167 -0
- package/tests/jest/components/TextWithEditMode.test.tsx +218 -0
- package/tests/jest/components/ToolTip.test.tsx +46 -0
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { render, screen, act } from "@testing-library/react";
|
|
3
|
+
import userEvent from "@testing-library/user-event";
|
|
4
|
+
import TextWithEditMode from "../../../src/components/TextWithEditMode";
|
|
5
|
+
|
|
6
|
+
describe("TextWithEditMode", () => {
|
|
7
|
+
it("renders text", () => {
|
|
8
|
+
const { rerender } = render(
|
|
9
|
+
<TextWithEditMode
|
|
10
|
+
text="test"
|
|
11
|
+
placeholder="editable thing"
|
|
12
|
+
aria-label="label"
|
|
13
|
+
/>
|
|
14
|
+
);
|
|
15
|
+
expect(screen.getByText("test")).toBeInTheDocument();
|
|
16
|
+
expect(
|
|
17
|
+
screen.getByRole("button", { name: /Edit editable thing/ })
|
|
18
|
+
).toBeInTheDocument();
|
|
19
|
+
|
|
20
|
+
rerender(
|
|
21
|
+
<TextWithEditMode
|
|
22
|
+
text="other text"
|
|
23
|
+
placeholder="editable thing"
|
|
24
|
+
aria-label="label"
|
|
25
|
+
/>
|
|
26
|
+
);
|
|
27
|
+
expect(screen.queryByText("test")).not.toBeInTheDocument();
|
|
28
|
+
expect(screen.getByText("other text")).toBeInTheDocument();
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
it("starts in edit mode if there's no text", () => {
|
|
32
|
+
render(
|
|
33
|
+
<TextWithEditMode placeholder="editable thing" aria-label="label" />
|
|
34
|
+
);
|
|
35
|
+
const input = screen.getByRole("textbox");
|
|
36
|
+
expect(input).toHaveAttribute("placeholder", "editable thing");
|
|
37
|
+
expect(input).toHaveValue("");
|
|
38
|
+
expect(
|
|
39
|
+
screen.getByRole("button", { name: /Save editable thing/ })
|
|
40
|
+
).toBeInTheDocument();
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
it("switches to edit mode", async () => {
|
|
44
|
+
const user = userEvent.setup();
|
|
45
|
+
render(
|
|
46
|
+
<TextWithEditMode
|
|
47
|
+
text="test"
|
|
48
|
+
placeholder="editable thing"
|
|
49
|
+
aria-label="label"
|
|
50
|
+
/>
|
|
51
|
+
);
|
|
52
|
+
expect(screen.queryByRole("textbox")).not.toBeInTheDocument();
|
|
53
|
+
|
|
54
|
+
await user.click(
|
|
55
|
+
screen.getByRole("button", { name: /Edit editable thing/ })
|
|
56
|
+
);
|
|
57
|
+
|
|
58
|
+
const input = screen.getByRole("textbox");
|
|
59
|
+
expect(input).toHaveAttribute("placeholder", "editable thing");
|
|
60
|
+
expect(input).toHaveValue("test");
|
|
61
|
+
expect(screen.getByRole("button", { name: /Save/ })).toBeInTheDocument();
|
|
62
|
+
expect(
|
|
63
|
+
screen.queryByRole("button", { name: /Edit/ })
|
|
64
|
+
).not.toBeInTheDocument();
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
it("switches out of edit mode", async () => {
|
|
68
|
+
const user = userEvent.setup();
|
|
69
|
+
const onUpdate = jest.fn();
|
|
70
|
+
render(
|
|
71
|
+
<TextWithEditMode
|
|
72
|
+
placeholder="editable thing"
|
|
73
|
+
onUpdate={onUpdate}
|
|
74
|
+
aria-label="label"
|
|
75
|
+
/>
|
|
76
|
+
);
|
|
77
|
+
// Type the new value into the field; the component reads the real input
|
|
78
|
+
// value back through its ref on save (no prototype stubbing).
|
|
79
|
+
await user.type(screen.getByRole("textbox"), "new value");
|
|
80
|
+
await user.click(
|
|
81
|
+
screen.getByRole("button", { name: /Save editable thing/ })
|
|
82
|
+
);
|
|
83
|
+
|
|
84
|
+
expect(screen.queryByRole("textbox")).not.toBeInTheDocument();
|
|
85
|
+
expect(onUpdate).toHaveBeenCalledTimes(1);
|
|
86
|
+
expect(onUpdate).toHaveBeenCalledWith("new value");
|
|
87
|
+
expect(screen.getByText("new value")).toBeInTheDocument();
|
|
88
|
+
expect(screen.getByRole("button", { name: /Edit/ })).toBeInTheDocument();
|
|
89
|
+
expect(
|
|
90
|
+
screen.queryByRole("button", { name: /Save/ })
|
|
91
|
+
).not.toBeInTheDocument();
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
it("gets text via the ref API", async () => {
|
|
95
|
+
const user = userEvent.setup();
|
|
96
|
+
// In display mode, getText() returns the current text.
|
|
97
|
+
const displayRef = React.createRef<TextWithEditMode>();
|
|
98
|
+
const { unmount } = render(
|
|
99
|
+
<TextWithEditMode
|
|
100
|
+
text="test"
|
|
101
|
+
placeholder="editable thing"
|
|
102
|
+
aria-label="label"
|
|
103
|
+
ref={displayRef}
|
|
104
|
+
/>
|
|
105
|
+
);
|
|
106
|
+
expect(displayRef.current!.getText()).toBe("test");
|
|
107
|
+
unmount();
|
|
108
|
+
|
|
109
|
+
// From edit mode, getText() returns the current input value and exits edit mode.
|
|
110
|
+
const editRef = React.createRef<TextWithEditMode>();
|
|
111
|
+
render(
|
|
112
|
+
<TextWithEditMode
|
|
113
|
+
placeholder="editable thing"
|
|
114
|
+
aria-label="label"
|
|
115
|
+
ref={editRef}
|
|
116
|
+
/>
|
|
117
|
+
);
|
|
118
|
+
await user.type(screen.getByRole("textbox"), "new value");
|
|
119
|
+
let value = "";
|
|
120
|
+
act(() => {
|
|
121
|
+
value = editRef.current!.getText();
|
|
122
|
+
});
|
|
123
|
+
expect(value).toBe("new value");
|
|
124
|
+
expect(screen.queryByRole("textbox")).not.toBeInTheDocument();
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
it("resets via the ref API", async () => {
|
|
128
|
+
const user = userEvent.setup();
|
|
129
|
+
const onUpdate = jest.fn();
|
|
130
|
+
|
|
131
|
+
// With no text prop, reset() returns to a blank edit mode.
|
|
132
|
+
const blankRef = React.createRef<TextWithEditMode>();
|
|
133
|
+
const { unmount } = render(
|
|
134
|
+
<TextWithEditMode
|
|
135
|
+
placeholder="editable thing"
|
|
136
|
+
onUpdate={onUpdate}
|
|
137
|
+
aria-label="label"
|
|
138
|
+
ref={blankRef}
|
|
139
|
+
/>
|
|
140
|
+
);
|
|
141
|
+
await user.type(screen.getByRole("textbox"), "new value");
|
|
142
|
+
await user.click(
|
|
143
|
+
screen.getByRole("button", { name: /Save editable thing/ })
|
|
144
|
+
);
|
|
145
|
+
expect(screen.getByText("new value")).toBeInTheDocument();
|
|
146
|
+
expect(onUpdate).toHaveBeenCalledTimes(1);
|
|
147
|
+
|
|
148
|
+
act(() => {
|
|
149
|
+
blankRef.current!.reset();
|
|
150
|
+
});
|
|
151
|
+
expect(screen.queryByText("new value")).not.toBeInTheDocument();
|
|
152
|
+
expect(screen.getByRole("textbox")).toBeInTheDocument();
|
|
153
|
+
expect(onUpdate).toHaveBeenCalledTimes(2);
|
|
154
|
+
expect(onUpdate.mock.calls[1][0]).toBeUndefined();
|
|
155
|
+
unmount();
|
|
156
|
+
|
|
157
|
+
// With a text prop, reset() returns to displaying that text.
|
|
158
|
+
const textRef = React.createRef<TextWithEditMode>();
|
|
159
|
+
render(
|
|
160
|
+
<TextWithEditMode
|
|
161
|
+
text="test"
|
|
162
|
+
placeholder="editable thing"
|
|
163
|
+
onUpdate={onUpdate}
|
|
164
|
+
aria-label="label"
|
|
165
|
+
ref={textRef}
|
|
166
|
+
/>
|
|
167
|
+
);
|
|
168
|
+
await user.click(
|
|
169
|
+
screen.getByRole("button", { name: /Edit editable thing/ })
|
|
170
|
+
);
|
|
171
|
+
const input = screen.getByRole("textbox");
|
|
172
|
+
await user.clear(input);
|
|
173
|
+
await user.type(input, "new value");
|
|
174
|
+
await user.click(
|
|
175
|
+
screen.getByRole("button", { name: /Save editable thing/ })
|
|
176
|
+
);
|
|
177
|
+
expect(screen.queryByText("test")).not.toBeInTheDocument();
|
|
178
|
+
expect(screen.getByText("new value")).toBeInTheDocument();
|
|
179
|
+
expect(onUpdate).toHaveBeenCalledTimes(3);
|
|
180
|
+
|
|
181
|
+
act(() => {
|
|
182
|
+
textRef.current!.reset();
|
|
183
|
+
});
|
|
184
|
+
expect(screen.queryByText("new value")).not.toBeInTheDocument();
|
|
185
|
+
expect(screen.getByText("test")).toBeInTheDocument();
|
|
186
|
+
expect(onUpdate).toHaveBeenCalledTimes(4);
|
|
187
|
+
expect(onUpdate.mock.calls[3][0]).toBe("test");
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
it("optionally disables the save button if the text is blank", async () => {
|
|
191
|
+
const user = userEvent.setup();
|
|
192
|
+
render(
|
|
193
|
+
<TextWithEditMode
|
|
194
|
+
placeholder="editable thing"
|
|
195
|
+
aria-label="label"
|
|
196
|
+
disableIfBlank
|
|
197
|
+
/>
|
|
198
|
+
);
|
|
199
|
+
const saveButton = screen.getByRole("button", {
|
|
200
|
+
name: /Save editable thing/,
|
|
201
|
+
});
|
|
202
|
+
expect(saveButton).toBeDisabled();
|
|
203
|
+
|
|
204
|
+
await user.type(screen.getByRole("textbox"), "test");
|
|
205
|
+
expect(saveButton).toBeEnabled();
|
|
206
|
+
});
|
|
207
|
+
|
|
208
|
+
it("updates the displayed value as the user types", async () => {
|
|
209
|
+
const user = userEvent.setup();
|
|
210
|
+
render(
|
|
211
|
+
<TextWithEditMode placeholder="editable thing" aria-label="label" />
|
|
212
|
+
);
|
|
213
|
+
const input = screen.getByRole("textbox");
|
|
214
|
+
expect(input).toHaveValue("");
|
|
215
|
+
await user.type(input, "test");
|
|
216
|
+
expect(input).toHaveValue("test");
|
|
217
|
+
});
|
|
218
|
+
});
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { render, screen } from "@testing-library/react";
|
|
3
|
+
import userEvent from "@testing-library/user-event";
|
|
4
|
+
import ToolTip from "../../../src/components/ToolTip";
|
|
5
|
+
|
|
6
|
+
describe("ToolTip", () => {
|
|
7
|
+
const renderToolTip = () =>
|
|
8
|
+
render(<ToolTip trigger={<h1>Hover</h1>} text="ToolTip Content" />);
|
|
9
|
+
|
|
10
|
+
it("renders the trigger element", () => {
|
|
11
|
+
renderToolTip();
|
|
12
|
+
expect(screen.getByRole("heading", { name: "Hover" })).toBeInTheDocument();
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
it("renders the tooltip", () => {
|
|
16
|
+
const { container } = renderToolTip();
|
|
17
|
+
const tooltip = container.querySelector<HTMLElement>(".tool-tip")!;
|
|
18
|
+
expect(tooltip).toBeInTheDocument();
|
|
19
|
+
expect(tooltip).toHaveTextContent("ToolTip Content");
|
|
20
|
+
expect(tooltip.innerHTML).toContain("ToolTip Content");
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
it("initially hides the tooltip", () => {
|
|
24
|
+
const { container } = renderToolTip();
|
|
25
|
+
expect(container.querySelector(".tool-tip")).toHaveClass("hide");
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
it("shows the tooltip on mouseEnter", async () => {
|
|
29
|
+
const user = userEvent.setup();
|
|
30
|
+
const { container } = renderToolTip();
|
|
31
|
+
await user.hover(screen.getByRole("tooltip"));
|
|
32
|
+
expect(container.querySelector(".tool-tip")).not.toHaveClass("hide");
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
it("hides the tooltip on mouseLeave", async () => {
|
|
36
|
+
const user = userEvent.setup();
|
|
37
|
+
const { container } = renderToolTip();
|
|
38
|
+
const toolTipContainer = screen.getByRole("tooltip");
|
|
39
|
+
|
|
40
|
+
await user.hover(toolTipContainer);
|
|
41
|
+
expect(container.querySelector(".tool-tip")).not.toHaveClass("hide");
|
|
42
|
+
|
|
43
|
+
await user.unhover(toolTipContainer);
|
|
44
|
+
expect(container.querySelector(".tool-tip")).toHaveClass("hide");
|
|
45
|
+
});
|
|
46
|
+
});
|