diff --git a/radicale/tests/static/event_mixed_recurrence_id_dt_type.ics b/radicale/tests/static/event_mixed_recurrence_id_dt_type.ics new file mode 100644 index 00000000..8c9e9edf --- /dev/null +++ b/radicale/tests/static/event_mixed_recurrence_id_dt_type.ics @@ -0,0 +1,20 @@ +BEGIN:VCALENDAR +VERSION:2.0 + +BEGIN:VEVENT +DTSTART:20060102T120000Z +DURATION:PT1H +RRULE:FREQ=DAILY;COUNT=3 +SUMMARY:Recurring event +UID:event_mixed_recurrence_id_dt_type +END:VEVENT + +BEGIN:VEVENT +DTSTART:20060103T140000Z +DURATION:PT1H +RECURRENCE-ID;VALUE=DATE:20060103 +SUMMARY:Override with wrong type +UID:event_mixed_recurrence_id_dt_type +END:VEVENT + +END:VCALENDAR \ No newline at end of file diff --git a/radicale/tests/test_expand.py b/radicale/tests/test_expand.py index 9783abeb..9a1f7369 100644 --- a/radicale/tests/test_expand.py +++ b/radicale/tests/test_expand.py @@ -698,3 +698,43 @@ permissions: RrWw""") status, responses = self.report("/test", request) assert status == 207 assert len(responses) == 0 + + def test_report_with_incompatible_recurrence_id_dt_types(self, caplog) -> None: + """Test report with incompatible RECURRENCE-ID value types (RFC 5545 3.8.4.4)""" + + import logging + caplog.set_level(logging.WARNING) + + event_id = "event_mixed_recurrence_id_dt_type" + start = "20060103T000000Z" + end = "20060105T000000Z" + + self.put("/calendar.ics/", get_file_content(f"{event_id}.ics")) + + request = f""" + + + + + + + + + + + + + + + """ + + status, _, _ = self.request("REPORT", "/calendar.ics/", request) + + assert status == 400 + + logs = caplog.messages + error_logs = [log for log in logs if "incompatible RECURRENCE-ID value type" in log] + assert len(error_logs) > 0 + assert event_id in error_logs[0] + assert "base DTSTART is datetime" in error_logs[0] + assert "override RECURRENCE-ID is date" in error_logs[0]