import { describe, expect, it } from "vitest"; import { buildTimelineProjectContextDetailResponse, buildTimelineProjectContextResponse, buildTimelineProjectContextSummary, } from "../router/timeline-project-context-response-support.js"; describe("timeline project context response support", () => { it("combines timeline counts with holiday overlay summary data", () => { expect(buildTimelineProjectContextSummary({ allocations: [{ projectId: "project_1", resourceId: "resource_1" }], demands: [{ projectId: "project_1" }], assignments: [{ projectId: "project_1", resourceId: "resource_1" }], resourceIds: ["resource_1", "resource_2"], allResourceAllocations: [{ id: "booking_1" }, { id: "booking_2" }], assignmentConflicts: [ { crossProjectOverlapCount: 0 }, { crossProjectOverlapCount: 2 }, ], holidayOverlays: [ { id: "overlay_1", resourceId: "resource_1", startDate: "2026-04-03", endDate: "2026-04-03", note: "Holiday", scope: "COUNTRY", calendarName: "DE", sourceType: "CALENDAR", countryCode: "DE", countryName: "Germany", federalState: null, metroCityName: null, }, { id: "overlay_2", resourceId: "resource_2", startDate: "2026-04-04", endDate: "2026-04-04", note: "Holiday", scope: "CITY", calendarName: "Berlin", sourceType: "CALENDAR", countryCode: "DE", countryName: "Germany", federalState: "BE", metroCityName: "Berlin", }, ], })).toEqual({ allocationCount: 1, demandCount: 1, assignmentCount: 1, projectCount: 1, resourceCount: 1, resourceIds: 2, allResourceAllocationCount: 2, conflictedAssignmentCount: 1, overlayCount: 2, holidayResourceCount: 2, byScope: [ { scope: "CITY", count: 1 }, { scope: "COUNTRY", count: 1 }, ], }); }); it("builds anonymized project context responses and detail summaries", () => { const directory = { config: { enabled: true, mode: "alias", domain: "example.test" }, byResourceId: new Map([ [ "resource_1", { displayName: "Anon Alice", eid: "ANON-001", email: "anon-alice@example.test", }, ], ]), byAliasEid: new Map([["anon-001", "resource_1"]]), }; expect(buildTimelineProjectContextResponse({ project: { id: "project_1" }, allocations: [ { id: "allocation_1", projectId: "project_1", resourceId: "resource_1", resource: { id: "resource_1", displayName: "Alice", eid: "E-001" }, }, ], demands: [{ id: "demand_1", projectId: "project_1" }], assignments: [ { id: "assignment_1", projectId: "project_1", resourceId: "resource_1", resource: { id: "resource_1", displayName: "Alice", eid: "E-001" }, }, ], allResourceAllocations: [ { id: "booking_1", resourceId: "resource_1", resource: { id: "resource_1", displayName: "Alice", eid: "E-001" }, }, ], resourceIds: ["resource_1"], directory: directory as never, })).toEqual({ project: { id: "project_1" }, allocations: [ { id: "allocation_1", projectId: "project_1", resourceId: "resource_1", resource: { id: "resource_1", displayName: "Anon Alice", eid: "ANON-001" }, }, ], demands: [{ id: "demand_1", projectId: "project_1" }], assignments: [ { id: "assignment_1", projectId: "project_1", resourceId: "resource_1", resource: { id: "resource_1", displayName: "Anon Alice", eid: "ANON-001" }, }, ], allResourceAllocations: [ { id: "booking_1", resourceId: "resource_1", resource: { id: "resource_1", displayName: "Anon Alice", eid: "ANON-001" }, }, ], resourceIds: ["resource_1"], }); expect(buildTimelineProjectContextDetailResponse({ project: { id: "project_1" }, period: { startDate: new Date("2026-04-01T00:00:00.000Z"), endDate: new Date("2026-04-05T00:00:00.000Z"), }, allocations: [ { id: "allocation_1", projectId: "project_1", resourceId: "resource_1", resource: { id: "resource_1", displayName: "Alice", eid: "E-001" }, }, ], demands: [{ id: "demand_1", projectId: "project_1" }], assignments: [ { id: "assignment_1", projectId: "project_1", resourceId: "resource_1", resource: { id: "resource_1", displayName: "Alice", eid: "E-001" }, }, ], allResourceAllocations: [ { id: "booking_1", resourceId: "resource_1", resource: { id: "resource_1", displayName: "Alice", eid: "E-001" }, }, ], resourceIds: ["resource_1"], assignmentConflicts: [{ crossProjectOverlapCount: 1, assignmentId: "assignment_1" }], holidayOverlays: [], directory: directory as never, })).toEqual({ project: { id: "project_1" }, period: { startDate: "2026-04-01", endDate: "2026-04-05", }, summary: { allocationCount: 1, demandCount: 1, assignmentCount: 1, projectCount: 1, resourceCount: 1, resourceIds: 1, allResourceAllocationCount: 1, conflictedAssignmentCount: 1, overlayCount: 0, holidayResourceCount: 0, byScope: [], }, allocations: [ { id: "allocation_1", projectId: "project_1", resourceId: "resource_1", resource: { id: "resource_1", displayName: "Anon Alice", eid: "ANON-001" }, }, ], demands: [{ id: "demand_1", projectId: "project_1" }], assignments: [ { id: "assignment_1", projectId: "project_1", resourceId: "resource_1", resource: { id: "resource_1", displayName: "Anon Alice", eid: "ANON-001" }, }, ], allResourceAllocations: [ { id: "booking_1", resourceId: "resource_1", resource: { id: "resource_1", displayName: "Anon Alice", eid: "ANON-001" }, }, ], assignmentConflicts: [{ crossProjectOverlapCount: 1, assignmentId: "assignment_1" }], holidayOverlays: [], resourceIds: ["resource_1"], }); }); });