import { describe, expect, it } from "vitest"; import { ADMIN_GROUP, BOTTOM_NAV_HREFS, NAV_GROUPS, isFullScreenPage, visibleNavGroups, } from "./nav-config"; const ALL_ITEMS = [...NAV_GROUPS, ADMIN_GROUP].flatMap((group) => group.items); const ALL_PERMISSIONS = ALL_ITEMS.flatMap((item) => [ ...(item.permission === undefined ? [] : [item.permission].flat()), ...(item.alsoRequires ?? []), ]); function hrefs(permissions: string[]): string[] { return visibleNavGroups({ permissions }) .flatMap((group) => group.items) .map((item) => item.href); } describe("nav-config", () => { it('every sidebar area is reachable on a phone via bottom nav or „Mehr"', () => { const sidebar = hrefs(ALL_PERMISSIONS); // „Mehr" lists every visible group, the bottom nav the four favourites. const phone = new Set([...BOTTOM_NAV_HREFS, ...sidebar]); expect(sidebar.length).toBe(ALL_ITEMS.length); expect(sidebar.every((href) => phone.has(href))).toBe(true); expect(sidebar).toContain("/honey-batches"); }); it("keeps every bottom nav entry in the nav config", () => { const known = ALL_ITEMS.map((item) => item.href); expect(BOTTOM_NAV_HREFS.every((href) => known.includes(href))).toBe(true); }); it("admin entries need their permission", () => { expect(hrefs([])).not.toContain("/settings/audit-log"); expect(hrefs([])).not.toContain("/settings/backup"); expect(visibleNavGroups({ permissions: [] }).map((g) => g.label)).not.toContain( "Verwaltung", ); const admin = visibleNavGroups({ permissions: ["audit:read"] }).find( (group) => group.label === "Verwaltung", ); expect(admin?.items.map((item) => item.href)).toEqual(["/settings/audit-log"]); }); it("shows the System entry only with system:read", () => { expect(hrefs([])).not.toContain("/settings/system"); expect(hrefs(["system:read"])).toContain("/settings/system"); }); it("shows „Beutensysteme“ only with hive-systems:manage", () => { expect(hrefs([])).not.toContain("/settings/hive-systems"); expect(hrefs(["colonies:read"])).not.toContain("/settings/hive-systems"); expect(hrefs(["hive-systems:manage"])).toContain("/settings/hive-systems"); }); it("hides items the user may not see", () => { expect(hrefs([])).not.toContain("/winter"); expect(hrefs(["winter-checks:read"])).toContain("/winter"); }); it("„Vorschläge“ needs tasks:read and shows the open count", () => { expect(hrefs([])).not.toContain("/suggestions"); const work = visibleNavGroups({ permissions: ["tasks:read"] }).find( (group) => group.label === "Arbeit", ); const item = work?.items.find((entry) => entry.href === "/suggestions"); expect(item?.label).toBe("Vorschläge"); expect(item?.counter).toBe("suggestions"); }); it("shows „Sprachnotizen“ only with voice-captures:use AND inspections:create", () => { expect(hrefs([])).not.toContain("/voice"); expect(hrefs(["voice-captures:use"])).not.toContain("/voice"); expect(hrefs(["inspections:create"])).not.toContain("/voice"); const work = visibleNavGroups({ permissions: ["voice-captures:use", "inspections:create"], }).find((group) => group.label === "Arbeit"); const item = work?.items.find((entry) => entry.href === "/voice"); expect(item?.label).toBe("Sprachnotizen"); }); it("shows Prüfbereitschaft only with compliance:read", () => { expect(hrefs([])).not.toContain("/compliance"); expect(hrefs(["compliance:read"])).toContain("/compliance"); const group = visibleNavGroups({ permissions: ["compliance:read"] }).find((g) => g.items.some((item) => item.href === "/compliance"), ); expect(group?.label).toBe("Betrieb"); expect(group?.items.find((item) => item.href === "/compliance")?.label).toBe("Prüfbereitschaft"); }); it("knows the Beute editor („Umbauen“) as the one full-screen page", () => { expect(isFullScreenPage("/colonies/c1/hive")).toBe(true); expect(isFullScreenPage("/colonies/c%201/hive/")).toBe(true); expect(isFullScreenPage("/colonies/c1")).toBe(false); expect(isFullScreenPage("/colonies")).toBe(false); expect(isFullScreenPage("/colonies/c1/hive/history")).toBe(false); expect(isFullScreenPage("/apiaries/a1/hive")).toBe(false); }); });