feat(web): authorities sort+filter, create external_uri, external_uri in rows, url input (#50)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-08 09:02:13 +02:00
parent 76b2cbde1d
commit 75e7cf9047
3 changed files with 134 additions and 15 deletions
+66
View File
@@ -69,3 +69,69 @@ test("unknown kind redirects to person list", async () => {
renderApp(tree(), { route: "/authorities/banana" });
expect(await screen.findByText("Ada Lovelace")).toBeInTheDocument();
});
test("authorities render sorted by label", async () => {
server.use(
http.get("/api/admin/authorities", () =>
HttpResponse.json([
{ id: "a-zoe", kind: "person", external_uri: null, labels: [{ lang: "en", label: "Zoe" }] },
{ id: "a-adam", kind: "person", external_uri: null, labels: [{ lang: "en", label: "Adam" }] },
]),
),
);
renderApp(tree(), { route: "/authorities/person" });
expect(await screen.findByText("Adam")).toBeInTheDocument();
const items = screen.getAllByRole("listitem");
const texts = items.map((item) => item.textContent ?? "");
const adam = texts.findIndex((text) => text.includes("Adam"));
const zoe = texts.findIndex((text) => text.includes("Zoe"));
expect(adam).toBeLessThan(zoe);
});
test("filter narrows the authority list", async () => {
server.use(
http.get("/api/admin/authorities", () =>
HttpResponse.json([
{ id: "a-ada", kind: "person", external_uri: null, labels: [{ lang: "en", label: "Ada Lovelace" }] },
{ id: "a-grace", kind: "person", external_uri: null, labels: [{ lang: "en", label: "Grace Hopper" }] },
]),
),
);
renderApp(tree(), { route: "/authorities/person" });
expect(await screen.findByText("Ada Lovelace")).toBeInTheDocument();
expect(screen.getByText("Grace Hopper")).toBeInTheDocument();
await userEvent.type(screen.getByRole("textbox", { name: /filter/i }), "grace");
expect(screen.getByText("Grace Hopper")).toBeInTheDocument();
expect(screen.queryByText("Ada Lovelace")).not.toBeInTheDocument();
});
test("create posts the entered external_uri", async () => {
let body: unknown;
server.use(
http.post("/api/admin/authorities", async ({ request }) => {
body = await request.json();
return HttpResponse.json({ id: "a-c" }, { status: 201 });
}),
);
renderApp(tree(), { route: "/authorities/person" });
expect(await screen.findByText("Ada Lovelace")).toBeInTheDocument();
await userEvent.type(screen.getByLabelText(/^label$/i), "Carl von Linné");
await userEvent.type(screen.getByLabelText(/external uri/i), "https://viaf.org/456");
await userEvent.click(screen.getByRole("button", { name: /create/i }));
await waitFor(() =>
expect((body as { external_uri: string })?.external_uri).toBe("https://viaf.org/456"),
);
});
test("read row shows its external_uri as a link", async () => {
server.use(
http.get("/api/admin/authorities", () =>
HttpResponse.json([
{ id: "a-ada", kind: "person", external_uri: "https://viaf.org/123", labels: [{ lang: "en", label: "Ada Lovelace" }] },
]),
),
);
renderApp(tree(), { route: "/authorities/person" });
expect(await screen.findByText("Ada Lovelace")).toBeInTheDocument();
expect(screen.getByRole("link", { name: /viaf\.org/ })).toBeInTheDocument();
});