from __future__ import annotations import unittest from govoplan_calendar.backend.ical import event_to_ics, parse_vevent class ICalendarParsingTests(unittest.TestCase): def test_parse_vevent_preserves_unknown_properties_and_params(self) -> None: payload = """BEGIN:VCALENDAR VERSION:2.0 BEGIN:VEVENT UID:event-1@example.test DTSTAMP:20260707T080000Z DTSTART;TZID=Europe/Berlin:20260708T090000 DTEND;TZID=Europe/Berlin:20260708T100000 SUMMARY:Planning ATTENDEE;CN=Ada;ROLE=REQ-PARTICIPANT:mailto:ada@example.test RRULE:FREQ=WEEKLY;COUNT=3 X-GOVOPLAN-CUSTOM:kept END:VEVENT END:VCALENDAR """ event = parse_vevent(payload) self.assertEqual(event["uid"], "event-1@example.test") self.assertEqual(event["summary"], "Planning") self.assertEqual(event["timezone"], "Europe/Berlin") self.assertEqual(event["rrule"], {"FREQ": "WEEKLY", "COUNT": "3"}) self.assertEqual(event["attendees"][0]["params"]["CN"], ["Ada"]) property_names = [item["name"] for item in event["icalendar"]["properties"]] self.assertIn("X-GOVOPLAN-CUSTOM", property_names) def test_parse_all_day_event(self) -> None: event = parse_vevent( """BEGIN:VCALENDAR VERSION:2.0 BEGIN:VEVENT UID:event-2@example.test DTSTART;VALUE=DATE:20260708 DTEND;VALUE=DATE:20260709 SUMMARY:All day END:VEVENT END:VCALENDAR """ ) self.assertTrue(event["all_day"]) self.assertEqual(event["start_at"].hour, 0) def test_generated_ics_contains_required_vevent_fields(self) -> None: class Event: uid = "event-3@example.test" start_at = parse_vevent( """BEGIN:VCALENDAR BEGIN:VEVENT UID:x DTSTART:20260708T090000Z SUMMARY:x END:VEVENT END:VCALENDAR """ )["start_at"] end_at = None all_day = False timezone = None summary = "Generated" sequence = 0 status = "CONFIRMED" transparency = "OPAQUE" classification = "PUBLIC" description = None location = None categories = [] rrule = None organizer = None attendees = [] ics = event_to_ics(Event()) self.assertIn("BEGIN:VEVENT", ics) self.assertIn("UID:event-3@example.test", ics) self.assertIn("SUMMARY:Generated", ics) if __name__ == "__main__": unittest.main()