import { beforeEach, describe, expect, it, vi } from "vitest"; vi.mock("../router/timeline-read-shared.js", () => ({ buildSelfServiceTimelineInput: vi.fn(), buildTimelineEntriesDetailInput: vi.fn(), })); vi.mock("../router/timeline-holiday-load-support.js", () => ({ loadTimelineHolidayOverlays: vi.fn(), })); vi.mock("../router/timeline-holiday-support.js", () => ({ buildTimelineHolidayOverlayDetailResponse: vi.fn(), formatTimelineHolidayOverlays: vi.fn(), })); import { buildSelfServiceTimelineInput, buildTimelineEntriesDetailInput, } from "../router/timeline-read-shared.js"; import { loadTimelineHolidayOverlays } from "../router/timeline-holiday-load-support.js"; import { buildTimelineHolidayOverlayDetailResponse, formatTimelineHolidayOverlays, } from "../router/timeline-holiday-support.js"; import { readMyTimelineHolidayOverlays, readTimelineHolidayOverlayDetail, } from "../router/timeline-holiday-procedure-support.js"; const buildSelfServiceTimelineInputMock = vi.mocked(buildSelfServiceTimelineInput); const buildTimelineEntriesDetailInputMock = vi.mocked(buildTimelineEntriesDetailInput); const loadTimelineHolidayOverlaysMock = vi.mocked(loadTimelineHolidayOverlays); const buildTimelineHolidayOverlayDetailResponseMock = vi.mocked(buildTimelineHolidayOverlayDetailResponse); const formatTimelineHolidayOverlaysMock = vi.mocked(formatTimelineHolidayOverlays); describe("timeline holiday procedure support", () => { beforeEach(() => { vi.clearAllMocks(); }); it("returns an empty list when self-service scope cannot be resolved", async () => { buildSelfServiceTimelineInputMock.mockResolvedValueOnce(null); await expect( readMyTimelineHolidayOverlays( { db: {}, dbUser: { id: "user_1" } } as never, { startDate: new Date("2026-04-01T00:00:00.000Z"), endDate: new Date("2026-04-07T00:00:00.000Z"), }, ), ).resolves.toEqual([]); expect(loadTimelineHolidayOverlaysMock).not.toHaveBeenCalled(); }); it("loads self-service holiday overlays when a scope is available", async () => { const ctx = { db: {}, dbUser: { id: "user_1" } } as never; const input = { startDate: new Date("2026-04-01T00:00:00.000Z"), endDate: new Date("2026-04-07T00:00:00.000Z"), }; const selfServiceInput = { startDate: new Date("2026-04-01T00:00:00.000Z"), endDate: new Date("2026-04-07T00:00:00.000Z"), resourceIds: ["resource_1"], }; buildSelfServiceTimelineInputMock.mockResolvedValueOnce(selfServiceInput as never); loadTimelineHolidayOverlaysMock.mockResolvedValueOnce([{ id: "overlay_1" }] as never); await expect(readMyTimelineHolidayOverlays(ctx, input)).resolves.toEqual([{ id: "overlay_1" }]); expect(buildSelfServiceTimelineInputMock).toHaveBeenCalledWith(ctx, input); expect(loadTimelineHolidayOverlaysMock).toHaveBeenCalledWith(ctx.db, selfServiceInput); }); it("builds holiday overlay detail responses from resolved detail inputs", async () => { buildTimelineEntriesDetailInputMock.mockReturnValueOnce({ period: { startDate: new Date("2026-04-01T00:00:00.000Z"), endDate: new Date("2026-04-07T00:00:00.000Z"), }, filters: { countryCodes: ["DE"] }, timelineInput: { startDate: new Date("2026-04-01T00:00:00.000Z"), endDate: new Date("2026-04-07T00:00:00.000Z"), countryCodes: ["DE"], }, } as never); loadTimelineHolidayOverlaysMock.mockResolvedValueOnce([{ id: "overlay_1" }] as never); formatTimelineHolidayOverlaysMock.mockReturnValueOnce([{ id: "formatted_1" }] as never); buildTimelineHolidayOverlayDetailResponseMock.mockReturnValueOnce({ detail: true } as never); await expect( readTimelineHolidayOverlayDetail({} as never, { startDate: "2026-04-01", endDate: "2026-04-07", countryCodes: ["DE"], }), ).resolves.toEqual({ detail: true }); expect(loadTimelineHolidayOverlaysMock).toHaveBeenCalledWith({}, { startDate: new Date("2026-04-01T00:00:00.000Z"), endDate: new Date("2026-04-07T00:00:00.000Z"), countryCodes: ["DE"], }); expect(formatTimelineHolidayOverlaysMock).toHaveBeenCalledWith([{ id: "overlay_1" }]); expect(buildTimelineHolidayOverlayDetailResponseMock).toHaveBeenCalledWith({ startDate: new Date("2026-04-01T00:00:00.000Z"), endDate: new Date("2026-04-07T00:00:00.000Z"), filters: { countryCodes: ["DE"] }, overlays: [{ id: "formatted_1" }], }); }); });