Fix: expand REPORT leaves recurrence properties on expanded instances
_strip_single_event() removed the recurrence-defining properties (RRULE, EXDATE, EXRULE, RDATE) with a single try/except around sequential delattr() calls. When one of them was absent (e.g. an event with no EXDATE), the AttributeError aborted the whole block and the following properties -- notably RDATE -- were left on the expanded single-occurrence VEVENTs returned by a calendar-data expand REPORT. Remove each property independently so a missing one no longer prevents removal of the others. Add a regression test and fixture. Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
|
||||
## 3.7.7.dev
|
||||
* Fix: time-range filter treated a VEVENT with a whole-day DURATION (e.g. P1D, P2D) as zero-length (timedelta.seconds instead of total_seconds), so such events were missing from calendar-query REPORT results
|
||||
* Fix: calendar-data expand (REPORT) left recurrence properties (e.g. RDATE) on the expanded single-occurrence VEVENTs; a single try/except around the sequential delattr() calls stopped at the first absent property (e.g. missing EXDATE), so later ones were never removed
|
||||
|
||||
## 3.7.6
|
||||
* Extension: item verification on commandline
|
||||
|
||||
@@ -638,13 +638,15 @@ def _strip_single_event(
|
||||
_convert_to_utc(vevent, 'dtend', dt_format)
|
||||
_convert_to_utc(vevent, 'recurrence_id', dt_format)
|
||||
|
||||
try:
|
||||
delattr(vevent, 'rrule')
|
||||
delattr(vevent, 'exdate')
|
||||
delattr(vevent, 'exrule')
|
||||
delattr(vevent, 'rdate')
|
||||
except AttributeError:
|
||||
pass
|
||||
# Remove every recurrence-defining property independently: a single
|
||||
# try/except around the sequential delattr() calls stopped at the first
|
||||
# property that was absent, leaving the following ones (e.g. RDATE) on the
|
||||
# expanded single-occurrence instance.
|
||||
for prop in ('rrule', 'exdate', 'exrule', 'rdate'):
|
||||
try:
|
||||
delattr(vevent, prop)
|
||||
except AttributeError:
|
||||
pass
|
||||
|
||||
|
||||
def _strip_component(vevent: vobject.base.Component) -> None:
|
||||
|
||||
12
radicale/tests/static/event_rrule_rdate.ics
Normal file
12
radicale/tests/static/event_rrule_rdate.ics
Normal file
@@ -0,0 +1,12 @@
|
||||
BEGIN:VCALENDAR
|
||||
VERSION:2.0
|
||||
PRODID:-//Radicale tests//NONSGML test//EN
|
||||
BEGIN:VEVENT
|
||||
UID:event_rrule_rdate
|
||||
DTSTART:20060102T170000Z
|
||||
DURATION:PT1H
|
||||
RRULE:FREQ=DAILY;COUNT=3
|
||||
RDATE:20060110T170000Z
|
||||
SUMMARY:Daily recurring meeting
|
||||
END:VEVENT
|
||||
END:VCALENDAR
|
||||
@@ -750,3 +750,34 @@ permissions: RrWw""")
|
||||
ONLY_DATES,
|
||||
2
|
||||
)
|
||||
|
||||
def test_report_with_expand_property_strips_recurrence_properties(self) -> None:
|
||||
"""Expanded instances must not retain recurrence properties.
|
||||
|
||||
Regression test: the stored event has an RRULE and an RDATE but no
|
||||
EXDATE/EXRULE. Expanded VEVENT instances represent a single
|
||||
occurrence (identified by RECURRENCE-ID) and must not carry any
|
||||
recurrence-defining property (RRULE, RDATE, EXRULE, EXDATE).
|
||||
"""
|
||||
uid = "event_rrule_rdate"
|
||||
start = "20060102T000000Z"
|
||||
end = "20060105T000000Z"
|
||||
|
||||
# Baseline (no expand): the stored event still holds RRULE and RDATE.
|
||||
_, responses = self.report(
|
||||
"/calendar.ics/", self._req_without_expand(uid, start, end))
|
||||
status, element = responses[
|
||||
f"/calendar.ics/{uid}.ics"]["C:calendar-data"]
|
||||
assert status == 200 and element.text
|
||||
assert "RRULE" in element.text
|
||||
assert "RDATE" in element.text
|
||||
|
||||
# Expanded: individual instances must not carry recurrence properties.
|
||||
_, responses = self.report(
|
||||
"/calendar.ics/", self._req_with_expand(uid, start, end))
|
||||
status, element = responses[
|
||||
f"/calendar.ics/{uid}.ics"]["C:calendar-data"]
|
||||
assert status == 200 and element.text
|
||||
assert "RECURRENCE-ID" in element.text
|
||||
assert "RRULE" not in element.text
|
||||
assert "RDATE" not in element.text
|
||||
|
||||
Reference in New Issue
Block a user