import { describe, expect, it } from "vitest"; import { NAVIGATION_ROUTES, ROUTE_REGISTRY, } from "../../src/features/installed-feature-contracts.ts"; import type { RouteDefinition } from "../../src/contracts/routes.ts"; import { createRedirectLoopGuard, decideRouteAccess, } from "../../src/presentation/routes/navigation-policy.ts"; describe("installed route registry", () => { it("derives visible navigation in explicit order", () => { const expected = Object.values(ROUTE_REGISTRY) .filter((route) => route.navigationOrder !== null) .sort( (left, right) => left.navigationOrder! - right.navigationOrder!, ) .map((route) => route.routeId); expect(NAVIGATION_ROUTES.map(({ routeId }) => routeId)).toEqual(expected); }); it("allows public routes without consulting a product permission", () => { expect(decideRouteAccess("APP_HOME", "unauthenticated")).toEqual({ allowed: true, action: "none", }); }); it("treats every non-public route as explicitly session-required", () => { const protectedRoutes = Object.values( ROUTE_REGISTRY as Readonly>, ).filter((route) => route.access !== "public"); expect( protectedRoutes.every((route) => route.access === "session-required"), ).toBe(true); for (const route of protectedRoutes) { expect(route.access).toBe("session-required"); expect(decideRouteAccess(route.routeId, "unauthenticated")).toEqual({ allowed: false, action: "show-sign-in", }); } }); it("bounds automatic redirects by pair and maximum hops", () => { const guard = createRedirectLoopGuard(2); expect(guard.allow("/private", "/signin")).toBe(true); expect(guard.allow("/private", "/signin")).toBe(false); expect(guard.allow("/signin", "/signin")).toBe(false); expect(guard.allow("/signin", "/continue")).toBe(true); expect(guard.allow("/continue", "/final")).toBe(false); expect(guard.hopCount).toBe(2); guard.reset(); expect(guard.allow("/unrelated", "/canonical-unrelated")).toBe(true); }); });