diff --git a/apps/api/tests/broker/reminderScheduler.test.ts b/apps/api/tests/broker/reminderScheduler.test.ts index fc756c0..293f6ec 100644 --- a/apps/api/tests/broker/reminderScheduler.test.ts +++ b/apps/api/tests/broker/reminderScheduler.test.ts @@ -855,3 +855,52 @@ describe('reminderScheduler — T-05-19: per-subscription error isolation', () = expect(vi.mocked(dispatchPush).mock.calls.length).toBe(2); // both attempted }); }); + +// ── CR-02: all-day-aware push body (Phase 11 Plan 05) ──────────────────────── + +describe('humanizeLeadMinutes — CR-02 all-day-aware push body', () => { + // CR-02: humanizeLeadMinutes(0) produces "Starts in 0 min" for timed events, + // but for all-day same-day events (lead=0) the correct body is "Today". + // The function must accept an isAllDay flag to return sensible all-day wording. + // These tests MUST FAIL before the fix — humanizeLeadMinutes takes only one arg. + + it('CR-02: all-day same-day (lead=0) body is NOT "Starts in 0 min" (isAllDay=true)', async () => { + const { humanizeLeadMinutes } = await import('../../src/broker/reminderScheduler.js'); + // Before fix: humanizeLeadMinutes(0) → 'Starts in 0 min' (wrong for all-day same-day) + // After fix: humanizeLeadMinutes(0, true) → 'Today' + expect(humanizeLeadMinutes(0, true)).not.toBe('Starts in 0 min'); + }); + + it('CR-02: all-day same-day (lead=0, isAllDay=true) body is "Today"', async () => { + const { humanizeLeadMinutes } = await import('../../src/broker/reminderScheduler.js'); + expect(humanizeLeadMinutes(0, true)).toBe('Today'); + }); + + it('CR-02: all-day 1-day lead (1440 min, isAllDay=true) body is "Tomorrow"', async () => { + const { humanizeLeadMinutes } = await import('../../src/broker/reminderScheduler.js'); + expect(humanizeLeadMinutes(1440, true)).toBe('Tomorrow'); + }); + + it('CR-02: all-day 2-day lead (2880 min, isAllDay=true) body is "In 2 days"', async () => { + const { humanizeLeadMinutes } = await import('../../src/broker/reminderScheduler.js'); + expect(humanizeLeadMinutes(2880, true)).toBe('In 2 days'); + }); + + it('CR-02: all-day 1-week lead (10080 min, isAllDay=true) body is "In 1 week"', async () => { + const { humanizeLeadMinutes } = await import('../../src/broker/reminderScheduler.js'); + expect(humanizeLeadMinutes(10080, true)).toBe('In 1 week'); + }); + + it('CR-02: timed event body unchanged — humanizeLeadMinutes(0, false) is "Starts in 0 min"', async () => { + const { humanizeLeadMinutes } = await import('../../src/broker/reminderScheduler.js'); + // Timed event 0-lead: treated as None by the scheduler, but the formatter + // should still return the existing "Starts in 0 min" for completeness + expect(humanizeLeadMinutes(0, false)).toBe('Starts in 0 min'); + }); + + it('CR-02: timed event body unchanged — humanizeLeadMinutes(30) still "Starts in 30 min"', async () => { + const { humanizeLeadMinutes } = await import('../../src/broker/reminderScheduler.js'); + // Default isAllDay=false: existing timed behavior must be unchanged + expect(humanizeLeadMinutes(30)).toBe('Starts in 30 min'); + }); +});