import { describe, expect, it } from 'vitest'; import { humanDuration, isStale, scheduleIntervalMs } from './schedule.js'; const H = 3600_000; const D = 24 * H; describe('scheduleIntervalMs', () => { it('classifies the manifest schedules', () => { expect(scheduleIntervalMs('0 2 * * *')).toBe(D); // civic daily expect(scheduleIntervalMs('30 2 * * *')).toBe(D); // clinicaltrials daily expect(scheduleIntervalMs('0 5 * * 2')).toBe(7 * D); // clinvar / hgnc weekly expect(scheduleIntervalMs('0 3 1 * *')).toBe(31 * D); // ncit-evs monthly expect(scheduleIntervalMs('0 7 1 7 *')).toBe(31 * D); // cdc-uscs yearly → treated as monthly floor expect(scheduleIntervalMs('15 * * * *')).toBe(H); // health probe hourly expect(scheduleIntervalMs('*/10 * * * *')).toBe(10 * 60_000); expect(scheduleIntervalMs('0 */6 * * *')).toBe(6 * H); expect(scheduleIntervalMs('0 2,14 * * *')).toBe(12 * H); expect(scheduleIntervalMs('0 4 * * 1,4')).toBe(3.5 * D); }); it('returns null for malformed / missing expressions', () => { expect(scheduleIntervalMs(undefined)).toBeNull(); expect(scheduleIntervalMs('')).toBeNull(); expect(scheduleIntervalMs('0 6 15 1,7 * *')).toBeNull(); // 6 fields }); }); describe('isStale', () => { const now = Date.parse('2026-09-08T12:00:00Z'); it('flags no success within 2× the interval', () => { expect(isStale(new Date(now - 1.5 * D), '0 2 * * *', now).stale).toBe(false); expect(isStale(new Date(now - 2.5 * D), '0 2 * * *', now).stale).toBe(true); expect(isStale(new Date(now - 10 * D), '0 5 * * 2', now).stale).toBe(false); expect(isStale(new Date(now - 15 * D), '0 5 * * 2', now).stale).toBe(true); }); it('never-succeeded scheduled connectors are stale; unscheduled ones never are', () => { expect(isStale(null, '0 2 * * *', now)).toMatchObject({ stale: true, ageMs: null, limitMs: 2 * D }); expect(isStale(null, undefined, now).stale).toBe(false); expect(isStale(new Date(now - 100 * D), null, now).stale).toBe(false); }); }); describe('humanDuration', () => { it('formats', () => { expect(humanDuration(30_000)).toBe('30 s'); expect(humanDuration(5 * 60_000)).toBe('5 min'); expect(humanDuration(3 * H + 5 * 60_000)).toBe('3 h 5 min'); expect(humanDuration(3 * D + 2 * H)).toBe('3 d 2 h'); expect(humanDuration(null)).toBe('-'); }); });