Skip to content

Commit c774eba

Browse files
committed
Add new tests
1 parent f3f7578 commit c774eba

3 files changed

Lines changed: 934 additions & 0 deletions

File tree

Lines changed: 376 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,376 @@
1+
import * as React from "react";
2+
import { fireEvent } from "@testing-library/react";
3+
import { DiscoveryServices } from "../../../src/components/DiscoveryServices";
4+
import renderWithContext from "../testUtils/renderWithContext";
5+
import {
6+
ConfigurationSettings,
7+
DiscoveryServicesData,
8+
} from "../../../src/interfaces";
9+
import { defaultFeatureFlags } from "../../../src/utils/featureFlags";
10+
11+
// NB: This adds tests to the already existing tests in:
12+
// - `src/components/__tests__/DiscoveryServices-test.tsx`.
13+
//
14+
// Those tests should eventually be migrated here and
15+
// adapted to the Jest/React Testing Library paradigm.
16+
17+
describe("DiscoveryServices - registered library disclosure", () => {
18+
// ── Shared fixtures ───────────────────────────────────────────────────────
19+
20+
const allLibraries = [
21+
{ short_name: "gamma", name: "Gamma Library", uuid: "uuid-gamma" },
22+
{ short_name: "alpha", name: "Alpha Library", uuid: "uuid-alpha" },
23+
{ short_name: "beta", name: "Beta Library", uuid: "uuid-beta" },
24+
{ short_name: "delta", name: "Delta Library" }, // no uuid
25+
];
26+
27+
const sysAdminConfig: Partial<ConfigurationSettings> = {
28+
csrfToken: "",
29+
featureFlags: defaultFeatureFlags,
30+
roles: [{ role: "system" }],
31+
};
32+
33+
const renderServices = (data: Partial<DiscoveryServicesData>) =>
34+
renderWithContext(
35+
<DiscoveryServices
36+
data={
37+
{
38+
discovery_services: [],
39+
allLibraries,
40+
...data,
41+
} as DiscoveryServicesData
42+
}
43+
fetchData={jest.fn()}
44+
editItem={jest.fn().mockResolvedValue(undefined)}
45+
deleteItem={jest.fn().mockResolvedValue(undefined)}
46+
registerLibrary={jest.fn().mockResolvedValue(undefined)}
47+
fetchLibraryRegistrations={jest.fn().mockResolvedValue(undefined)}
48+
csrfToken="token"
49+
isFetching={false}
50+
/>,
51+
sysAdminConfig
52+
);
53+
54+
// ── Toggle visibility ─────────────────────────────────────────────────────
55+
56+
it("shows no toggle when libraryRegistrations data has not yet loaded", () => {
57+
const { container } = renderServices({
58+
discovery_services: [{ id: 1, protocol: "p", name: "Service A" } as any],
59+
// libraryRegistrations omitted → undefined
60+
});
61+
expect(container.querySelector(".library-toggle")).toBeNull();
62+
expect(container.querySelector(".library-count")).toBeNull();
63+
});
64+
65+
it("shows a disabled toggle and 'no registered libraries' when none are registered", () => {
66+
const { container } = renderServices({
67+
discovery_services: [{ id: 1, protocol: "p", name: "Service A" } as any],
68+
libraryRegistrations: [
69+
{
70+
id: 1,
71+
libraries: [
72+
{
73+
short_name: "alpha",
74+
status: "warning",
75+
} as any,
76+
{
77+
short_name: "beta",
78+
status: "failure",
79+
} as any,
80+
],
81+
},
82+
],
83+
});
84+
const toggle = container.querySelector<HTMLButtonElement>(
85+
".library-toggle"
86+
);
87+
expect(toggle).not.toBeNull();
88+
expect(toggle.disabled).toBe(true);
89+
expect(container.querySelector(".library-count").textContent).toBe(
90+
" (no registered libraries)"
91+
);
92+
});
93+
94+
it("shows '1 registered library' when exactly one library is registered", () => {
95+
const { container } = renderServices({
96+
discovery_services: [{ id: 1, protocol: "p", name: "Service A" } as any],
97+
libraryRegistrations: [
98+
{
99+
id: 1,
100+
libraries: [
101+
{
102+
short_name: "alpha",
103+
status: "success",
104+
stage: "production",
105+
} as any,
106+
],
107+
},
108+
],
109+
});
110+
const toggle = container.querySelector<HTMLButtonElement>(
111+
".library-toggle"
112+
);
113+
expect(toggle.disabled).toBe(false);
114+
expect(container.querySelector(".library-count").textContent).toBe(
115+
" (1 registered library)"
116+
);
117+
});
118+
119+
it("shows 'N registered libraries' when multiple are registered", () => {
120+
const { container } = renderServices({
121+
discovery_services: [{ id: 1, protocol: "p", name: "Service A" } as any],
122+
libraryRegistrations: [
123+
{
124+
id: 1,
125+
libraries: [
126+
{
127+
short_name: "alpha",
128+
status: "success",
129+
stage: "production",
130+
} as any,
131+
{ short_name: "beta", status: "success", stage: "testing" } as any,
132+
{ short_name: "gamma", status: "warning" } as any,
133+
],
134+
},
135+
],
136+
});
137+
expect(container.querySelector(".library-count").textContent).toBe(
138+
" (2 registered libraries)"
139+
);
140+
});
141+
142+
// ── Content filtering ─────────────────────────────────────────────────────
143+
144+
it("shows only registered (status=success) libraries in the expanded list", () => {
145+
const { container } = renderServices({
146+
discovery_services: [{ id: 1, protocol: "p", name: "Service A" } as any],
147+
libraryRegistrations: [
148+
{
149+
id: 1,
150+
libraries: [
151+
{
152+
short_name: "alpha",
153+
status: "success",
154+
stage: "production",
155+
} as any,
156+
{ short_name: "beta", status: "warning", stage: "testing" } as any,
157+
{ short_name: "gamma", status: "failure" } as any,
158+
],
159+
},
160+
],
161+
});
162+
fireEvent.click(container.querySelector(".library-toggle"));
163+
164+
const items = container.querySelectorAll(".associated-libraries li");
165+
expect(items).toHaveLength(1);
166+
expect(items[0].textContent).toContain("Alpha Library");
167+
});
168+
169+
// ── Stage suffix ──────────────────────────────────────────────────────────
170+
171+
it("shows the registration stage in the suffix", () => {
172+
const { container } = renderServices({
173+
discovery_services: [{ id: 1, protocol: "p", name: "Service A" } as any],
174+
libraryRegistrations: [
175+
{
176+
id: 1,
177+
libraries: [
178+
{
179+
short_name: "alpha",
180+
status: "success",
181+
stage: "production",
182+
} as any,
183+
],
184+
},
185+
],
186+
});
187+
fireEvent.click(container.querySelector(".library-toggle"));
188+
189+
const item = container.querySelector(".associated-libraries li");
190+
expect(item.textContent).toBe("Alpha Library - registered - production");
191+
});
192+
193+
it("shows '- registered' without a stage when stage is absent", () => {
194+
const { container } = renderServices({
195+
discovery_services: [{ id: 1, protocol: "p", name: "Service A" } as any],
196+
libraryRegistrations: [
197+
{
198+
id: 1,
199+
libraries: [{ short_name: "alpha", status: "success" } as any],
200+
},
201+
],
202+
});
203+
fireEvent.click(container.querySelector(".library-toggle"));
204+
205+
const item = container.querySelector(".associated-libraries li");
206+
expect(item.textContent).toBe("Alpha Library - registered");
207+
});
208+
209+
// ── Sorting ───────────────────────────────────────────────────────────────
210+
211+
it("sorts registered libraries alphabetically by display name", () => {
212+
const { container } = renderServices({
213+
discovery_services: [{ id: 1, protocol: "p", name: "Service A" } as any],
214+
libraryRegistrations: [
215+
{
216+
id: 1,
217+
libraries: [
218+
{
219+
short_name: "gamma",
220+
status: "success",
221+
stage: "production",
222+
} as any,
223+
{ short_name: "alpha", status: "success", stage: "testing" } as any,
224+
{
225+
short_name: "beta",
226+
status: "success",
227+
stage: "production",
228+
} as any,
229+
],
230+
},
231+
],
232+
});
233+
fireEvent.click(container.querySelector(".library-toggle"));
234+
235+
const items = container.querySelectorAll(".associated-libraries li");
236+
expect(items[0].textContent).toContain("Alpha Library");
237+
expect(items[1].textContent).toContain("Beta Library");
238+
expect(items[2].textContent).toContain("Gamma Library");
239+
});
240+
241+
// ── Links ─────────────────────────────────────────────────────────────────
242+
243+
it("links the library name to its config page when a uuid is available", () => {
244+
const { container } = renderServices({
245+
discovery_services: [{ id: 1, protocol: "p", name: "Service A" } as any],
246+
libraryRegistrations: [
247+
{
248+
id: 1,
249+
libraries: [
250+
{
251+
short_name: "alpha",
252+
status: "success",
253+
stage: "production",
254+
} as any,
255+
],
256+
},
257+
],
258+
});
259+
fireEvent.click(container.querySelector(".library-toggle"));
260+
261+
const link = container.querySelector<HTMLAnchorElement>(
262+
".associated-libraries a"
263+
);
264+
expect(link).not.toBeNull();
265+
expect(link.textContent).toBe("Alpha Library");
266+
expect(link.href).toContain("/admin/web/config/libraries/edit/uuid-alpha");
267+
// The suffix should not be inside the link.
268+
expect(link.nextSibling.textContent).toBe(" - registered - production");
269+
});
270+
271+
it("renders the library name as plain text when no uuid is available", () => {
272+
const { container } = renderServices({
273+
discovery_services: [{ id: 1, protocol: "p", name: "Service A" } as any],
274+
libraryRegistrations: [
275+
{
276+
id: 1,
277+
libraries: [
278+
{ short_name: "delta", status: "success", stage: "testing" } as any,
279+
],
280+
},
281+
],
282+
});
283+
fireEvent.click(container.querySelector(".library-toggle"));
284+
285+
expect(container.querySelector(".associated-libraries a")).toBeNull();
286+
expect(
287+
container.querySelector(".associated-libraries li").textContent
288+
).toBe("Delta Library - registered - testing");
289+
});
290+
291+
// ── Per-service isolation ─────────────────────────────────────────────────
292+
293+
it("shows each service's own registered libraries independently", () => {
294+
const { container } = renderServices({
295+
discovery_services: [
296+
{ id: 1, protocol: "p", name: "Service A" } as any,
297+
{ id: 2, protocol: "p", name: "Service B" } as any,
298+
],
299+
libraryRegistrations: [
300+
{
301+
id: 1,
302+
libraries: [
303+
{
304+
short_name: "alpha",
305+
status: "success",
306+
stage: "production",
307+
} as any,
308+
],
309+
},
310+
{
311+
id: 2,
312+
libraries: [
313+
{ short_name: "beta", status: "success", stage: "testing" } as any,
314+
{
315+
short_name: "gamma",
316+
status: "success",
317+
stage: "production",
318+
} as any,
319+
],
320+
},
321+
],
322+
});
323+
324+
expect(container.querySelector(".library-count").textContent).toBe(
325+
" (1 registered library)"
326+
);
327+
328+
const toggles = container.querySelectorAll<HTMLButtonElement>(
329+
".library-toggle"
330+
);
331+
expect(toggles).toHaveLength(2);
332+
expect(
333+
toggles[1].closest("li").querySelector(".library-count").textContent
334+
).toBe(" (2 registered libraries)");
335+
});
336+
337+
// ── Alt+click toggle-all ──────────────────────────────────────────────────
338+
339+
it("alt+click expands all services that have registered libraries", () => {
340+
const { container } = renderServices({
341+
discovery_services: [
342+
{ id: 1, protocol: "p", name: "Service A" } as any,
343+
{ id: 2, protocol: "p", name: "Service B" } as any,
344+
{ id: 3, protocol: "p", name: "Service C" } as any,
345+
],
346+
libraryRegistrations: [
347+
{
348+
id: 1,
349+
libraries: [
350+
{
351+
short_name: "alpha",
352+
status: "success",
353+
stage: "production",
354+
} as any,
355+
],
356+
},
357+
{
358+
id: 2,
359+
libraries: [], // no registrations → disabled toggle
360+
},
361+
{
362+
id: 3,
363+
libraries: [
364+
{ short_name: "beta", status: "success", stage: "testing" } as any,
365+
],
366+
},
367+
],
368+
});
369+
370+
const toggles = container.querySelectorAll(".library-toggle");
371+
fireEvent.click(toggles[0], { altKey: true });
372+
373+
// Services 1 and 3 have registered libraries; service 2 has none.
374+
expect(container.querySelectorAll(".associated-libraries")).toHaveLength(2);
375+
});
376+
});

0 commit comments

Comments
 (0)