Ctrl K
ComunidadGuías…

test/shared/entity-pages/core.test.ts

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
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" });
  });
});