import { describe, it, expect } from 'vitest' import { isWithinSchedule } from '../../../app/utils/schedule_window.js' import type { ScheduleWindow } from '../../../app/domain/configuration/configuration.js' describe('isWithinSchedule', () => { it('returns true when schedule is undefined', () => { expect(isWithinSchedule(undefined)).toBe(true) }) it('returns true when within a normal window (non-midnight-spanning)', () => { const schedule: ScheduleWindow = { daysOfWeek: [1, 2, 3, 4, 5], // Mon-Fri startHour: 2, endHour: 6, timezone: 'UTC', } // Wednesday at 03:00 UTC const now = new Date('2025-01-08T03:00:00Z') expect(isWithinSchedule(schedule, now)).toBe(true) }) it('returns false when outside a normal window', () => { const schedule: ScheduleWindow = { daysOfWeek: [1, 2, 3, 4, 5], startHour: 2, endHour: 6, timezone: 'UTC', } // Wednesday at 10:00 UTC const now = new Date('2025-01-08T10:00:00Z') expect(isWithinSchedule(schedule, now)).toBe(false) }) it('returns false when at the endHour boundary (exclusive)', () => { const schedule: ScheduleWindow = { daysOfWeek: [1, 2, 3, 4, 5], startHour: 2, endHour: 6, timezone: 'UTC', } // Wednesday at 06:00 UTC (endHour is exclusive) const now = new Date('2025-01-08T06:00:00Z') expect(isWithinSchedule(schedule, now)).toBe(false) }) it('handles midnight-spanning window (startHour > endHour)', () => { const schedule: ScheduleWindow = { daysOfWeek: [0, 1, 2, 3, 4, 5, 6], startHour: 22, endHour: 6, timezone: 'UTC', } // At 23:00 UTC - should be within expect(isWithinSchedule(schedule, new Date('2025-01-08T23:00:00Z'))).toBe(true) // At 03:00 UTC - should be within expect(isWithinSchedule(schedule, new Date('2025-01-08T03:00:00Z'))).toBe(true) // At 10:00 UTC - should be outside expect(isWithinSchedule(schedule, new Date('2025-01-08T10:00:00Z'))).toBe(false) }) it('filters by day of week', () => { const schedule: ScheduleWindow = { daysOfWeek: [1, 2, 3, 4, 5], // Mon-Fri only startHour: 0, endHour: 23, timezone: 'UTC', } // Saturday 2025-01-11 at 10:00 UTC const saturday = new Date('2025-01-11T10:00:00Z') expect(isWithinSchedule(schedule, saturday)).toBe(false) // Monday 2025-01-06 at 10:00 UTC const monday = new Date('2025-01-06T10:00:00Z') expect(isWithinSchedule(schedule, monday)).toBe(true) }) it('handles IANA timezone conversion', () => { const schedule: ScheduleWindow = { daysOfWeek: [0, 1, 2, 3, 4, 5, 6], startHour: 2, endHour: 6, timezone: 'Europe/Paris', // UTC+1 in winter } // 03:00 UTC = 04:00 Paris time → within [2, 6) expect(isWithinSchedule(schedule, new Date('2025-01-08T03:00:00Z'))).toBe(true) // 00:00 UTC = 01:00 Paris time → outside [2, 6) expect(isWithinSchedule(schedule, new Date('2025-01-08T00:00:00Z'))).toBe(false) }) it('returns true when daysOfWeek is empty (no day restriction)', () => { const schedule: ScheduleWindow = { daysOfWeek: [], startHour: 2, endHour: 6, timezone: 'UTC', } // Any day at 03:00 UTC expect(isWithinSchedule(schedule, new Date('2025-01-08T03:00:00Z'))).toBe(true) }) })