import { describe, expect, it, vi, beforeEach, afterEach } from "vitest"; import { BOARD_WINDOW_DAYS_BACK, BOARD_WINDOW_DAYS_FORWARD, SCHEDULE_WINDOW_DAYS_BACK, SCHEDULE_WINDOW_DAYS_FORWARD, MAP_WINDOW_DAYS_BACK, MAP_WINDOW_MONTHS_FORWARD, isInBoardWindow, isInScheduleWindow, isInMapWindow, boardWindowBounds, scheduleWindowBounds, mapWindowBounds, } from "./dateWindow.js"; describe("dateWindow constants", () => { it("exports the TZ-defined numerical bounds", () => { expect(BOARD_WINDOW_DAYS_BACK).toBe(1); expect(BOARD_WINDOW_DAYS_FORWARD).toBe(14); expect(SCHEDULE_WINDOW_DAYS_BACK).toBe(1); expect(SCHEDULE_WINDOW_DAYS_FORWARD).toBe(330); expect(MAP_WINDOW_DAYS_BACK).toBe(1); expect(MAP_WINDOW_MONTHS_FORWARD).toBe(6); }); }); describe("dateWindow helpers (clock frozen at 2026-05-15)", () => { beforeEach(() => { vi.useFakeTimers(); vi.setSystemTime(new Date(2026, 4, 15, 12, 0, 0)); // May 15, 2026 noon local time }); afterEach(() => { vi.useRealTimers(); }); // Helper to format date as YYYY-MM-DD for comparison function toYmd(d: Date): string { return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, "0")}-${String(d.getDate()).padStart(2, "0")}`; } describe("4.1.2-R12: isInBoardWindow (-1/+14 days)", () => { it("accepts today (yyyyMMdd)", () => { expect(isInBoardWindow("20260515")).toBe(true); }); it("accepts yesterday (-1 day)", () => { expect(isInBoardWindow("20260514")).toBe(true); }); it("rejects -2 days", () => { expect(isInBoardWindow("20260513")).toBe(false); }); it("accepts today + 14 days", () => { expect(isInBoardWindow("20260529")).toBe(true); }); it("rejects today + 15 days", () => { expect(isInBoardWindow("20260530")).toBe(false); }); it("rejects malformed input", () => { expect(isInBoardWindow("")).toBe(false); expect(isInBoardWindow("2026-05-15")).toBe(false); expect(isInBoardWindow("20269999")).toBe(false); }); }); describe("4.1.2-R12: isInScheduleWindow (-1/+330 days)", () => { it("accepts today + 330 days", () => { expect(isInScheduleWindow("20270410")).toBe(true); }); it("rejects today + 331 days", () => { expect(isInScheduleWindow("20270411")).toBe(false); }); it("rejects -2 days", () => { expect(isInScheduleWindow("20260513")).toBe(false); }); }); describe("4.1.2-R12: isInMapWindow (-1 day / +6 months)", () => { it("accepts today + 6 months (same calendar day)", () => { expect(isInMapWindow("20261115")).toBe(true); }); it("rejects today + 6 months + 1 day", () => { expect(isInMapWindow("20261116")).toBe(false); }); it("rejects -2 days", () => { expect(isInMapWindow("20260513")).toBe(false); }); }); it("exposes bounds tuples for UI consumers", () => { const [bMin, bMax] = boardWindowBounds(); expect(toYmd(bMin)).toBe("2026-05-14"); expect(toYmd(bMax)).toBe("2026-05-29"); const [sMin, sMax] = scheduleWindowBounds(); expect(toYmd(sMin)).toBe("2026-05-14"); expect(toYmd(sMax)).toBe("2027-04-10"); const [mMin, mMax] = mapWindowBounds(); expect(toYmd(mMin)).toBe("2026-05-14"); expect(toYmd(mMax)).toBe("2026-11-15"); }); });