test(11-05): RED — WR-01 positive-duration TRIGGER classifies as custom

4 new tests in classifyValarms suite asserting TRIGGER:+PT15M and TRIGGER:PT30M
(positive/no-sign = fires after event) classify as {kind:'custom'}, not as
preset/offlist. Negative triggers regression guards also present.
2 tests FAIL (RED): Math.abs() discards the sign, misclassifies as preset.
This commit is contained in:
Lucas Berger
2026-06-14 08:15:06 -04:00
parent 16ac235476
commit d18aba7816
+40
View File
@@ -464,3 +464,43 @@ describe('computeAlertInstantUtc', () => {
expect(result.toISOString()).toBe('2026-11-01T14:00:00.000Z');
});
});
// ─── Phase 11 Plan 05 WR-01: positive-duration TRIGGER classifies as custom ──
describe('classifyValarms — WR-01: positive-duration trigger (fires after event)', () => {
// RFC 5545 allows TRIGGER:+PT15M — fires 15 min AFTER event start.
// Before the fix: Math.abs() discards the sign and classifies it as preset/offlist 15.
// After the fix: positive duration → {kind:'custom'} (preserve as-is).
it('WR-01: TRIGGER:+PT15M classifies as custom, NOT preset', () => {
// TRIGGER:+PT15M is a post-event alarm; must not be mis-read as a 15-min-before lead.
// This test MUST FAIL before the fix.
const ics = makeIcs(
'BEGIN:VALARM\r\nTRIGGER;RELATED=END:PT15M\r\nACTION:DISPLAY\r\nDESCRIPTION:Reminder\r\nEND:VALARM',
);
expect(classifyValarms(ics)).toEqual({ kind: 'custom' });
});
it('WR-01: TRIGGER:+PT30M classifies as custom, NOT offlist', () => {
// 30 min is in PRESET_MINUTES — without the sign check, Math.abs would give preset/30.
const ics = makeIcs(
'BEGIN:VALARM\r\nTRIGGER:PT30M\r\nACTION:DISPLAY\r\nDESCRIPTION:Reminder\r\nEND:VALARM',
);
expect(classifyValarms(ics)).toEqual({ kind: 'custom' });
});
it('WR-01: negative TRIGGER:-PT15M still classifies as preset (unchanged behavior)', () => {
// Regression guard: negative triggers must not be affected by the fix.
const ics = makeIcs(
'BEGIN:VALARM\r\nTRIGGER:-PT15M\r\nACTION:DISPLAY\r\nDESCRIPTION:Reminder\r\nEND:VALARM',
);
expect(classifyValarms(ics)).toEqual({ kind: 'preset', leadMinutes: 15 });
});
it('WR-01: negative off-list TRIGGER:-PT45M still classifies as offlist', () => {
const ics = makeIcs(
'BEGIN:VALARM\r\nTRIGGER:-PT45M\r\nACTION:DISPLAY\r\nDESCRIPTION:Reminder\r\nEND:VALARM',
);
expect(classifyValarms(ics)).toEqual({ kind: 'offlist', leadMinutes: 45 });
});
});