Files
EpicNext-Cms/src/features/housekeeping/domains/hotel/hotel-providers.test.ts
T
Simo 43470ebf82
CI / check (pull_request) Failing after 10s
CI / deploy (pull_request) Skipped
CI / release (pull_request) Skipped
feat(housekeeping): unify complete rebuild in gated preview
2026-08-31 20:37:51 +02:00

75 lines
2.3 KiB
TypeScript

import { describe, expect, it, vi } from "vitest";
import { PERMS } from "@/lib/permission-slugs";
import type { HousekeepingCapabilityContext } from "../../foundation/contracts";
import { createHotelInboxSources } from "./inbox";
import { createHotelSearchProviders } from "./search";
import { createHotelWidgets } from "./widgets";
function context(granted: readonly string[]): HousekeepingCapabilityContext {
const permissions = new Set(granted);
return {
actor: { id: 42, username: "operator", rank: 7 },
isSuperAdmin: false,
has: (slug) => permissions.has(slug),
hasAny: (...slugs) => slugs.some((slug) => permissions.has(slug)),
hasAll: (...slugs) => slugs.every((slug) => permissions.has(slug)),
};
}
describe("Hotel Studio providers", () => {
it("publishes searchable Studio operations with capability filtering", async () => {
const [provider] = createHotelSearchProviders({
studio: vi.fn(async () => [
{
id: "op-1",
title: "Furniture import",
description: "running",
href: "/ase-next/hotel/studio/furni",
},
]),
});
const result = await provider.search(context([PERMS.ASSETS_IMPORT]), {
term: " furni ",
limit: 50,
});
expect(result).toMatchObject({
ok: true,
data: [{ id: "op-1", domain: "hotel" }],
});
});
it("exposes an operational inbox source and mandatory active widget", async () => {
const operation = {
operationId: "op-1",
kind: "sync" as const,
phase: "failed" as const,
completed: 3,
total: 5,
messageKey: "errors.housekeeping.dependencyUnavailable",
correlationId: "corr-1",
actorId: 42,
createdAt: "2026-08-30T10:00:00.000Z",
updatedAt: "2026-08-30T10:01:00.000Z",
};
const [source] = createHotelInboxSources({
operations: vi.fn(async () => [operation]),
});
const [widget] = createHotelWidgets({
activeOperations: vi.fn(async () => ({ running: 2, failed: 1 })),
});
expect(widget.kind).toBe("mandatory");
expect(
await source.getItems(
context([PERMS.ASSETS_IMPORT]),
new AbortController().signal,
),
).toMatchObject({ ok: true, data: { items: [{ state: "failed" }] } });
expect(
await widget.load(
context([PERMS.ASSETS_IMPORT]),
new AbortController().signal,
),
).toMatchObject({ ok: true, data: { running: 2, failed: 1 } });
});
});