diff options
| author | Danilo M. <danix@danix.xyz> | 2026-09-27 19:53:54 +0200 |
|---|---|---|
| committer | Danilo M. <danix@danix.xyz> | 2026-09-27 19:53:54 +0200 |
| commit | 608a449d5d98a3e8bba624f8e3546516b2a8f998 (patch) | |
| tree | 807534678ac9fc13b0a4645cc4fe885a87851874 /test_cal_notif.py | |
| parent | db9a7a2dc1e35991c6410a1cef1ddad1c0b3c155 (diff) | |
| download | cal-notif-608a449d5d98a3e8bba624f8e3546516b2a8f998.tar.gz cal-notif-608a449d5d98a3e8bba624f8e3546516b2a8f998.zip | |
Expand calendar events: RRULE, EXDATE, RECURRENCE-ID, all-day, VALARM
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'test_cal_notif.py')
| -rw-r--r-- | test_cal_notif.py | 67 |
1 files changed, 67 insertions, 0 deletions
diff --git a/test_cal_notif.py b/test_cal_notif.py index 27f60ba..2237dae 100644 --- a/test_cal_notif.py +++ b/test_cal_notif.py @@ -79,6 +79,73 @@ def test_config(): pass +def test_expand(): + lo, hi = at(2026, 1, 1), at(2026, 2, 1) + # Weekly zoned event, two EXDATEs, one moved occurrence. + weekly = """UID:w@example.org +DTSTART;TZID=Europe/Rome:20260105T090000 +DTEND;TZID=Europe/Rome:20260105T100000 +RRULE:FREQ=WEEKLY;UNTIL=20260131T000000Z +EXDATE;TZID=Europe/Rome:20260112T090000,20260119T090000 +SUMMARY:standup""" + moved = """UID:w@example.org +RECURRENCE-ID;TZID=Europe/Rome:20260126T090000 +DTSTART;TZID=Europe/Rome:20260126T150000 +DTEND;TZID=Europe/Rome:20260126T160000 +SUMMARY:standup moved""" + occ = cn.expand(ics(weekly, moved), "work", lo, hi) + got = sorted((o.start, o.summary) for o in occ) + assert got == [(at(2026, 1, 5, 9), "standup"), (at(2026, 1, 26, 15), "standup moved")], got + + # All-day yearly with a UTC UNTIL (dateutil rejects the naive/aware mix + # unless normalised) and a relative VALARM 1 day before. + bday = """UID:b@example.org +DTSTART;VALUE=DATE:19800112 +RRULE:FREQ=YEARLY;UNTIL=20300101T000000Z +SUMMARY:birthday +BEGIN:VALARM +ACTION:DISPLAY +TRIGGER:-P1D +END:VALARM""" + (o,) = cn.expand(ics(bday), "bd", lo, hi) + assert o.allday and o.start == datetime(2026, 1, 12).astimezone() + assert o.valarms == (datetime(2026, 1, 11).astimezone(),) + + # A week-ahead VALARM on an event past `hi` widens that event's window. + far = """UID:f@example.org +DTSTART;TZID=Europe/Rome:20260205T090000 +SUMMARY:far +BEGIN:VALARM +ACTION:DISPLAY +TRIGGER:-P7D +END:VALARM""" + (o,) = cn.expand(ics(far), "c", lo, hi) + assert o.valarms == (at(2026, 1, 29, 9),) + assert cn.expand(ics(far.replace("-P7D", "-PT1H")), "c", lo, hi) == [] + + # RELATED=END trigger counts from DTEND. + end = """UID:e@example.org +DTSTART;TZID=Europe/Rome:20260110T090000 +DTEND;TZID=Europe/Rome:20260110T110000 +BEGIN:VALARM +ACTION:DISPLAY +TRIGGER;RELATED=END:-PT15M +END:VALARM""" + (o,) = cn.expand(ics(end), "c", lo, hi) + assert o.valarms == (at(2026, 1, 10, 10, 45),) + + +def test_load_events(): + with tempfile.TemporaryDirectory() as d: + cal = Path(d) / "123" + cal.mkdir() + (cal / "displayname").write_text("work\n") + (cal / "a.ics").write_bytes(ics("UID:a@example.org\nDTSTART;TZID=Europe/Rome:20260110T090000")) + (cal / "broken.ics").write_text("not a calendar") + (o,) = cn.load_events(d, at(2026, 1, 1), at(2026, 2, 1)) # broken one skipped + assert o.cal == "work" and o.uid == "a@example.org" + + if __name__ == "__main__": for name, fn in list(globals().items()): if name.startswith("test_"): |
