import { describe, expect, it } from 'vitest'; import { formatDisplayDate, getDaysDifference, getItemUrgency, getRelativeDueDateLabel, } from '../dateUtils'; describe('dateUtils', () => { const today = '2026-10-09'; describe('getItemUrgency', () => { it('returns completed if item status is completed regardless of due date', () => { const urgency = getItemUrgency({ status: 'completed', dueDate: '2026-01-01' }, today); expect(urgency).toBe('completed'); }); it('returns no_date if dueDate is undefined or blank (Decision 29: Missing due dates allowed)', () => { expect(getItemUrgency({ status: 'active', dueDate: undefined }, today)).toBe('no_date'); expect(getItemUrgency({ status: 'active', dueDate: '' }, today)).toBe('no_date'); expect(getItemUrgency({ status: 'active', dueDate: ' ' }, today)).toBe('no_date'); }); it('returns overdue if dueDate is strictly prior to today', () => { const urgency = getItemUrgency({ status: 'active', dueDate: '2026-10-05' }, today); expect(urgency).toBe('overdue'); }); it('returns upcoming if dueDate is today or within the 30-day window', () => { expect(getItemUrgency({ status: 'active', dueDate: '2026-10-09' }, today)).toBe('upcoming'); expect(getItemUrgency({ status: 'active', dueDate: '2026-10-15' }, today)).toBe('upcoming'); expect(getItemUrgency({ status: 'active', dueDate: '2026-11-05' }, today)).toBe('upcoming'); }); it('returns normal if dueDate is beyond the 30-day upcoming window', () => { const urgency = getItemUrgency({ status: 'active', dueDate: '2026-12-01' }, today); expect(urgency).toBe('normal'); }); }); describe('getDaysDifference', () => { it('computes positive days difference for upcoming dates', () => { expect(getDaysDifference('2026-10-14', today)).toBe(5); }); it('computes negative days difference for overdue dates', () => { expect(getDaysDifference('2026-10-06', today)).toBe(-3); }); it('returns 0 for today', () => { expect(getDaysDifference('2026-10-09', today)).toBe(0); }); it('returns null for missing date', () => { expect(getDaysDifference(undefined, today)).toBeNull(); }); }); describe('formatDisplayDate and relative labels', () => { it('formats display dates nicely', () => { expect(formatDisplayDate('2026-10-09')).toBe('Oct 9, 2026'); expect(formatDisplayDate(undefined)).toBe('No due date'); }); it('returns human relative labels for overdue, today, and upcoming', () => { expect(getRelativeDueDateLabel('2026-10-05', 'active', today)).toBe('4 days overdue'); expect(getRelativeDueDateLabel('2026-10-08', 'active', today)).toBe('1 day overdue'); expect(getRelativeDueDateLabel('2026-10-09', 'active', today)).toBe('Due today'); expect(getRelativeDueDateLabel('2026-10-10', 'active', today)).toBe('Due tomorrow'); expect(getRelativeDueDateLabel('2026-10-15', 'active', today)).toBe('Due in 6 days'); expect(getRelativeDueDateLabel('2026-10-15', 'completed', today)).toBe('Completed'); }); }); });