import { readFileSync } from "node:fs";
import { resolve } from "node:path";
import { renderToStaticMarkup } from "react-dom/server";
import { describe, expect, it, vi } from "vitest";
import type { HousekeepingSurface } from "../contracts";
import type { HousekeepingNavigationDomain } from "../navigation";
import { HousekeepingShell } from "./housekeeping-shell";
vi.mock("@/actions/housekeeping-search", () => ({
executeHousekeepingSearch: vi.fn(),
}));
const labels = {
skipToContent: "Skip to housekeeping content",
primaryNavigation: "Primary housekeeping navigation",
contextualNavigation: "Operations navigation",
command: "Search housekeeping",
preview: "Preview",
backToSite: "Back to site",
operatorRank: "Rank 6",
commandDeck: {
placeholder: "Search navigation, commands, and entities",
navigation: "Navigation",
commands: "Commands",
entities: "Entities",
loading: "Searching…",
empty: "No results",
partial: "Some providers are unavailable",
close: "Close",
},
};
const domains: readonly HousekeepingNavigationDomain[] = [
{
id: "operations",
href: "/ase-next/operations",
iconId: "inbox",
label: "Operations",
description: "Manage operations",
items: [
{ id: "queue", href: "/ase-next/operations/queue", label: "Queue" },
],
},
{
id: "people",
href: "/ase-next/people",
iconId: "users",
label: "People",
description: "Manage people",
items: [],
},
{
id: "content",
href: "/ase-next/content",
iconId: "file-text",
label: "Content",
description: "Manage content",
items: [],
},
{
id: "economy",
href: "/ase-next/economy",
iconId: "gem",
label: "Economy",
description: "Manage economy",
items: [],
},
{
id: "hotel",
href: "/ase-next/hotel",
iconId: "hotel",
label: "Hotel",
description: "Manage hotel",
items: [],
},
{
id: "system",
href: "/ase-next/system",
iconId: "settings",
label: "System",
description: "Manage system",
items: [],
},
];
const taskFiles = [
"src/features/housekeeping/foundation/shell/housekeeping-shell.tsx",
"src/features/housekeeping/foundation/shell/domain-rail.tsx",
"src/features/housekeeping/foundation/shell/context-nav.tsx",
"src/features/housekeeping/foundation/shell/command-trigger.tsx",
"src/features/housekeeping/foundation/shell/operator-summary.tsx",
"src/features/housekeeping/foundation/page/housekeeping-page-shell.tsx",
"src/features/housekeeping/foundation/page/housekeeping-page-state.tsx",
"src/features/housekeeping/foundation/shell/housekeeping-shell.test.tsx",
"src/features/housekeeping/foundation/page/housekeeping-page-state.test.tsx",
] as const;
const componentTaskFiles = taskFiles.slice(0, 7);
const structuralBoundaryRules = [
{ label: "client directive", pattern: new RegExp("use " + "client") },
{
label: "palette color",
pattern:
/(?:bg|text|border|from|via|to|ring|outline|fill|stroke|divide|shadow|accent|caret|decoration|placeholder)-(?:white|black|slate|gray|zinc|neutral|stone|red|orange|amber|yellow|lime|green|emerald|teal|cyan|sky|blue|indigo|violet|purple|fuchsia|pink|rose)(?:-\d{2,3})?/,
},
{ label: "hex color", pattern: new RegExp("#" + "[0-9a-fA-F]{3,8}") },
{
label: "rgb or hsl color",
pattern: new RegExp("(?:r" + "gb|h" + "sl)\\("),
},
];
const componentBoundaryRules = [
{
label: "React hook",
pattern: /\b(?:React\.)?use[A-Z]\w*(?:\s*\(|\s*(?:as|,|}))/,
},
{ label: "click handler", pattern: /\bonClick\s*=/ },
{ label: "keyboard handler", pattern: /\bonKey(?:Down|Up|Press)\s*=/ },
{ label: "executable JSX event prop", pattern: /\bon[A-Z]\w*\s*=/ },
{ label: "event listener", pattern: new RegExp("addEvent" + "Listener") },
{
label: "inline literal color",
pattern:
/\bstyle\s*=\s*\{\{[^}]*\b(?:color|background(?:Color)?|borderColor|fill|stroke)\s*:\s*["'](?!var\(--admin-[^)]+\))[^"']+["']/,
},
{
label: "database or action import",
pattern: new RegExp(
"(?:from\\s*|import\\s*\\()\\s*['\"][^'\"]*(?:@/lib/" +
"db|drizzle(?:-orm)?|/" +
"actions?)[^'\"]*['\"]",
),
},
{ label: "command package", pattern: new RegExp("cmd" + "k", "i") },
{ label: "localization import", pattern: new RegExp("next" + "-intl") },
{
label: "search or mutation runtime",
pattern: /\b(?:fetch|useQuery|useMutation)\s*\(/,
},
{
label: "persistence storage",
pattern:
/\b(?:localStorage|sessionStorage|indexedDB)\b|\.(?:setItem|getItem|removeItem)\s*\(/,
},
];
function renderShell(
activeDomainId: HousekeepingNavigationDomain["id"] = "operations",
availableDomains: readonly HousekeepingNavigationDomain[] = domains,
surface: HousekeepingSurface = "preview",
): string {
return renderToStaticMarkup(
Deck body