import { describe, expect, it } from 'vitest'; import { parsePreviewTime, PREVIEW_RANGE_DAYS } from './preview-time'; const NOW = new Date('2026-09-23T08:00:00Z'); describe('parsePreviewTime', () => { it('defaults to now when nothing is asked for', () => { expect(parsePreviewTime(null, NOW)).toEqual({ at: NOW, isNow: true }); }); it('accepts a moment in the future', () => { const result = parsePreviewTime('2026-09-24T08:00:00Z', NOW); expect(result.at.toISOString()).toBe('2026-09-24T08:00:00.000Z'); expect(result.isNow).toBe(false); }); it('accepts a local datetime as a browser sends it', () => { // has no timezone; it is read as local time. expect(parsePreviewTime('2026-12-24T10:00', NOW).at.getFullYear()).toBe(2026); }); it('accepts a moment in the past', () => { expect(parsePreviewTime('2026-09-20T08:00:00Z', NOW).isNow).toBe(false); }); it('falls back to now on an unparseable value', () => { // Better a correct screen than a confident rendering of nonsense. expect(parsePreviewTime('demain matin', NOW)).toEqual({ at: NOW, isNow: true }); expect(parsePreviewTime('', NOW)).toEqual({ at: NOW, isNow: true }); }); it('refuses a moment beyond the planning horizon', () => { const far = new Date(NOW.getTime() + (PREVIEW_RANGE_DAYS + 1) * 86_400_000); expect(parsePreviewTime(far.toISOString(), NOW).isNow).toBe(true); }); it('accepts a moment just inside the horizon', () => { const edge = new Date(NOW.getTime() + (PREVIEW_RANGE_DAYS - 1) * 86_400_000); expect(parsePreviewTime(edge.toISOString(), NOW).isNow).toBe(false); }); it('treats a moment within the minute as now', () => { const almost = new Date(NOW.getTime() + 30_000); expect(parsePreviewTime(almost.toISOString(), NOW).isNow).toBe(true); }); });