feat(housekeeping): add global command deck search
This commit is contained in:
1 parent
2e95a106e0
commit
bcb0ca977f
18 files changed
+1353
-23
No files matched your search
@@ -0,0 +1,119 @@
|
||||
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<Record<string, never>, 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<string, string> = {
|
||||
"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",
|
||||
]);
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user