import { describe, expect, it } from "vitest"; import { z } from "zod"; import { PERMS } from "@/lib/permission-slugs"; import type { HousekeepingCommand } from "../commands/registry"; import type { HousekeepingCapabilityContext, HousekeepingDomainManifest, } from "../contracts"; import type { HousekeepingRegistry } from "../registry"; import { searchNavigationAndCommands } from "./navigation-search"; function context(granted: readonly string[]): HousekeepingCapabilityContext { const permissions = new Set(granted); return { actor: { id: 42, username: "operator", rank: 7 }, isSuperAdmin: false, has: (slug) => permissions.has(slug), hasAny: (...slugs) => slugs.some((slug) => permissions.has(slug)), hasAll: (...slugs) => slugs.every((slug) => permissions.has(slug)), }; } const peopleManifest = { id: "people", labelKey: "pages.housekeeping.domains.people.title", descriptionKey: "pages.housekeeping.domains.people.description", iconId: "users", canonicalHref: "/ase/people", capability: { mode: "any", slugs: [PERMS.USERS_VIEW] }, routes: [ { id: "people.users", href: "/ase/people/users", labelKey: "pages.housekeeping.routes.people.users", capability: { mode: "any", slugs: [PERMS.USERS_VIEW] }, }, { id: "people.moderation", href: "/ase/people/moderation", labelKey: "pages.housekeeping.routes.people.moderation", capability: { mode: "any", slugs: [PERMS.MODERATION_VIEW] }, }, ], searchProviders: [], inboxSources: [], widgets: [], } as const satisfies HousekeepingDomainManifest; const registry: HousekeepingRegistry = { domains: [peopleManifest] }; function command( id: string, permission: string, ): HousekeepingCommand, never> { return { id, owner: "people", risk: "safe", capability: { mode: "any", slugs: [permission] }, input: z.object({}), requiresReason: false, rateLimit: { attempts: 3, windowMs: 60_000 }, execute: async () => ({ ok: true, data: undefined as never, correlationId: "command", }), }; } const translations: Record = { "pages.housekeeping.domains.people.title": "People", "pages.housekeeping.domains.people.description": "Accounts and moderation", "pages.housekeeping.routes.people.users": "User accounts", "pages.housekeeping.routes.people.moderation": "Moderation queue", }; describe("navigation and command search", () => { it("matches permitted domain/routes/commands and omits forbidden entries", () => { const result = searchNavigationAndCommands({ registry, commands: [ command("people.user.refresh", PERMS.USERS_VIEW), command("people.moderation.ban", PERMS.MODERATION_VIEW), ], context: context([PERMS.USERS_VIEW]), term: "user", translate: (key) => translations[key] ?? key, }); expect(result.navigation.map((hit) => hit.id)).toEqual([ "route:people.users", ]); expect(result.commands.map((hit) => hit.commandId)).toEqual([ "people.user.refresh", ]); expect(result.navigation[0]?.href).toBe("/ase/people/users"); expect(result.commands[0]?.href).toBe("/ase/people"); }); it("normalizes terms and keeps registry/command order stable", () => { const result = searchNavigationAndCommands({ registry, commands: [ command("people.user.refresh", PERMS.USERS_VIEW), command("people.user.inspect", PERMS.USERS_VIEW), ], context: context([PERMS.USERS_VIEW]), term: " PEOPLE ", translate: (key) => translations[key] ?? key, }); expect(result.navigation.map((hit) => hit.id)).toEqual(["domain:people"]); expect(result.commands.map((hit) => hit.commandId)).toEqual([ "people.user.refresh", "people.user.inspect", ]); }); });