import { describe, expect, it } from "vitest"; import { NAVIGATION_ROUTES, ROUTE_REGISTRY, } from "../../src/features/installed-feature-contracts.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", () => { expect(ROUTE_REGISTRY.REFERENCE_RESOURCE_LIST.access).toBe( "session-required", ); expect( decideRouteAccess("REFERENCE_RESOURCE_LIST", "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); }); });