Files

91 lines
2.5 KiB
Python
Raw Permalink Normal View History

from datetime import UTC, datetime
import pytest
from pigway_frame_flow.errors import FlowError
from pigway_frame_flow.providers.ical import calendar_events
def feed(properties):
return (
"BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\n"
+ properties
+ "\r\nEND:VEVENT\r\nEND:VCALENDAR"
).encode()
def test_recurring_event_exclusions_and_folded_title():
result = calendar_events(
feed(
"UID:one\r\nDTSTART:20261008T080000Z\r\nRRULE:FREQ=DAILY;COUNT=3\r\nEXDATE:20261009T080000Z\r\nSUMMARY:Family\r\n time"
),
datetime(2026, 10, 8, tzinfo=UTC),
)
assert len(result["events"]) == 2
assert result["events"][0]["title"] == "Family time"
assert result["events"][1]["start"].startswith("2026-10-10")
def test_cancelled_event_ignored():
assert (
calendar_events(
feed("DTSTART:20261008T080000Z\r\nSTATUS:CANCELLED\r\nSUMMARY:Cancelled"),
datetime(2026, 10, 8, tzinfo=UTC),
)["events"]
== []
)
def test_high_frequency_rejected():
with pytest.raises(FlowError):
calendar_events(
feed("DTSTART:20261008T080000Z\r\nRRULE:FREQ=SECONDLY\r\nSUMMARY:Bad"),
datetime(2026, 10, 8, tzinfo=UTC),
)
def test_timezone_and_past_filter():
events = calendar_events(
feed("DTSTART;TZID=Asia/Shanghai:20261008T090000\r\nSUMMARY:Meeting"),
datetime(2026, 10, 8, tzinfo=UTC),
)["events"]
assert len(events) == 1
assert events[0]["start"].endswith("+08:00")
assert (
calendar_events(
feed("DTSTART:20260101T090000Z\r\nSUMMARY:Past"),
datetime(2026, 10, 8, tzinfo=UTC),
)["events"]
== []
)
def test_dense_recurrence_is_bounded():
rule = (
"FREQ=DAILY;BYHOUR="
+ ",".join(map(str, range(24)))
+ ";BYMINUTE="
+ ",".join(map(str, range(60)))
)
with pytest.raises(FlowError):
calendar_events(
feed("DTSTART:20261008T000000Z\r\nRRULE:" + rule + "\r\nSUMMARY:Too many"),
datetime(2026, 10, 8, tzinfo=UTC),
)
def test_exrule_not_silently_ignored():
with pytest.raises(FlowError):
calendar_events(
feed("DTSTART:20261008T080000Z\r\nEXRULE:FREQ=DAILY\r\nSUMMARY:Excluded"),
datetime(2026, 10, 8, tzinfo=UTC),
)
def test_all_day_today_in_local_timezone():
result = calendar_events(
feed("DTSTART;VALUE=DATE:20261008\r\nSUMMARY:Today"),
datetime(2026, 10, 8, 1, tzinfo=UTC),
)
assert len(result["events"]) == 1