import { beforeEach, describe, expect, it, vi } from "vitest"; const { createAuditEntry } = vi.hoisted(() => ({ createAuditEntry: vi.fn(), })); vi.mock("../lib/audit.js", () => ({ createAuditEntry, })); import { createHolidayCalendar, createHolidayCalendarEntry, deleteHolidayCalendarEntry, updateHolidayCalendar, } from "../router/holiday-calendar-procedure-support.js"; function createContext(db: Record) { return { db: db as never, dbUser: { id: "user_admin" } as never, }; } describe("holiday calendar procedure support", () => { beforeEach(() => { createAuditEntry.mockReset(); }); it("creates a holiday calendar with normalized scope and audit logging", async () => { const countryFindUnique = vi.fn().mockResolvedValue({ id: "country_de", name: "Deutschland", }); const metroCityFindUnique = vi.fn().mockResolvedValue(null); const holidayCalendarFindFirst = vi.fn().mockResolvedValue(null); const holidayCalendarCreate = vi.fn().mockResolvedValue({ id: "cal_by", name: "Bayern Feiertage", country: { id: "country_de", code: "DE", name: "Deutschland" }, metroCity: null, entries: [], }); const result = await createHolidayCalendar( createContext({ country: { findUnique: countryFindUnique }, metroCity: { findUnique: metroCityFindUnique }, holidayCalendar: { findFirst: holidayCalendarFindFirst, create: holidayCalendarCreate, }, }), { name: "Bayern Feiertage", scopeType: "STATE", countryId: "country_de", stateCode: " by ", }, ); expect(countryFindUnique).toHaveBeenCalledWith({ where: { id: "country_de" }, select: { id: true, name: true }, }); expect(holidayCalendarFindFirst).toHaveBeenCalledWith({ where: { scopeType: "STATE", countryId: "country_de", stateCode: "BY", }, select: { id: true }, }); expect(holidayCalendarCreate).toHaveBeenCalledWith({ data: { name: "Bayern Feiertage", scopeType: "STATE", countryId: "country_de", stateCode: "BY", isActive: true, priority: 0, }, include: expect.any(Object), }); expect(result.id).toBe("cal_by"); expect(createAuditEntry).toHaveBeenCalledWith( expect.objectContaining({ entityType: "HolidayCalendar", action: "CREATE", entityId: "cal_by", }), ); }); it("updates a holiday calendar with resolved partial scope values", async () => { const holidayCalendarFindUnique = vi.fn().mockResolvedValue({ id: "cal_city", name: "Augsburg lokal", scopeType: "CITY", countryId: "country_de", stateCode: null, metroCityId: "city_augsburg", }); const holidayCalendarFindFirst = vi.fn().mockResolvedValue(null); const metroCityFindUnique = vi.fn().mockResolvedValue({ id: "city_augsburg", countryId: "country_de", }); const holidayCalendarUpdate = vi.fn().mockResolvedValue({ id: "cal_city", name: "Augsburg lokal bevorzugt", stateCode: null, metroCityId: "city_augsburg", country: { id: "country_de", code: "DE", name: "Deutschland" }, metroCity: { id: "city_augsburg", name: "Augsburg" }, entries: [], }); const result = await updateHolidayCalendar( createContext({ holidayCalendar: { findUnique: holidayCalendarFindUnique, findFirst: holidayCalendarFindFirst, update: holidayCalendarUpdate, }, metroCity: { findUnique: metroCityFindUnique }, }), { id: "cal_city", data: { name: "Augsburg lokal bevorzugt", metroCityId: undefined, priority: 7, }, }, ); expect(holidayCalendarFindFirst).toHaveBeenCalledWith({ where: { scopeType: "CITY", countryId: "country_de", metroCityId: "city_augsburg", id: { not: "cal_city" }, }, select: { id: true }, }); expect(holidayCalendarUpdate).toHaveBeenCalledWith({ where: { id: "cal_city" }, data: { name: "Augsburg lokal bevorzugt", priority: 7, }, include: expect.any(Object), }); expect(result.name).toBe("Augsburg lokal bevorzugt"); expect(createAuditEntry).toHaveBeenCalledWith( expect.objectContaining({ entityType: "HolidayCalendar", action: "UPDATE", entityId: "cal_city", }), ); }); it("creates and deletes holiday-calendar entries with clamped dates", async () => { const holidayCalendarFindUnique = vi.fn().mockResolvedValue({ id: "cal_de", name: "Deutschland", }); const holidayCalendarEntryFindFirst = vi.fn().mockResolvedValue(null); const holidayCalendarEntryCreate = vi.fn().mockResolvedValue({ id: "entry_1", holidayCalendarId: "cal_de", name: "Neujahr", date: new Date("2026-01-01T00:00:00.000Z"), }); const holidayCalendarEntryFindUnique = vi.fn().mockResolvedValue({ id: "entry_1", holidayCalendarId: "cal_de", name: "Neujahr", date: new Date("2026-01-01T00:00:00.000Z"), }); const holidayCalendarEntryDelete = vi.fn().mockResolvedValue({ id: "entry_1" }); const created = await createHolidayCalendarEntry( createContext({ holidayCalendar: { findUnique: holidayCalendarFindUnique }, holidayCalendarEntry: { findFirst: holidayCalendarEntryFindFirst, create: holidayCalendarEntryCreate, }, }), { holidayCalendarId: "cal_de", name: "Neujahr", date: new Date("2026-01-01T14:30:00.000Z"), }, ); const deleted = await deleteHolidayCalendarEntry( createContext({ holidayCalendarEntry: { findUnique: holidayCalendarEntryFindUnique, delete: holidayCalendarEntryDelete, }, }), { id: "entry_1" }, ); expect(holidayCalendarEntryFindFirst).toHaveBeenCalledWith({ where: { holidayCalendarId: "cal_de", date: new Date("2026-01-01T00:00:00.000Z"), }, select: { id: true }, }); expect(holidayCalendarEntryCreate).toHaveBeenCalledWith({ data: { holidayCalendarId: "cal_de", date: new Date("2026-01-01T00:00:00.000Z"), name: "Neujahr", isRecurringAnnual: false, }, }); expect(created.id).toBe("entry_1"); expect(holidayCalendarEntryDelete).toHaveBeenCalledWith({ where: { id: "entry_1" }, }); expect(deleted).toEqual({ success: true, id: "entry_1", name: "Neujahr", }); expect(createAuditEntry).toHaveBeenCalledTimes(2); }); });