feat(housekeeping): compose operations workspace
This commit is contained in:
@@ -0,0 +1,91 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { PERMS } from "@/lib/permission-slugs";
|
||||
import type { HousekeepingCapabilityContext } from "../../foundation/contracts";
|
||||
import { operationsMigrationEntries } from "../../migration/operations";
|
||||
import { OPERATIONS_INBOX_SOURCES } from "./inbox";
|
||||
import { operationsManifest } from "./manifest";
|
||||
import { OPERATIONS_ROUTES } from "./routes";
|
||||
import { OPERATIONS_SEARCH_PROVIDERS } from "./search";
|
||||
import { OPERATIONS_WIDGETS } from "./widgets";
|
||||
|
||||
const context: HousekeepingCapabilityContext = {
|
||||
actor: { id: 42, username: "operator", rank: 7 },
|
||||
isSuperAdmin: false,
|
||||
has: (slug) => slug === PERMS.ADMIN_DASHBOARD,
|
||||
hasAny: (...slugs) => slugs.includes(PERMS.ADMIN_DASHBOARD),
|
||||
hasAll: (...slugs) => slugs.every((slug) => slug === PERMS.ADMIN_DASHBOARD),
|
||||
};
|
||||
|
||||
describe("Operations workspace registration", () => {
|
||||
it("maps the one legacy dashboard row to operations.workspace at canonical /ase", () => {
|
||||
expect(OPERATIONS_ROUTES).toEqual([
|
||||
expect.objectContaining({
|
||||
id: "operations.workspace",
|
||||
href: "/ase",
|
||||
capability: { mode: "any", slugs: [PERMS.ADMIN_DASHBOARD] },
|
||||
}),
|
||||
]);
|
||||
expect(operationsMigrationEntries).toEqual([
|
||||
expect.objectContaining({
|
||||
legacyPath: "/admin",
|
||||
targetDomain: "operations",
|
||||
targetPath: OPERATIONS_ROUTES[0]?.href,
|
||||
}),
|
||||
]);
|
||||
});
|
||||
|
||||
it("publishes a real route, safe navigation search, inbox summary, and mandatory widget", async () => {
|
||||
expect(operationsManifest.routes).toEqual(OPERATIONS_ROUTES);
|
||||
expect(operationsManifest.searchProviders).toEqual(
|
||||
OPERATIONS_SEARCH_PROVIDERS,
|
||||
);
|
||||
expect(operationsManifest.inboxSources).toEqual(OPERATIONS_INBOX_SOURCES);
|
||||
expect(operationsManifest.widgets).toEqual(OPERATIONS_WIDGETS);
|
||||
|
||||
const search = await OPERATIONS_SEARCH_PROVIDERS[0]?.search(context, {
|
||||
term: "operations",
|
||||
limit: 25,
|
||||
});
|
||||
expect(search).toMatchObject({
|
||||
ok: true,
|
||||
data: [
|
||||
expect.objectContaining({
|
||||
id: "operations.workspace",
|
||||
type: "navigation",
|
||||
href: "/ase",
|
||||
}),
|
||||
],
|
||||
});
|
||||
|
||||
const inbox = await OPERATIONS_INBOX_SOURCES[0]?.getItems(
|
||||
context,
|
||||
new AbortController().signal,
|
||||
);
|
||||
expect(inbox).toMatchObject({
|
||||
ok: true,
|
||||
data: {
|
||||
availability: "available",
|
||||
items: [
|
||||
expect.objectContaining({
|
||||
sourceId: "operations.access-summary",
|
||||
href: "/ase",
|
||||
}),
|
||||
],
|
||||
},
|
||||
});
|
||||
|
||||
expect(OPERATIONS_WIDGETS[0]).toMatchObject({
|
||||
id: "operations.workspace-summary",
|
||||
kind: "mandatory",
|
||||
owner: "operations",
|
||||
});
|
||||
const widget = await OPERATIONS_WIDGETS[0]?.load(
|
||||
context,
|
||||
new AbortController().signal,
|
||||
);
|
||||
expect(widget).toMatchObject({
|
||||
ok: true,
|
||||
data: { accessibleDomains: 0, accessibleRoutes: 0 },
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user