101 lines
3.2 KiB
TypeScript
101 lines
3.2 KiB
TypeScript
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");
|
|
});
|
|
});
|