Files
CapaKraken/packages/engine/src/__tests__/vacation-utils.test.ts
T

123 lines
4.0 KiB
TypeScript

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([]);
});
});