94 lines
3.5 KiB
TypeScript
94 lines
3.5 KiB
TypeScript
import { expect, test } from "vitest";
|
|
import { screen, waitFor } from "@testing-library/react";
|
|
import userEvent from "@testing-library/user-event";
|
|
import { http, HttpResponse } from "msw";
|
|
import { Route, Routes } from "react-router-dom";
|
|
|
|
import { server } from "../test/server";
|
|
import { renderApp } from "../test/render";
|
|
import { FieldsPage } from "./fields-page";
|
|
|
|
function tree() {
|
|
return (
|
|
<Routes>
|
|
<Route path="/fields" element={<FieldsPage />} />
|
|
</Routes>
|
|
);
|
|
}
|
|
|
|
test("lists field definitions grouped, with an Other heading for ungrouped", async () => {
|
|
renderApp(tree(), { route: "/fields" });
|
|
expect(await screen.findByText("Inscription")).toBeInTheDocument();
|
|
expect(screen.getByText(/^Description$/i)).toBeInTheDocument();
|
|
expect(screen.getByText(/^Other$/i)).toBeInTheDocument();
|
|
});
|
|
|
|
test("creates a text field — posts the body and clears the key input", async () => {
|
|
let body: { key: string; data_type: string } | undefined;
|
|
|
|
server.use(
|
|
http.post("/api/admin/field-definitions", async ({ request }) => {
|
|
body = (await request.json()) as { key: string; data_type: string };
|
|
return HttpResponse.json({ key: "notes" }, { status: 201 });
|
|
}),
|
|
);
|
|
renderApp(tree(), { route: "/fields" });
|
|
|
|
await userEvent.type(screen.getByLabelText(/^key$/i), "notes");
|
|
await userEvent.type(screen.getByLabelText(/label \(en\)/i), "Notes");
|
|
await userEvent.click(screen.getByRole("button", { name: /create field/i }));
|
|
|
|
await waitFor(() => expect(body?.key).toBe("notes"));
|
|
expect(body?.data_type).toBe("text");
|
|
await waitFor(() => expect(screen.getByLabelText(/^key$/i)).toHaveValue(""));
|
|
});
|
|
|
|
test("selecting Authority reveals the kind picker and posts the chosen kind", async () => {
|
|
let body: { authority_kind: string | null } | undefined;
|
|
|
|
server.use(
|
|
http.post("/api/admin/field-definitions", async ({ request }) => {
|
|
body = (await request.json()) as { authority_kind: string | null };
|
|
return HttpResponse.json({ key: "maker" }, { status: 201 });
|
|
}),
|
|
);
|
|
renderApp(tree(), { route: "/fields" });
|
|
|
|
await userEvent.type(screen.getByLabelText(/^key$/i), "maker");
|
|
await userEvent.type(screen.getByLabelText(/label \(en\)/i), "Maker");
|
|
await userEvent.selectOptions(screen.getByLabelText(/^type$/i), "authority");
|
|
const kind = await screen.findByLabelText(/authority kind/i);
|
|
await userEvent.selectOptions(kind, "person");
|
|
await userEvent.click(screen.getByRole("button", { name: /create field/i }));
|
|
|
|
await waitFor(() => expect(body?.authority_kind).toBe("person"));
|
|
});
|
|
|
|
test("selecting Term reveals the vocabulary picker and blocks submit until chosen", async () => {
|
|
let posted = false;
|
|
|
|
server.use(
|
|
http.post("/api/admin/field-definitions", () => {
|
|
posted = true;
|
|
return HttpResponse.json({ key: "x" }, { status: 201 });
|
|
}),
|
|
);
|
|
renderApp(tree(), { route: "/fields" });
|
|
|
|
await userEvent.type(screen.getByLabelText(/^key$/i), "material");
|
|
await userEvent.type(screen.getByLabelText(/label \(en\)/i), "Material");
|
|
await userEvent.selectOptions(screen.getByLabelText(/^type$/i), "term");
|
|
|
|
const vocab = await screen.findByLabelText(/^vocabulary$/i);
|
|
|
|
expect(vocab).toBeInTheDocument();
|
|
|
|
await userEvent.click(screen.getByRole("button", { name: /create field/i }));
|
|
expect(await screen.findByRole("alert")).toBeInTheDocument();
|
|
expect(posted).toBe(false);
|
|
|
|
await userEvent.selectOptions(vocab, "v-material");
|
|
await userEvent.click(screen.getByRole("button", { name: /create field/i }));
|
|
await waitFor(() => expect(posted).toBe(true));
|
|
});
|