import { describe, expect, it } from "vitest"; import { calculateAllocation, calculateTotalCost, countWorkingDays, isWorkday, } from "../allocation/calculator.js"; const stdAvailability = { monday: 8, tuesday: 8, wednesday: 8, thursday: 8, friday: 8, }; describe("isWorkday", () => { it("returns true for Monday", () => { expect(isWorkday(new Date("2025-01-06"), stdAvailability)).toBe(true); // Monday }); it("returns false for Saturday", () => { expect(isWorkday(new Date("2025-01-04"), stdAvailability)).toBe(false); // Saturday }); it("returns false for Sunday", () => { expect(isWorkday(new Date("2025-01-05"), stdAvailability)).toBe(false); // Sunday }); }); describe("countWorkingDays", () => { it("counts 5 days in a Mon-Fri week", () => { const start = new Date("2025-01-06"); // Monday const end = new Date("2025-01-10"); // Friday expect(countWorkingDays(start, end, stdAvailability)).toBe(5); }); it("counts 10 days over two Mon-Fri weeks", () => { const start = new Date("2025-01-06"); // Monday const end = new Date("2025-01-17"); // Friday expect(countWorkingDays(start, end, stdAvailability)).toBe(10); }); it("counts 0 for a weekend-only range", () => { const start = new Date("2025-01-04"); // Saturday const end = new Date("2025-01-05"); // Sunday expect(countWorkingDays(start, end, stdAvailability)).toBe(0); }); it("counts same day as 1 if it's a workday", () => { const day = new Date("2025-01-06"); // Monday expect(countWorkingDays(day, day, stdAvailability)).toBe(1); }); }); describe("calculateAllocation", () => { it("calculates cost for a full week at 8h/day and 100 EUR/h (10000 cents)", () => { const result = calculateAllocation({ lcrCents: 10000, // 100 EUR/h hoursPerDay: 8, startDate: new Date("2025-01-06"), // Monday endDate: new Date("2025-01-10"), // Friday availability: stdAvailability, }); expect(result.workingDays).toBe(5); expect(result.totalHours).toBe(40); // 5 days × 8h × 10000 cents/h = 400000 cents = 4000 EUR expect(result.totalCostCents).toBe(400000); expect(result.dailyCostCents).toBe(80000); expect(result.dailyBreakdown).toHaveLength(5); }); it("skips weekend days in breakdown", () => { const result = calculateAllocation({ lcrCents: 10000, hoursPerDay: 8, startDate: new Date("2025-01-04"), // Saturday endDate: new Date("2025-01-12"), // Sunday availability: stdAvailability, }); expect(result.workingDays).toBe(5); const weekendDays = result.dailyBreakdown.filter((d) => !d.isWorkday); expect(weekendDays).toHaveLength(4); // 2 weekends }); it("caps hours at available hours if requested > available", () => { const limitedAvailability = { ...stdAvailability, monday: 4 }; const result = calculateAllocation({ lcrCents: 10000, hoursPerDay: 8, // Requested more than available startDate: new Date("2025-01-06"), // Monday only endDate: new Date("2025-01-06"), availability: limitedAvailability, }); expect(result.totalHours).toBe(4); // Capped at availability expect(result.totalCostCents).toBe(40000); // 4h × 10000 cents }); it("returns zero for date range with no working days", () => { const result = calculateAllocation({ lcrCents: 10000, hoursPerDay: 8, startDate: new Date("2025-01-04"), // Saturday endDate: new Date("2025-01-05"), // Sunday availability: stdAvailability, }); expect(result.workingDays).toBe(0); expect(result.totalHours).toBe(0); expect(result.totalCostCents).toBe(0); }); }); describe("calculateTotalCost", () => { it("calculates correctly", () => { // 10000 cents/h × 8h × 5 days = 400000 cents expect(calculateTotalCost(10000, 8, 5)).toBe(400000); }); it("returns 0 for 0 working days", () => { expect(calculateTotalCost(10000, 8, 0)).toBe(0); }); });