import { describe, expect, it } from "vitest"; import { isQuietMinute, isQuietTime, localDateAndMinute } from "./quiet-hours.js"; const minute = (clock: string) => { const [hour, min] = clock.split(":").map(Number); return hour! * 60 + min!; }; describe("quiet hours", () => { it("covers a same-day range with an inclusive start and an exclusive end", () => { const lunch = { start: minute("12:00"), end: minute("13:30") }; expect(isQuietMinute(lunch, minute("11:59"))).toBe(false); expect(isQuietMinute(lunch, minute("12:00"))).toBe(true); expect(isQuietMinute(lunch, minute("13:29"))).toBe(true); expect(isQuietMinute(lunch, minute("13:30"))).toBe(false); }); it("covers a range that crosses midnight", () => { const night = { start: minute("22:00"), end: minute("07:00") }; expect(isQuietMinute(night, minute("21:59"))).toBe(false); expect(isQuietMinute(night, minute("22:00"))).toBe(true); expect(isQuietMinute(night, minute("23:59"))).toBe(true); expect(isQuietMinute(night, minute("00:00"))).toBe(true); expect(isQuietMinute(night, minute("06:59"))).toBe(true); expect(isQuietMinute(night, minute("07:00"))).toBe(false); expect(isQuietMinute(night, minute("12:00"))).toBe(false); }); it("is never quiet without a range or with an empty one", () => { expect(isQuietMinute(null, minute("03:00"))).toBe(false); expect(isQuietMinute({ start: 300, end: 300 }, 300)).toBe(false); }); it("reads the wall clock in the user's time zone", () => { // 21:30 UTC is 23:30 in Vienna (CEST, UTC+2) and 14:30 in Los Angeles (PDT, UTC-7). const now = new Date("2026-07-01T21:30:00Z"); const night = { start: minute("22:00"), end: minute("07:00") }; expect(isQuietTime(night, "Europe/Vienna", now)).toBe(true); expect(isQuietTime(night, "America/Los_Angeles", now)).toBe(false); expect(isQuietTime(night, null, now)).toBe(false); }); it("falls back to UTC for an unknown zone and reports the local date", () => { const now = new Date("2026-01-31T23:15:00Z"); expect(localDateAndMinute(now, "Not/AZone")).toEqual({ date: "2026-01-31", minute: minute("23:15"), }); // Already the next day in Tokyo (UTC+9). expect(localDateAndMinute(now, "Asia/Tokyo")).toEqual({ date: "2026-02-01", minute: minute("08:15"), }); }); it("follows daylight saving changes", () => { const night = { start: minute("22:00"), end: minute("07:00") }; // 05:30 UTC is 06:30 in Vienna in winter (CET) and 07:30 in summer (CEST). expect(isQuietTime(night, "Europe/Vienna", new Date("2026-01-15T05:30:00Z"))).toBe(true); expect(isQuietTime(night, "Europe/Vienna", new Date("2026-07-15T05:30:00Z"))).toBe(false); }); });