import { DEFAULT_SEASON_AUTOPILOT_CONFIG } from '../automation/rule-config/season-autopilot.config'; import { varroaMeasurementDue } from './varroa-due'; const CONFIG = DEFAULT_SEASON_AUTOPILOT_CONFIG; const SOMMER = { segment: 'SOMMER', springSince: '2026-03-20' } as const; const WINTERRUHE = { segment: 'WINTERRUHE', springSince: '2026-03-20', } as const; const NEVER_MEASURED = { createdOn: '2025-01-01', lastMeasuredOn: null, lastMeasurementId: null, }; describe('varroaMeasurementDue', () => { it('is due 28 days after the last measurement outside WINTERRUHE', () => expect( varroaMeasurementDue( { createdOn: '2025-01-01', lastMeasuredOn: '2026-06-01', lastMeasurementId: 'm-1', }, SOMMER, CONFIG, '2026-06-30', ), ).toEqual({ dueOn: '2026-06-29', kind: 'INTERVAL', anchor: 'm-1' })); it('counts from createdOn without a measurement and anchors on none', () => expect( varroaMeasurementDue( { ...NEVER_MEASURED, createdOn: '2026-04-20' }, SOMMER, CONFIG, '2026-06-30', ), ).toEqual({ dueOn: '2026-05-18', kind: 'INTERVAL', anchor: 'none' })); it('uses the configured interval', () => expect( varroaMeasurementDue( { ...NEVER_MEASURED, createdOn: '2026-04-20' }, SOMMER, { ...CONFIG, varroaMeasureIntervalDays: 14 }, '2026-06-30', ), ).toMatchObject({ dueOn: '2026-05-04' })); it('is due on 11-15 in the winter window without a measurement since 11-01', () => expect( varroaMeasurementDue( { createdOn: '2025-01-01', lastMeasuredOn: '2026-09-20', lastMeasurementId: 'm-1', }, WINTERRUHE, CONFIG, '2026-11-20', ), ).toEqual({ dueOn: '2026-11-15', kind: 'WINTER_WINDOW', anchor: 'winter-2026', })); it('is not due in the winter window after a measurement since 11-01', () => expect( varroaMeasurementDue( { createdOn: '2025-01-01', lastMeasuredOn: '2026-11-03', lastMeasurementId: 'm-2', }, WINTERRUHE, CONFIG, '2026-11-20', ), ).toBeNull()); it('is not due in WINTERRUHE outside the winter window', () => { expect( varroaMeasurementDue(NEVER_MEASURED, WINTERRUHE, CONFIG, '2026-12-21'), ).toBeNull(); expect( varroaMeasurementDue(NEVER_MEASURED, WINTERRUHE, CONFIG, '2026-02-10'), ).toBeNull(); }); it('opens the winter window on its first and last day', () => { expect( varroaMeasurementDue(NEVER_MEASURED, WINTERRUHE, CONFIG, '2026-11-15'), ).toMatchObject({ kind: 'WINTER_WINDOW' }); expect( varroaMeasurementDue(NEVER_MEASURED, WINTERRUHE, CONFIG, '2026-12-20'), ).toMatchObject({ kind: 'WINTER_WINDOW' }); }); it('moves an interval due day inside the winter to the start of FRUEHJAHR', () => expect( varroaMeasurementDue( { createdOn: '2025-01-01', lastMeasuredOn: '2026-11-20', lastMeasurementId: 'm-3', }, { segment: 'FRUEHJAHR', springSince: '2027-03-20' }, CONFIG, '2027-03-25', ), ).toEqual({ dueOn: '2027-03-20', kind: 'INTERVAL', anchor: 'm-3' })); it('keeps a due day after the start of FRUEHJAHR', () => expect( varroaMeasurementDue( { createdOn: '2025-01-01', lastMeasuredOn: '2027-03-10', lastMeasurementId: 'm-4', }, { segment: 'FRUEHJAHR', springSince: '2027-03-20' }, CONFIG, '2027-04-01', ), ).toMatchObject({ dueOn: '2027-04-07' })); });