@@ -27,23 +27,26 @@ def test_host_request_ics_content():
2727 ics : str = create_host_request_ics_calendar (
2828 host_request , other_name = "Bob" , hosting = True , loc_context = LocalizationContext .en_utc ()
2929 ).serialize ()
30- assert _normalize_ics (ics ) == _normalize_ics ("""
30+ assert _assert_ics_matches_pattern (
31+ ics ,
32+ """
3133BEGIN:VCALENDAR
3234VERSION:2.0
3335PRODID:-//Couchers.org//Couchers//EN
3436BEGIN:VEVENT
35- SEQUENCE:<stripped>
37+ SEQUENCE:***
3638DTSTART;VALUE=DATE:20000101
3739DTEND;VALUE=DATE:20000103
38- DESCRIPTION:<stripped> /42
40+ DESCRIPTION:*** /42
3941LOCATION:New York
4042SUMMARY:Hosting Bob
41- UID:host_request.42@<stripped>
42- URL:<stripped> /42
43+ UID:host_request.42@***
44+ URL:*** /42
4345END:VEVENT
4446METHOD:PUBLISH
4547END:VCALENDAR
46- """ )
48+ """ ,
49+ )
4750
4851
4952def test_host_request_cancelled_ics_content ():
@@ -58,24 +61,27 @@ def test_host_request_cancelled_ics_content():
5861 ics : str = create_host_request_ics_calendar (
5962 host_request , other_name = "Bob" , hosting = True , loc_context = LocalizationContext .en_utc ()
6063 ).serialize ()
61- assert _normalize_ics (ics ) == _normalize_ics ("""
64+ assert _assert_ics_matches_pattern (
65+ ics ,
66+ """
6267BEGIN:VCALENDAR
6368VERSION:2.0
6469PRODID:-//Couchers.org//Couchers//EN
6570BEGIN:VEVENT
66- SEQUENCE:<stripped>
71+ SEQUENCE:***
6772DTSTART;VALUE=DATE:20000101
6873DTEND;VALUE=DATE:20000103
69- DESCRIPTION:<stripped> /42
74+ DESCRIPTION:*** /42
7075LOCATION:New York
7176STATUS:CANCELLED
7277SUMMARY:Cancelled: Hosting Bob
73- UID:host_request.42@<stripped>
74- URL:<stripped> /42
78+ UID:host_request.42@***
79+ URL:*** /42
7580END:VEVENT
7681METHOD:PUBLISH
7782END:VCALENDAR
78- """ )
83+ """ ,
84+ )
7985
8086
8187def test_event_ics_content ():
@@ -84,47 +90,41 @@ def test_event_ics_content():
8490 title = "Event Title" ,
8591 slug = "event-slug" ,
8692 content = "Event description" ,
87- start_time = Timestamp_from_datetime (datetime (2000 , 1 , 1 , tzinfo = UTC )),
88- end_time = Timestamp_from_datetime (datetime (2000 , 1 , 2 , tzinfo = UTC )),
93+ start_time = Timestamp_from_datetime (datetime (2000 , 1 , 1 , 12 , 0 , tzinfo = UTC )),
94+ end_time = Timestamp_from_datetime (datetime (2000 , 1 , 2 , 12 , 0 , tzinfo = UTC )),
8995 location = events_pb2 .EventLocation (address = "City, Country" , lat = 0.1 , lng = 0.1 ),
9096 )
9197
9298 ics : str = create_event_ics_calendar (event , loc_context = LocalizationContext .en_utc ()).serialize ()
93- assert _normalize_ics (ics ) == _normalize_ics ("""
99+ assert _assert_ics_matches_pattern (
100+ ics ,
101+ """
94102BEGIN:VCALENDAR
95103VERSION:2.0
96104PRODID:-//Couchers.org//Couchers//EN
97105BEGIN:VEVENT
98- SEQUENCE:<stripped>
99- DTSTART;VALUE=DATE:20000101
100- DTEND;VALUE=DATE:20000102
106+ SEQUENCE:***
107+ DTSTART;20000101T120000Z
108+ DTEND;20000102T120000Z
101109DESCRIPTION:Event description
102110LOCATION:City, Country
103111STATUS:CANCELLED
104112SUMMARY:Event Title
105- UID:event.42@<stripped>
106- URL:<stripped> /42
113+ UID:event.42@***
114+ URL:*** /42
107115END:VEVENT
108116METHOD:PUBLISH
109117END:VCALENDAR
110- """ )
111-
112-
113- def _normalize_ics (ics : str ) -> str :
114- # Normalize whitespace:
115- # - The ics library produces '\r\n', in-code literals are '\n'
116- # - In-code literals have start/end newlines and indentation.
117- ics = ics .replace ("\r \n " , "\n " ).strip ()
118-
119- # Strip the domain in the UID, which depends on environment variables
120- ics = re .sub (
121- r"^UID:.*@(.*)$" , lambda match : match [0 ].removesuffix (match [1 ]) + "<stripped>" , ics , flags = re .MULTILINE
118+ """ ,
122119 )
123120
124- # Strip the domain in the URL and DESCRIPTION, which depends on environment variables
125- ics = re .sub (r"^(DESCRIPTION|URL):(.*)/(\d+)" , r"\1:<stripped>/\3" , ics , flags = re .MULTILINE )
126121
127- return ics
122+ def _assert_ics_matches_pattern (actual : str , expected_pattern : str ) -> str :
123+ actual = actual .replace ("\r \n " , "\n " ).strip ()
124+ expected_pattern = expected_pattern .strip ()
125+
126+ expected_pattern = re .escape (expected_pattern ).replace ("\*\*\*" , ".*?" )
127+ return re .fullmatch (expected_pattern , actual )
128128
129129
130130def test_host_request_attachments (db , email_collector : EmailCollector , moderator : Moderator ):
0 commit comments