Skip to content

Commit 5d0ff43

Browse files
committed
Test id parsing
1 parent e1424f3 commit 5d0ff43

File tree

2 files changed

+401
-1
lines changed

2 files changed

+401
-1
lines changed

tests/events/microsoft/test_events_provider.py

Lines changed: 191 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@ def events_responses() -> None:
6464
"value": [
6565
{
6666
"id": "singular_id",
67+
"iCalUId": "singular_ical_id",
68+
"createdDateTime": "2025-07-07T08:41:36.5027961Z",
6769
"lastModifiedDateTime": "2022-09-07T08:41:36.5027961Z",
6870
"originalStartTimeZone": "Eastern Standard Time",
6971
"originalEndTimeZone": "Eastern Standard Time",
@@ -106,6 +108,8 @@ def events_responses() -> None:
106108
},
107109
{
108110
"id": "recurrence_id",
111+
"iCalUId": "recurrence_ical_id",
112+
"createdDateTime": "2022-09-07T08:41:36.5027961Z",
109113
"lastModifiedDateTime": "2022-09-27T14:41:23.1042764Z",
110114
"originalStartTimeZone": "Pacific Standard Time",
111115
"originalEndTimeZone": "Pacific Standard Time",
@@ -352,6 +356,8 @@ def exception_override_response() -> None:
352356
},
353357
{
354358
"id": "recurrence_id_exception",
359+
"iCalUId": "recurrence_ical_id_exception",
360+
"createdDateTime": "2022-09-27T14:41:23.1042764Z",
355361
"lastModifiedDateTime": "2022-09-27T14:41:23.1042764Z",
356362
"originalStartTimeZone": "Pacific Standard Time",
357363
"originalEndTimeZone": "Pacific Standard Time",
@@ -474,10 +480,195 @@ def test_sync_events(provider) -> None:
474480

475481
assert isinstance(events_by_title["Singular"], Event)
476482
assert events_by_title["Singular"].description == "Singular"
483+
assert events_by_title["Singular"].uid == "singular_id"
477484
assert isinstance(events_by_title["Recurring"], RecurringEvent)
478485
assert events_by_title["Recurring"].description == "Hello world!"
479486

480487

488+
@pytest.fixture
489+
def events_with_cutoff_response() -> None:
490+
responses.get(
491+
BASE_URL + "/me/calendars/fake_calendar_id/events",
492+
json={
493+
"value": [
494+
{
495+
"id": "before_cutoff_id",
496+
"iCalUId": "before_cutoff_ical_id",
497+
"createdDateTime": "2025-07-29T12:00:00.0000000Z", # Before cutoff
498+
"lastModifiedDateTime": "2025-07-29T12:00:00.0000000Z",
499+
"originalStartTimeZone": "Eastern Standard Time",
500+
"originalEndTimeZone": "Eastern Standard Time",
501+
"subject": "Event Before Cutoff",
502+
"importance": "normal",
503+
"sensitivity": "normal",
504+
"isAllDay": False,
505+
"isCancelled": False,
506+
"isOrganizer": True,
507+
"showAs": "busy",
508+
"type": "singleInstance",
509+
"recurrence": None,
510+
"body": {
511+
"contentType": "html",
512+
"content": "Before cutoff",
513+
},
514+
"start": {
515+
"dateTime": "2025-08-01T12:00:00.0000000",
516+
"timeZone": "UTC",
517+
},
518+
"end": {
519+
"dateTime": "2025-08-01T13:00:00.0000000",
520+
"timeZone": "UTC",
521+
},
522+
"locations": [],
523+
"attendees": [],
524+
"organizer": None,
525+
},
526+
{
527+
"id": "after_cutoff_id",
528+
"iCalUId": "after_cutoff_ical_id",
529+
"createdDateTime": "2025-08-01T12:00:00.0000000Z", # After cutoff
530+
"lastModifiedDateTime": "2025-08-01T12:00:00.0000000Z",
531+
"originalStartTimeZone": "Eastern Standard Time",
532+
"originalEndTimeZone": "Eastern Standard Time",
533+
"subject": "Event After Cutoff",
534+
"importance": "normal",
535+
"sensitivity": "normal",
536+
"isAllDay": False,
537+
"isCancelled": False,
538+
"isOrganizer": True,
539+
"showAs": "busy",
540+
"type": "singleInstance",
541+
"recurrence": None,
542+
"body": {"contentType": "html", "content": "After cutoff"},
543+
"start": {
544+
"dateTime": "2025-08-01T14:00:00.0000000",
545+
"timeZone": "UTC",
546+
},
547+
"end": {
548+
"dateTime": "2025-08-01T15:00:00.0000000",
549+
"timeZone": "UTC",
550+
},
551+
"locations": [],
552+
"attendees": [],
553+
"organizer": None,
554+
},
555+
{
556+
"id": "recurring_after_cutoff_id",
557+
"iCalUId": "recurring_after_cutoff_ical_id",
558+
"createdDateTime": "2025-08-05T10:00:00.0000000Z", # After cutoff
559+
"lastModifiedDateTime": "2025-08-05T10:00:00.0000000Z",
560+
"originalStartTimeZone": "Pacific Standard Time",
561+
"originalEndTimeZone": "Pacific Standard Time",
562+
"subject": "Recurring After Cutoff",
563+
"importance": "normal",
564+
"sensitivity": "normal",
565+
"isAllDay": False,
566+
"isCancelled": False,
567+
"isOrganizer": True,
568+
"showAs": "busy",
569+
"type": "seriesMaster",
570+
"body": {
571+
"contentType": "html",
572+
"content": "Recurring after cutoff",
573+
},
574+
"start": {
575+
"dateTime": "2025-08-10T15:00:00.0000000",
576+
"timeZone": "UTC",
577+
},
578+
"end": {
579+
"dateTime": "2025-08-10T15:30:00.0000000",
580+
"timeZone": "UTC",
581+
},
582+
"locations": [],
583+
"recurrence": {
584+
"pattern": {
585+
"type": "daily",
586+
"interval": 1,
587+
"month": 0,
588+
"dayOfMonth": 0,
589+
"firstDayOfWeek": "sunday",
590+
"index": "first",
591+
},
592+
"range": {
593+
"type": "endDate",
594+
"startDate": "2025-08-10",
595+
"endDate": "2025-08-12",
596+
"recurrenceTimeZone": "Pacific Standard Time",
597+
"numberOfOccurrences": 0,
598+
},
599+
},
600+
"attendees": [],
601+
"organizer": {
602+
"emailAddress": {
603+
"name": "Test",
604+
"address": "test@example.com",
605+
}
606+
},
607+
},
608+
]
609+
},
610+
)
611+
612+
613+
@pytest.fixture
614+
def recurring_instances_response() -> None:
615+
responses.get(
616+
BASE_URL + "/me/events/recurring_after_cutoff_id/instances",
617+
json={
618+
"value": [
619+
{
620+
"type": "occurrence",
621+
"start": {
622+
"dateTime": "2025-08-10T15:00:00.0000000",
623+
"timeZone": "UTC",
624+
},
625+
"originalStart": "2025-08-10T15:00:00Z",
626+
},
627+
{
628+
"type": "occurrence",
629+
"start": {
630+
"dateTime": "2025-08-11T15:00:00.0000000",
631+
"timeZone": "UTC",
632+
},
633+
"originalStart": "2025-08-11T15:00:00Z",
634+
},
635+
{
636+
"type": "occurrence",
637+
"start": {
638+
"dateTime": "2025-08-12T15:00:00.0000000",
639+
"timeZone": "UTC",
640+
},
641+
"originalStart": "2025-08-12T15:00:00Z",
642+
},
643+
]
644+
},
645+
)
646+
647+
648+
@responses.activate
649+
@pytest.mark.usefixtures(
650+
"events_with_cutoff_response", "recurring_instances_response"
651+
)
652+
def test_sync_events_respects_ical_uid_cutoff(provider) -> None:
653+
events = provider.sync_events("fake_calendar_id")
654+
events_by_title = {event.title: event for event in events}
655+
656+
# Event created before cutoff should use MS Graph ID
657+
assert events_by_title["Event Before Cutoff"].uid == "before_cutoff_id"
658+
659+
# Event created after cutoff should use iCalUID
660+
assert events_by_title["Event After Cutoff"].uid == "after_cutoff_ical_id"
661+
662+
# Recurring event created after cutoff should use iCalUID
663+
assert isinstance(
664+
events_by_title["Recurring After Cutoff"], RecurringEvent
665+
)
666+
assert (
667+
events_by_title["Recurring After Cutoff"].uid
668+
== "recurring_after_cutoff_ical_id"
669+
)
670+
671+
481672
@responses.activate
482673
@pytest.mark.usefixtures("events_responses", "cancellation_override_response")
483674
def test_sync_events_cancellation(provider) -> None:

0 commit comments

Comments
 (0)