test/shared/entity-pages/core.test.ts
Rama main · réplica de lectura del repositorio original.
import { expect } from "@std/expect";
import { describe, it as test } from "@std/testing/bdd";
import {
resolveTabSlug,
splitActions,
type TabState,
tabLinks,
tabPath,
wrapAroundNeighbours,
} from "#shared/entity-pages/core.ts";
const tab = (slug: string, visible = true): TabState => ({
labelKey: `entity.tab.${slug || "overview"}`,
slug,
visible,
});
describe("tabPath", () => {
test("the default tab is the bare base path, not a trailing slash", () => {
expect(tabPath("/admin/attendees/5", "")).toBe("/admin/attendees/5");
});
test("a named tab appends its slug as a path segment", () => {
expect(tabPath("/admin/attendees/5", "ledger")).toBe(
"/admin/attendees/5/ledger",
);
});
});
describe("resolveTabSlug", () => {
const tabs = [tab(""), tab("edit"), tab("ledger", false), tab("activity")];
test("a bare request lands on the first VISIBLE tab", () => {
expect(resolveTabSlug(tabs, "")).toBe("");
// Role-aware default: when the first tab is hidden, the bare URL lands
// on the next visible one instead of 404ing or leaking the hidden tab.
expect(resolveTabSlug([tab("", false), tab("edit")], "")).toBe("edit");
});
test("a named visible tab resolves to itself", () => {
expect(resolveTabSlug(tabs, "edit")).toBe("edit");
expect(resolveTabSlug(tabs, "activity")).toBe("activity");
});
test("a hidden tab 404s even when named directly — visibility IS authorization", () => {
expect(resolveTabSlug(tabs, "ledger")).toBeNull();
});
test("an unknown slug resolves to null (404)", () => {
expect(resolveTabSlug(tabs, "nonsense")).toBeNull();
});
test("no visible tabs at all resolves to null", () => {
expect(resolveTabSlug([tab("", false)], "")).toBeNull();
});
});
describe("tabLinks", () => {
test("hidden tabs are absent from the strip entirely, and only the active tab is marked", () => {
const links = tabLinks(
[tab(""), tab("edit"), tab("ledger", false)],
"/admin/attendees/5",
"edit",
);
expect(links).toEqual([
{
active: false,
href: "/admin/attendees/5",
labelKey: "entity.tab.overview",
},
{
active: true,
href: "/admin/attendees/5/edit",
labelKey: "entity.tab.edit",
},
]);
});
});
describe("splitActions", () => {
test("splits danger actions from plain ones, preserving order within each", () => {
const actions = [
{ danger: false, name: "refund" },
{ name: "resend" },
{ danger: true, name: "delete" },
{ name: "text" },
];
expect(splitActions(actions)).toEqual({
danger: [{ danger: true, name: "delete" }],
plain: [
{ danger: false, name: "refund" },
{ name: "resend" },
{ name: "text" },
],
});
});
test("an empty list yields two empty halves", () => {
expect(splitActions([])).toEqual({ danger: [], plain: [] });
});
});
describe("wrapAroundNeighbours", () => {
test("gives a missing current item no neighbours on either side", () => {
expect(wrapAroundNeighbours(["A", "B"], (item) => item === "Z")).toEqual({
next: null,
previous: null,
});
});
test("gives an empty list no neighbours", () => {
expect(wrapAroundNeighbours([], () => false)).toEqual({
next: null,
previous: null,
});
});
test("gives the only item in a one-item list no neighbours", () => {
expect(wrapAroundNeighbours(["A"], (item) => item === "A")).toEqual({
next: null,
previous: null,
});
});
test("treats a falsy-looking item as a neighbour all the same", () => {
expect(wrapAroundNeighbours(["A", 0], (item) => item === "A").next).toBe(0);
expect(
wrapAroundNeighbours([0, "A"], (item) => item === "A").previous,
).toBe(0);
});
test("neighbours the middle item plainly", () => {
expect(
wrapAroundNeighbours(["A", "B", "C"], (item) => item === "B"),
).toEqual({ next: "C", previous: "A" });
});
test("wraps the first item's previous to the list's last", () => {
expect(
wrapAroundNeighbours(["A", "B", "C"], (item) => item === "A"),
).toEqual({ next: "B", previous: "C" });
});
test("wraps the last item's next to the list's first", () => {
expect(
wrapAroundNeighbours(["A", "B", "C"], (item) => item === "C"),
).toEqual({ next: "A", previous: "B" });
});
});