test(web): cover prune-fields, labels, format-date, delete-in-use dialog (#67)
This commit is contained in:
@@ -0,0 +1,35 @@
|
||||
import { expect, test, vi } from "vitest";
|
||||
import { screen, waitFor, within } from "@testing-library/react";
|
||||
import userEvent from "@testing-library/user-event";
|
||||
|
||||
import { renderApp } from "../test/render";
|
||||
import { DeleteConfirmDialog } from "./delete-confirm-dialog";
|
||||
import { InUseError } from "../api/errors";
|
||||
|
||||
test("delete-in-use shows the in-use count and keeps the dialog open", async () => {
|
||||
const onConfirm = vi.fn(() => Promise.reject(new InUseError(3)));
|
||||
renderApp(<DeleteConfirmDialog description="Delete this term?" onConfirm={onConfirm} />);
|
||||
|
||||
await userEvent.click(screen.getByRole("button", { name: /delete/i }));
|
||||
|
||||
const dialog = within(document.body);
|
||||
const buttons = await dialog.findAllByRole("button", { name: /delete/i });
|
||||
await userEvent.click(buttons[buttons.length - 1]);
|
||||
|
||||
expect(await dialog.findByText(/used by 3/i)).toBeInTheDocument();
|
||||
expect(dialog.getByText("Delete this term?")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test("a clean confirm closes the dialog", async () => {
|
||||
const onConfirm = vi.fn(() => Promise.resolve());
|
||||
renderApp(<DeleteConfirmDialog description="Delete this term?" onConfirm={onConfirm} />);
|
||||
|
||||
await userEvent.click(screen.getByRole("button", { name: /delete/i }));
|
||||
|
||||
const dialog = within(document.body);
|
||||
const buttons = await dialog.findAllByRole("button", { name: /delete/i });
|
||||
await userEvent.click(buttons[buttons.length - 1]);
|
||||
|
||||
await waitFor(() => expect(dialog.queryByText("Delete this term?")).toBeNull());
|
||||
expect(onConfirm).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
@@ -0,0 +1,19 @@
|
||||
import { expect, test } from "vitest";
|
||||
|
||||
import { formatDate } from "./format-date";
|
||||
|
||||
test("formats a date-only string in the locale without a timezone day-shift", () => {
|
||||
expect(formatDate("1962-04-03", "en")).toBe("Apr 3, 1962");
|
||||
});
|
||||
|
||||
test("returns the em-dash placeholder for null", () => {
|
||||
expect(formatDate(null, "en")).toBe("—");
|
||||
});
|
||||
|
||||
test("returns an unparseable string unchanged", () => {
|
||||
expect(formatDate("not-a-date", "en")).toBe("not-a-date");
|
||||
});
|
||||
|
||||
test("stringifies a non-string, non-null value", () => {
|
||||
expect(formatDate(42, "en")).toBe("42");
|
||||
});
|
||||
@@ -0,0 +1,24 @@
|
||||
import { expect, test } from "vitest";
|
||||
|
||||
import { labelText } from "./labels";
|
||||
|
||||
const labels = [
|
||||
{ lang: "en", label: "Bowl" },
|
||||
{ lang: "sv", label: "Skål" },
|
||||
];
|
||||
|
||||
test("returns the exact-language label when present", () => {
|
||||
expect(labelText(labels, "sv")).toBe("Skål");
|
||||
});
|
||||
|
||||
test("falls back to the English label when the requested language is missing", () => {
|
||||
expect(labelText(labels, "de")).toBe("Bowl");
|
||||
});
|
||||
|
||||
test("falls back to the first label when neither the language nor English is present", () => {
|
||||
expect(labelText([{ lang: "fr", label: "Bol" }], "de")).toBe("Bol");
|
||||
});
|
||||
|
||||
test("returns an empty string for no labels", () => {
|
||||
expect(labelText([], "en")).toBe("");
|
||||
});
|
||||
@@ -0,0 +1,39 @@
|
||||
import { expect, test } from "vitest";
|
||||
|
||||
import { pruneFields } from "./prune-fields";
|
||||
|
||||
test("drops empty/null/undefined scalars, keeps real scalars", () => {
|
||||
const out = pruneFields(
|
||||
{ a: "x", b: "", c: null, d: undefined, e: 0, f: false },
|
||||
new Set(),
|
||||
"en",
|
||||
);
|
||||
expect(out).toEqual({ a: "x", e: 0, f: false });
|
||||
});
|
||||
|
||||
test("a localized_text key keeps only the default-language entry", () => {
|
||||
const out = pruneFields(
|
||||
{ title: { en: "Bowl", sv: "Skål" } },
|
||||
new Set(["title"]),
|
||||
"sv",
|
||||
);
|
||||
expect(out).toEqual({ title: { sv: "Skål" } });
|
||||
});
|
||||
|
||||
test("a non-localized object value keeps all non-empty entries", () => {
|
||||
const out = pruneFields(
|
||||
{ dims: { w: "10", h: "", d: "5" } },
|
||||
new Set(),
|
||||
"en",
|
||||
);
|
||||
expect(out).toEqual({ dims: { w: "10", d: "5" } });
|
||||
});
|
||||
|
||||
test("an object value left with no entries is dropped entirely", () => {
|
||||
const out = pruneFields(
|
||||
{ title: { en: "Bowl" }, empty: { en: "", sv: "" } },
|
||||
new Set(["title", "empty"]),
|
||||
"sv",
|
||||
);
|
||||
expect(out).toEqual({});
|
||||
});
|
||||
Reference in New Issue
Block a user