134 lines
4.7 KiB
TypeScript
134 lines
4.7 KiB
TypeScript
// Breadcrumb helper unit test — the parent-nav-crumb rule that decides whether
|
|
// the responsible sidebar entry is prefixed to the loader-derived trail.
|
|
|
|
import { describe, expect, it } from "vitest";
|
|
import { shouldShowParentNavCrumb, type BreadcrumbTrailEntry } from "./useTitleData";
|
|
|
|
const CONTACTS_TRAIL: BreadcrumbTrailEntry[] = [
|
|
{ label: "Kontakte", href: "/app/acme/contacts" },
|
|
{ label: "Tags", href: "/app/acme/contacts/admin/tags" },
|
|
];
|
|
|
|
describe("shouldShowParentNavCrumb", () => {
|
|
it("drops a nav crumb whose target the trail already points at under a different name", () => {
|
|
// The CRM sidebar entry links to the contact list; the trail names that very
|
|
// page "Kontakte". A "CRM" crumb would be a second crumb for one route.
|
|
expect(
|
|
shouldShowParentNavCrumb({
|
|
navPath: "/app/acme/contacts",
|
|
navTitle: "CRM",
|
|
currentPathname: "/app/acme/contacts/admin/tags",
|
|
currentCrumbLabel: "Tags",
|
|
trail: CONTACTS_TRAIL,
|
|
}),
|
|
).toBe(false);
|
|
});
|
|
|
|
it("ignores a trailing slash when comparing the nav target with the trail", () => {
|
|
expect(
|
|
shouldShowParentNavCrumb({
|
|
navPath: "/app/acme/contacts/",
|
|
navTitle: "CRM",
|
|
currentPathname: "/app/acme/contacts/admin/tags",
|
|
currentCrumbLabel: "Tags",
|
|
trail: CONTACTS_TRAIL,
|
|
}),
|
|
).toBe(false);
|
|
});
|
|
|
|
it("drops a nav crumb that the trail already carries under the same label", () => {
|
|
expect(
|
|
shouldShowParentNavCrumb({
|
|
navPath: "/app/acme/other",
|
|
navTitle: "Kontakte",
|
|
currentPathname: "/app/acme/contacts/admin/tags",
|
|
currentCrumbLabel: "Tags",
|
|
trail: CONTACTS_TRAIL,
|
|
}),
|
|
).toBe(false);
|
|
});
|
|
|
|
it("drops the nav crumb when it is the current page", () => {
|
|
expect(
|
|
shouldShowParentNavCrumb({
|
|
navPath: "/app/acme/contacts",
|
|
navTitle: "CRM",
|
|
currentPathname: "/app/acme/contacts/",
|
|
currentCrumbLabel: "Kontakte",
|
|
trail: [{ label: "Kontakte", href: "/app/acme/contacts" }],
|
|
}),
|
|
).toBe(false);
|
|
});
|
|
|
|
it("keeps a nav crumb that names a section the trail does not cover", () => {
|
|
expect(
|
|
shouldShowParentNavCrumb({
|
|
navPath: "/app/acme/bookings/pages",
|
|
navTitle: "Buchungsseiten",
|
|
currentPathname: "/app/acme/bookings/pages/p1/edit",
|
|
currentCrumbLabel: "Editor",
|
|
trail: [{ label: "Editor", href: "/app/acme/bookings/pages/p1/edit" }],
|
|
}),
|
|
).toBe(true);
|
|
});
|
|
|
|
it("drops the nav crumb when the current page has its own row in the inner sub-sidenav", () => {
|
|
// /leads-statistics is a sibling entry under the Leads area. The rail
|
|
// already shows that context, so a "Leads" crumb would invent a level.
|
|
expect(
|
|
shouldShowParentNavCrumb({
|
|
navPath: "/app/acme/leads",
|
|
navTitle: "Leads",
|
|
currentPathname: "/app/acme/leads-statistics",
|
|
currentCrumbLabel: "Lead-Statistiken",
|
|
trail: [{ label: "Lead-Statistiken", href: "/app/acme/leads-statistics" }],
|
|
navContextPaths: ["/app/acme/leads", "/app/acme/leads-statistics"],
|
|
}),
|
|
).toBe(false);
|
|
});
|
|
|
|
it("keeps the nav crumb for a sub-page that has no row of its own in the rail", () => {
|
|
expect(
|
|
shouldShowParentNavCrumb({
|
|
navPath: "/app/acme/leads",
|
|
navTitle: "Leads",
|
|
currentPathname: "/app/acme/leads/l1",
|
|
currentCrumbLabel: "Karin Lehmann",
|
|
trail: [{ label: "Karin Lehmann", href: "/app/acme/leads/l1" }],
|
|
navContextPaths: ["/app/acme/leads", "/app/acme/leads-statistics"],
|
|
}),
|
|
).toBe(true);
|
|
});
|
|
|
|
it("drops the nav crumb when the trail already links to a row of the inner sub-sidenav", () => {
|
|
// Booking detail below the "Buchungen" row of the Termine rail: the trail
|
|
// names that row itself, so the area crumb would add a third level for a
|
|
// path the user walked in two steps.
|
|
expect(
|
|
shouldShowParentNavCrumb({
|
|
navPath: "/app/acme/calendar",
|
|
navTitle: "Termine",
|
|
currentPathname: "/app/acme/bookings/b1",
|
|
currentCrumbLabel: "Buchung",
|
|
trail: [
|
|
{ label: "Buchungen", href: "/app/acme/bookings" },
|
|
{ label: "Buchung", href: "/app/acme/bookings/b1" },
|
|
],
|
|
navContextPaths: ["/app/acme/calendar", "/app/acme/bookings", "/app/acme/availability"],
|
|
}),
|
|
).toBe(false);
|
|
});
|
|
|
|
it("drops the nav crumb when the entry has no path to link to", () => {
|
|
expect(
|
|
shouldShowParentNavCrumb({
|
|
navPath: "",
|
|
navTitle: "CRM",
|
|
currentPathname: "/app/acme/contacts/admin/tags",
|
|
currentCrumbLabel: "Tags",
|
|
trail: CONTACTS_TRAIL,
|
|
}),
|
|
).toBe(false);
|
|
});
|
|
});
|