51 lines
1.5 KiB
TypeScript
51 lines
1.5 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
|
import { z } from "zod";
|
|
import { anyCapability, ok } from "../contracts";
|
|
import {
|
|
getHousekeepingCommand,
|
|
type HousekeepingCommand,
|
|
registerHousekeepingCommand,
|
|
} from "./registry";
|
|
|
|
function command(
|
|
id: string,
|
|
owner: "people" | "system" = "people",
|
|
): HousekeepingCommand<{ id: number }, { id: number }> {
|
|
return {
|
|
id,
|
|
owner,
|
|
risk: "safe",
|
|
capability: anyCapability("admin.users.view"),
|
|
input: z.object({ id: z.number().int().positive() }),
|
|
requiresReason: false,
|
|
rateLimit: { attempts: 4, windowMs: 30_000 },
|
|
execute: async (context, input) => ok(input, context.correlationId),
|
|
};
|
|
}
|
|
|
|
describe("housekeeping command registry", () => {
|
|
it("returns the exact command registered under its global ID", () => {
|
|
const registered = command("people.registry.lookup");
|
|
|
|
registerHousekeepingCommand(registered);
|
|
|
|
expect(getHousekeepingCommand(registered.id)).toBe(registered);
|
|
});
|
|
|
|
it("rejects a duplicate global command ID before it can shadow its owner", () => {
|
|
registerHousekeepingCommand(command("people.registry.duplicate"));
|
|
|
|
expect(() =>
|
|
registerHousekeepingCommand(command("people.registry.duplicate")),
|
|
).toThrow("duplicate command id: people.registry.duplicate");
|
|
});
|
|
|
|
it("rejects a command whose namespace disagrees with its declared owner", () => {
|
|
expect(() =>
|
|
registerHousekeepingCommand(
|
|
command("people.registry.owner-mismatch", "system"),
|
|
),
|
|
).toThrow("command owner mismatch: people.registry.owner-mismatch");
|
|
});
|
|
});
|