Files
EpicNext-Cms/src/features/housekeeping/domains/people/people-widgets-production.test.ts
T
Simo 3fa1119f5a
CI / check (pull_request) Failing after 9s
CI / release (pull_request) Skipped
CI / deploy (pull_request) Skipped
fix(housekeeping): address people moderation review
2026-08-29 23:53:38 +02:00

101 lines
3.1 KiB
TypeScript

import { beforeEach, describe, expect, it, vi } from "vitest";
import { PERMS } from "@/lib/permission-slugs";
import type { HousekeepingCapabilityContext } from "../../foundation/contracts";
const mocks = vi.hoisted(() => ({
execute: vi.fn(),
fetchTicketQueueOpenCounts: vi.fn(),
}));
vi.mock("@/lib/admin/ticket-queue-counts", () => ({
fetchTicketQueueOpenCounts: mocks.fetchTicketQueueOpenCounts,
}));
vi.mock("@/lib/db", () => {
return { db: { execute: mocks.execute } };
});
import { PEOPLE_WIDGETS } from "./widgets";
function context(granted: readonly string[]): HousekeepingCapabilityContext {
const permissions = new Set(granted);
return {
actor: { id: 42, username: "operator", rank: 4 },
isSuperAdmin: false,
has: (slug) => permissions.has(slug),
hasAny: (...slugs) => slugs.some((slug) => permissions.has(slug)),
hasAll: (...slugs) => slugs.every((slug) => permissions.has(slug)),
};
}
async function load(granted: readonly string[]) {
return PEOPLE_WIDGETS[0].load(
context(granted),
new AbortController().signal,
);
}
beforeEach(() => {
vi.clearAllMocks();
mocks.fetchTicketQueueOpenCounts.mockResolvedValue({
cmsOpen: 1,
helpOpen: 2,
});
});
describe("People production queue widget", () => {
it("wires ticket-only, CFH-only, ban-only, mixed, and denied contexts without unauthorized reads", async () => {
await expect(load([PERMS.MOD_TICKETS_VIEW])).resolves.toMatchObject({
ok: true,
data: { tickets: 1, helpTickets: 2, cfh: 0, activeBans: 0 },
});
expect(mocks.fetchTicketQueueOpenCounts).toHaveBeenCalledTimes(1);
expect(mocks.execute).not.toHaveBeenCalled();
vi.clearAllMocks();
mocks.execute.mockResolvedValueOnce([[{ total: 3 }], []]);
await expect(load([PERMS.MOD_CFH_VIEW])).resolves.toMatchObject({
ok: true,
data: { tickets: 0, helpTickets: 0, cfh: 3, activeBans: 0 },
});
expect(mocks.fetchTicketQueueOpenCounts).not.toHaveBeenCalled();
expect(mocks.execute).toHaveBeenCalledTimes(1);
vi.clearAllMocks();
mocks.execute.mockResolvedValueOnce([[{ total: 4 }], []]);
await expect(load([PERMS.MOD_BANS_VIEW])).resolves.toMatchObject({
ok: true,
data: { tickets: 0, helpTickets: 0, cfh: 0, activeBans: 4 },
});
expect(mocks.fetchTicketQueueOpenCounts).not.toHaveBeenCalled();
expect(mocks.execute).toHaveBeenCalledTimes(1);
vi.clearAllMocks();
mocks.fetchTicketQueueOpenCounts.mockResolvedValue({
cmsOpen: 1,
helpOpen: 2,
});
mocks.execute
.mockResolvedValueOnce([[{ total: 3 }], []])
.mockResolvedValueOnce([[{ total: 4 }], []]);
const mixed = await load([
PERMS.MOD_TICKETS_VIEW,
PERMS.MOD_CFH_VIEW,
PERMS.MOD_BANS_VIEW,
]);
expect(mocks.fetchTicketQueueOpenCounts).toHaveBeenCalledTimes(1);
expect(mocks.execute).toHaveBeenCalledTimes(2);
expect(mixed).toMatchObject({
ok: true,
data: { tickets: 1, helpTickets: 2, cfh: 3, activeBans: 4 },
});
vi.clearAllMocks();
await expect(load([])).resolves.toMatchObject({
ok: false,
error: { code: "FORBIDDEN" },
});
expect(mocks.fetchTicketQueueOpenCounts).not.toHaveBeenCalled();
expect(mocks.execute).not.toHaveBeenCalled();
});
});