import { readFileSync } from "node:fs"; import { resolve } from "node:path"; import { renderToStaticMarkup } from "react-dom/server"; import { describe, expect, it, vi } from "vitest"; import { CommandDeck, commandDeckKeyAction, flattenHousekeepingSearchResults, isCommandDeckShortcut, nextCommandDeckIndex, projectHousekeepingSearchHref, restoreCommandDeckFocus, } from "./command-deck"; vi.mock("@/actions/housekeeping-search", () => ({ executeHousekeepingSearch: vi.fn(), })); const labels = { trigger: "Search housekeeping", placeholder: "Search navigation, commands, and entities", navigation: "Navigation", commands: "Commands", entities: "Entities", loading: "Searching…", empty: "No results", partial: "Some providers are unavailable", close: "Close", }; describe("CommandDeck", () => { it("renders an enabled accessible cmdk trigger", () => { const html = renderToStaticMarkup( , ); expect(html).toContain("Search housekeeping"); expect(html).toContain('aria-haspopup="dialog"'); expect(html).not.toContain("disabled"); expect(html).toContain("Ctrl+K"); }); it("models shortcut, arrows, Enter, and Escape deterministically", () => { expect( isCommandDeckShortcut({ key: "k", ctrlKey: true, metaKey: false }), ).toBe(true); expect( isCommandDeckShortcut({ key: "K", ctrlKey: false, metaKey: true }), ).toBe(true); expect( isCommandDeckShortcut({ key: "k", ctrlKey: true, metaKey: false, altKey: true, }), ).toBe(false); expect(commandDeckKeyAction("Escape", true)).toBe("close"); expect(commandDeckKeyAction("ArrowDown", true)).toBe("next"); expect(commandDeckKeyAction("ArrowUp", true)).toBe("previous"); expect(commandDeckKeyAction("Enter", true)).toBe("activate"); expect(commandDeckKeyAction("Enter", false)).toBe(null); expect(nextCommandDeckIndex(-1, 3, "next")).toBe(0); expect(nextCommandDeckIndex(2, 3, "next")).toBe(0); expect(nextCommandDeckIndex(0, 3, "previous")).toBe(2); }); it("restores trigger focus and keeps canonical result hrefs", () => { const focus = vi.fn(); restoreCommandDeckFocus({ focus }); expect(focus).toHaveBeenCalledOnce(); expect(projectHousekeepingSearchHref("/ase/people/users")).toBe( "/ase/people/users", ); }); it("keeps grouped result order and uses cmdk input/items in the client module", () => { const flattened = flattenHousekeepingSearchResults({ navigation: [ { id: "route:people.users", domain: "people", type: "navigation", title: "Users", href: "/ase/people/users", capability: { mode: "any", slugs: ["users.view"] }, }, ], commands: [ { id: "command:people.user.refresh", commandId: "people.user.refresh", domain: "people", type: "command", title: "User Refresh", href: "/ase/people", capability: { mode: "any", slugs: ["users.view"] }, risk: "safe", requiresReason: false, }, ], entities: [], errors: [], correlationId: "deck", }); expect(flattened.map((entry) => entry.group)).toEqual([ "navigation", "commands", ]); const source = readFileSync( resolve( process.cwd(), "src/features/housekeeping/foundation/shell/command-deck.tsx", ), "utf8", ); expect(source).toContain("CommandInput"); expect(source).toContain("CommandItem"); expect(source).toContain("onSelect"); }); });