Merge pull request #2193 from TowyTowy/fix/vtodo-time-range-completed-clobbers-due
Fix: time-range filter on VTODO with DTSTART/DUE and CREATED/COMPLETED
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
## 3.7.8.dev
|
## 3.7.8.dev
|
||||||
|
* Fix: time-range filter on a VTODO having DTSTART/DUE and also CREATED/COMPLETED used the CREATED->COMPLETED duration instead of the DTSTART->DUE one, so completed tasks were missing from (or wrongly returned by) calendar-query REPORT results
|
||||||
* Fix: sharing/proppatch: reject in case of write-access but 'p' is in permissions
|
* Fix: sharing/proppatch: reject in case of write-access but 'p' is in permissions
|
||||||
* Fix: sharing/by-map: catch collection path without trailing / (supporting "pimsync")
|
* Fix: sharing/by-map: catch collection path without trailing / (supporting "pimsync")
|
||||||
* Add: [report] max_expand_occurrence option to separate from max_freebusy_occurrence
|
* Add: [report] max_expand_occurrence option to separate from max_freebusy_occurrence
|
||||||
|
|||||||
@@ -442,7 +442,10 @@ def visit_time_ranges(vobject_item: vobject.base.Component, child_name: str,
|
|||||||
completed = date_to_datetime(completed.value)
|
completed = date_to_datetime(completed.value)
|
||||||
if created is not None:
|
if created is not None:
|
||||||
created = date_to_datetime(created.value)
|
created = date_to_datetime(created.value)
|
||||||
original_duration = (completed - created).total_seconds()
|
# NOTE: kept separate from "original_duration", otherwise a
|
||||||
|
# VTODO with DTSTART+DUE and also CREATED+COMPLETED would
|
||||||
|
# lose its DTSTART->DUE duration (see line 2 below)
|
||||||
|
completed_duration = (completed - created).total_seconds()
|
||||||
elif created is not None:
|
elif created is not None:
|
||||||
created = date_to_datetime(created.value)
|
created = date_to_datetime(created.value)
|
||||||
|
|
||||||
@@ -500,7 +503,7 @@ def visit_time_ranges(vobject_item: vobject.base.Component, child_name: str,
|
|||||||
elif completed is not None and created is not None:
|
elif completed is not None and created is not None:
|
||||||
# Line 5
|
# Line 5
|
||||||
completed = reference_date + timedelta(
|
completed = reference_date + timedelta(
|
||||||
seconds=original_duration)
|
seconds=completed_duration)
|
||||||
if (range_fn(reference_date - SECOND,
|
if (range_fn(reference_date - SECOND,
|
||||||
reference_date + SECOND,
|
reference_date + SECOND,
|
||||||
is_recurrence) or
|
is_recurrence) or
|
||||||
|
|||||||
13
radicale/tests/static/todo10.ics
Normal file
13
radicale/tests/static/todo10.ics
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
BEGIN:VCALENDAR
|
||||||
|
VERSION:2.0
|
||||||
|
PRODID:-//Radicale//NONSGML Radicale Server//EN
|
||||||
|
BEGIN:VTODO
|
||||||
|
UID:todo10
|
||||||
|
SUMMARY:todo10
|
||||||
|
DTSTART:20130901T180000Z
|
||||||
|
DUE:20130903T180000Z
|
||||||
|
CREATED:20130901T170000Z
|
||||||
|
COMPLETED:20130901T173000Z
|
||||||
|
STATUS:COMPLETED
|
||||||
|
END:VTODO
|
||||||
|
END:VCALENDAR
|
||||||
@@ -2083,6 +2083,27 @@ permissions: RrWw""")
|
|||||||
</C:comp-filter>"""], "todo", items=range(1, 9))
|
</C:comp-filter>"""], "todo", items=range(1, 9))
|
||||||
assert "/calendar.ics/todo7.ics" in answer
|
assert "/calendar.ics/todo7.ics" in answer
|
||||||
|
|
||||||
|
def test_time_range_filter_todos_dtstart_due_completed(self) -> None:
|
||||||
|
"""Report request with time-range filter on a completed todo which
|
||||||
|
also has DTSTART and DUE (rfc4791-9.9: DTSTART/DUE take
|
||||||
|
precedence over CREATED/COMPLETED)."""
|
||||||
|
# inside DTSTART..DUE, but outside CREATED..COMPLETED
|
||||||
|
answer = self._test_filter(["""\
|
||||||
|
<C:comp-filter name="VCALENDAR">
|
||||||
|
<C:comp-filter name="VTODO">
|
||||||
|
<C:time-range start="20130902T000000Z" end="20130903T000000Z"/>
|
||||||
|
</C:comp-filter>
|
||||||
|
</C:comp-filter>"""], "todo", items=(10,))
|
||||||
|
assert "/calendar.ics/todo10.ics" in answer
|
||||||
|
# entirely before DTSTART and CREATED
|
||||||
|
answer = self._test_filter(["""\
|
||||||
|
<C:comp-filter name="VCALENDAR">
|
||||||
|
<C:comp-filter name="VTODO">
|
||||||
|
<C:time-range start="20130801T000000Z" end="20130901T000000Z"/>
|
||||||
|
</C:comp-filter>
|
||||||
|
</C:comp-filter>"""], "todo", items=(10,))
|
||||||
|
assert "/calendar.ics/todo10.ics" not in answer
|
||||||
|
|
||||||
def test_time_range_filter_events_valarm(self) -> None:
|
def test_time_range_filter_events_valarm(self) -> None:
|
||||||
"""Report request with time-range filter on events having absolute VALARM."""
|
"""Report request with time-range filter on events having absolute VALARM."""
|
||||||
answer = self._test_filter(["""\
|
answer = self._test_filter(["""\
|
||||||
|
|||||||
Reference in New Issue
Block a user