Files
EpicNext-Cms/src/features/housekeeping/domains/operations/pages/workspace.test.tsx
T

159 lines
4.5 KiB
TypeScript

import { renderToStaticMarkup } from "react-dom/server";
import { describe, expect, it, vi } from "vitest";
import { PERMS } from "@/lib/permission-slugs";
import {
anyCapability,
type HousekeepingRouteDefinition,
ok,
} from "../../../foundation/contracts";
import { defaultHousekeepingPreferences } from "../../../foundation/preferences/schema";
import type { HousekeepingWidgetOption } from "../../../foundation/preferences/widget-options";
import type { OperationsWorkspaceLoadResult } from "../queries";
import { OperationsWorkspacePage } from "./workspace";
const capability = anyCapability(PERMS.USERS_VIEW);
const routes: readonly HousekeepingRouteDefinition[] = [
{
id: "people.users",
labelKey: "Users",
href: "/ase/people/users",
capability,
},
];
const widgets: readonly HousekeepingWidgetOption[] = [
{
id: "people.queue",
kind: "mandatory",
},
];
const preferences = {
...defaultHousekeepingPreferences(),
pinnedRouteIds: ["people.users"],
shortcutOrder: ["people.users"],
widgetOrder: ["people.queue"],
};
const result: OperationsWorkspaceLoadResult = {
model: {
inbox: {
items: [
{
sourceId: "people.queue",
itemId: "ticket-1",
deduplicationKey: "people.queue:ticket-1",
domain: "people",
capability,
severity: "warning",
priority: "high",
ageMs: 1_000,
state: "open",
occurredAt: "2026-08-30T10:00:00.000Z",
titleKey: "Ticket",
href: "/ase/people/users",
freshness: "fresh",
actions: [],
},
],
errors: [{ sourceId: "system.alerts", code: "TIMEOUT" }],
correlationId: "inbox",
},
recent: [
{
routeId: "people.users",
canonicalHref: "/ase/people/users",
labelKey: "Users",
occurredAt: "2026-08-30T09:00:00.000Z",
source: "route-visit",
},
],
favorites: preferences,
widgets: {
widgets: [{ id: "people.queue", data: { count: 1 } }],
errors: [{ widgetId: "system.health", code: "TIMEOUT" }],
},
},
errors: [{ section: "recent", code: "DEPENDENCY_UNAVAILABLE" }],
correlationId: "workspace",
};
const savePreferences = vi.fn(async (value) => ok(value, "saved"));
const labels = {
title: "Operations workspace",
description: "Capability-derived operational home",
noDomainsTitle: "No operational domains are available",
noDomainsDescription: "No authorized domain",
partial: "Some workspace sections are unavailable",
inbox: {
title: "Operational inbox",
domainFilter: "Filter by domain",
stateFilter: "Filter by state",
priorityFilter: "Filter by priority",
all: "All",
loading: "Loading",
empty: "Empty",
partial: "Some sources are unavailable",
open: "Open",
},
recent: { title: "Recent work", empty: "Nothing recent" },
favorites: {
title: "Favorites",
pin: "Pin",
unpin: "Unpin",
error: "Preferences could not be saved",
reorderInstructions: "Press Space, then use arrow keys.",
},
widgetSettings: {
title: "Widget settings",
mandatory: "Mandatory",
error: "Preferences could not be saved",
},
widgets: {
title: "Widgets",
partial: "Some widgets are unavailable",
error: "Widget order could not be saved",
reorderInstructions: "Press Space, then use arrow keys.",
},
} as const;
const routeTitles = { Users: "Users" };
const widgetTitles = { "people.queue": "People queue" };
describe("OperationsWorkspacePage", () => {
it("renders capability-filtered sections, partial failures, and preview links", () => {
const html = renderToStaticMarkup(
<OperationsWorkspacePage
result={result}
routes={routes}
widgetDefinitions={widgets}
labels={labels}
routeTitles={routeTitles}
widgetTitles={widgetTitles}
savePreferences={savePreferences}
/>,
);
expect(html).toContain("Operations workspace");
expect(html).toContain("Operational inbox");
expect(html).toContain("Recent work");
expect(html).toContain("Favorites");
expect(html).toContain("Widget settings");
expect(html).toContain("Some workspace sections are unavailable");
expect(html).not.toContain("system.alerts");
expect(html).not.toContain("system.health");
expect(html).toContain('href="/ase/people/users"');
});
it("renders an explicit state when no operational domain is accessible", () => {
const html = renderToStaticMarkup(
<OperationsWorkspacePage
result={result}
routes={[]}
widgetDefinitions={[]}
labels={labels}
routeTitles={{}}
widgetTitles={{}}
savePreferences={savePreferences}
/>,
);
expect(html).toContain("No operational domains are available");
expect(html).not.toContain("Operational inbox");
});
});