import { describe, expect, it } from "vitest"; import { isVacationDay, getVacationDatesInRange } from "../vacation/utils.js"; import type { VacationRange } from "../vacation/utils.js"; const approved = (start: string, end: string): VacationRange => ({ startDate: new Date(start), endDate: new Date(end), status: "APPROVED", }); const pending = (start: string, end: string): VacationRange => ({ startDate: new Date(start), endDate: new Date(end), status: "PENDING", }); describe("isVacationDay", () => { it("returns true when date falls within an approved vacation", () => { const vacations = [approved("2026-03-10", "2026-03-14")]; expect(isVacationDay(new Date("2026-03-12"), vacations)).toBe(true); }); it("returns true on the start date of the vacation", () => { const vacations = [approved("2026-03-10", "2026-03-14")]; expect(isVacationDay(new Date("2026-03-10"), vacations)).toBe(true); }); it("returns true on the end date of the vacation", () => { const vacations = [approved("2026-03-10", "2026-03-14")]; expect(isVacationDay(new Date("2026-03-14"), vacations)).toBe(true); }); it("returns false when date is outside vacation range", () => { const vacations = [approved("2026-03-10", "2026-03-14")]; expect(isVacationDay(new Date("2026-03-09"), vacations)).toBe(false); expect(isVacationDay(new Date("2026-03-15"), vacations)).toBe(false); }); it("ignores non-APPROVED vacations", () => { const vacations = [pending("2026-03-10", "2026-03-14")]; expect(isVacationDay(new Date("2026-03-12"), vacations)).toBe(false); }); it("returns false for empty vacation array", () => { expect(isVacationDay(new Date("2026-03-12"), [])).toBe(false); }); it("handles multiple overlapping vacations", () => { const vacations = [ approved("2026-03-10", "2026-03-12"), approved("2026-03-11", "2026-03-14"), ]; expect(isVacationDay(new Date("2026-03-11"), vacations)).toBe(true); expect(isVacationDay(new Date("2026-03-13"), vacations)).toBe(true); }); it("handles mixed statuses correctly", () => { const vacations = [ pending("2026-03-10", "2026-03-14"), approved("2026-03-20", "2026-03-21"), ]; expect(isVacationDay(new Date("2026-03-12"), vacations)).toBe(false); expect(isVacationDay(new Date("2026-03-20"), vacations)).toBe(true); }); }); describe("getVacationDatesInRange", () => { it("returns approved vacation dates within range", () => { const vacations = [approved("2026-03-10", "2026-03-12")]; const dates = getVacationDatesInRange( new Date("2026-03-09"), new Date("2026-03-13"), vacations, ); expect(dates).toHaveLength(3); // 10, 11, 12 expect(dates[0]!.getDate()).toBe(10); expect(dates[2]!.getDate()).toBe(12); }); it("clips to the query range", () => { const vacations = [approved("2026-03-05", "2026-03-15")]; const dates = getVacationDatesInRange( new Date("2026-03-10"), new Date("2026-03-12"), vacations, ); expect(dates).toHaveLength(3); // 10, 11, 12 }); it("returns empty for no approved vacations", () => { const vacations = [pending("2026-03-10", "2026-03-14")]; const dates = getVacationDatesInRange( new Date("2026-03-01"), new Date("2026-03-31"), vacations, ); expect(dates).toEqual([]); }); it("handles multiple non-overlapping vacations", () => { const vacations = [ approved("2026-03-10", "2026-03-11"), approved("2026-03-20", "2026-03-21"), ]; const dates = getVacationDatesInRange( new Date("2026-03-01"), new Date("2026-03-31"), vacations, ); expect(dates).toHaveLength(4); // 10, 11, 20, 21 }); it("returns empty when range does not intersect vacations", () => { const vacations = [approved("2026-04-01", "2026-04-05")]; const dates = getVacationDatesInRange( new Date("2026-03-01"), new Date("2026-03-31"), vacations, ); expect(dates).toEqual([]); }); });