|
|
@@ -21,16 +21,14 @@ Radicale tests with expand requests.
|
|
|
"""
|
|
|
|
|
|
import os
|
|
|
-import posixpath
|
|
|
-from typing import Any, Callable, ClassVar, Iterable, List, Optional, Tuple
|
|
|
+from typing import ClassVar, List
|
|
|
|
|
|
-import defusedxml.ElementTree as DefusedET
|
|
|
-import vobject
|
|
|
-
|
|
|
-from radicale import storage, xmlutils
|
|
|
-from radicale.tests import RESPONSES, BaseTest
|
|
|
+from radicale.tests import BaseTest
|
|
|
from radicale.tests.helpers import get_file_content
|
|
|
|
|
|
+ONLY_DATES = True
|
|
|
+CONTAINS_TIMES = False
|
|
|
+
|
|
|
|
|
|
class TestExpandRequests(BaseTest):
|
|
|
"""Tests with expand requests."""
|
|
|
@@ -70,9 +68,14 @@ permissions: RrWw""")
|
|
|
self.configure({"rights": {"file": rights_file_path,
|
|
|
"type": "from_file"}})
|
|
|
|
|
|
- def test_report_with_expand_property(self) -> None:
|
|
|
- """Test report with expand property"""
|
|
|
- self.put("/calendar.ics/", get_file_content("event_daily_rrule.ics"))
|
|
|
+ def _test_expand(self,
|
|
|
+ expected_uid: str,
|
|
|
+ expected_recurrence_ids: List[str],
|
|
|
+ expected_start_times: List[str],
|
|
|
+ expected_end_times: List[str],
|
|
|
+ only_dates: bool,
|
|
|
+ nr_uids: int) -> None:
|
|
|
+ self.put("/calendar.ics/", get_file_content(f"{expected_uid}.ics"))
|
|
|
req_body_without_expand = \
|
|
|
"""<?xml version="1.0" encoding="utf-8" ?>
|
|
|
<C:calendar-query xmlns:D="DAV:" xmlns:C="urn:ietf:params:xml:ns:caldav">
|
|
|
@@ -92,24 +95,26 @@ permissions: RrWw""")
|
|
|
_, responses = self.report("/calendar.ics/", req_body_without_expand)
|
|
|
assert len(responses) == 1
|
|
|
|
|
|
- response_without_expand = responses['/calendar.ics/event_daily_rrule.ics']
|
|
|
+ response_without_expand = responses[f'/calendar.ics/{expected_uid}.ics']
|
|
|
assert not isinstance(response_without_expand, int)
|
|
|
status, element = response_without_expand["C:calendar-data"]
|
|
|
|
|
|
assert status == 200 and element.text
|
|
|
|
|
|
assert "RRULE" in element.text
|
|
|
- assert "BEGIN:VTIMEZONE" in element.text
|
|
|
- assert "RECURRENCE-ID" not in element.text
|
|
|
+ if not only_dates:
|
|
|
+ assert "BEGIN:VTIMEZONE" in element.text
|
|
|
+ if nr_uids == 1:
|
|
|
+ assert "RECURRENCE-ID" not in element.text
|
|
|
|
|
|
uids: List[str] = []
|
|
|
for line in element.text.split("\n"):
|
|
|
if line.startswith("UID:"):
|
|
|
uid = line[len("UID:"):]
|
|
|
- assert uid == "event_daily_rrule"
|
|
|
+ assert uid == expected_uid
|
|
|
uids.append(uid)
|
|
|
|
|
|
- assert len(uids) == 1
|
|
|
+ assert len(uids) == nr_uids
|
|
|
|
|
|
req_body_with_expand = \
|
|
|
"""<?xml version="1.0" encoding="utf-8" ?>
|
|
|
@@ -133,7 +138,7 @@ permissions: RrWw""")
|
|
|
|
|
|
assert len(responses) == 1
|
|
|
|
|
|
- response_with_expand = responses['/calendar.ics/event_daily_rrule.ics']
|
|
|
+ response_with_expand = responses[f'/calendar.ics/{expected_uid}.ics']
|
|
|
assert not isinstance(response_with_expand, int)
|
|
|
status, element = response_with_expand["C:calendar-data"]
|
|
|
|
|
|
@@ -145,192 +150,51 @@ permissions: RrWw""")
|
|
|
recurrence_ids = []
|
|
|
for line in element.text.split("\n"):
|
|
|
if line.startswith("UID:"):
|
|
|
- assert line == "UID:event_daily_rrule"
|
|
|
+ assert line == f"UID:{expected_uid}"
|
|
|
uids.append(line)
|
|
|
|
|
|
if line.startswith("RECURRENCE-ID:"):
|
|
|
- assert line in ["RECURRENCE-ID:20060103T170000Z", "RECURRENCE-ID:20060104T170000Z"]
|
|
|
+ assert line in expected_recurrence_ids
|
|
|
recurrence_ids.append(line)
|
|
|
|
|
|
if line.startswith("DTSTART:"):
|
|
|
- assert line in ["DTSTART:20060103T170000Z", "DTSTART:20060104T170000Z"]
|
|
|
-
|
|
|
- assert len(uids) == 2
|
|
|
- assert len(set(recurrence_ids)) == 2
|
|
|
-
|
|
|
- def test_report_with_expand_property_all_day_event(self) -> None:
|
|
|
- """Test report with expand property"""
|
|
|
- self.put("/calendar.ics/", get_file_content("event_full_day_rrule.ics"))
|
|
|
- req_body_without_expand = \
|
|
|
- """<?xml version="1.0" encoding="utf-8" ?>
|
|
|
- <C:calendar-query xmlns:D="DAV:" xmlns:C="urn:ietf:params:xml:ns:caldav">
|
|
|
- <D:prop>
|
|
|
- <C:calendar-data>
|
|
|
- </C:calendar-data>
|
|
|
- </D:prop>
|
|
|
- <C:filter>
|
|
|
- <C:comp-filter name="VCALENDAR">
|
|
|
- <C:comp-filter name="VEVENT">
|
|
|
- <C:time-range start="20060103T000000Z" end="20060105T000000Z"/>
|
|
|
- </C:comp-filter>
|
|
|
- </C:comp-filter>
|
|
|
- </C:filter>
|
|
|
- </C:calendar-query>
|
|
|
- """
|
|
|
- _, responses = self.report("/calendar.ics/", req_body_without_expand)
|
|
|
- assert len(responses) == 1
|
|
|
-
|
|
|
- response_without_expand = responses['/calendar.ics/event_full_day_rrule.ics']
|
|
|
- assert not isinstance(response_without_expand, int)
|
|
|
- status, element = response_without_expand["C:calendar-data"]
|
|
|
-
|
|
|
- assert status == 200 and element.text
|
|
|
-
|
|
|
- assert "RRULE" in element.text
|
|
|
- assert "RECURRENCE-ID" not in element.text
|
|
|
-
|
|
|
- uids: List[str] = []
|
|
|
- for line in element.text.split("\n"):
|
|
|
- if line.startswith("UID:"):
|
|
|
- uid = line[len("UID:"):]
|
|
|
- assert uid == "event_full_day_rrule"
|
|
|
- uids.append(uid)
|
|
|
-
|
|
|
- assert len(uids) == 1
|
|
|
-
|
|
|
- req_body_with_expand = \
|
|
|
- """<?xml version="1.0" encoding="utf-8" ?>
|
|
|
- <C:calendar-query xmlns:D="DAV:" xmlns:C="urn:ietf:params:xml:ns:caldav">
|
|
|
- <D:prop>
|
|
|
- <C:calendar-data>
|
|
|
- <C:expand start="20060103T000000Z" end="20060105T000000Z"/>
|
|
|
- </C:calendar-data>
|
|
|
- </D:prop>
|
|
|
- <C:filter>
|
|
|
- <C:comp-filter name="VCALENDAR">
|
|
|
- <C:comp-filter name="VEVENT">
|
|
|
- <C:time-range start="20060103T000000Z" end="20060105T000000Z"/>
|
|
|
- </C:comp-filter>
|
|
|
- </C:comp-filter>
|
|
|
- </C:filter>
|
|
|
- </C:calendar-query>
|
|
|
- """
|
|
|
-
|
|
|
- _, responses = self.report("/calendar.ics/", req_body_with_expand)
|
|
|
-
|
|
|
- assert len(responses) == 1
|
|
|
-
|
|
|
- response_with_expand = responses['/calendar.ics/event_full_day_rrule.ics']
|
|
|
- assert not isinstance(response_with_expand, int)
|
|
|
- status, element = response_with_expand["C:calendar-data"]
|
|
|
-
|
|
|
- assert status == 200 and element.text
|
|
|
- assert "RRULE" not in element.text
|
|
|
- assert "BEGIN:VTIMEZONE" not in element.text
|
|
|
-
|
|
|
- uids = []
|
|
|
- recurrence_ids = []
|
|
|
- for line in element.text.split("\n"):
|
|
|
- if line.startswith("UID:"):
|
|
|
- assert line == "UID:event_full_day_rrule"
|
|
|
- uids.append(line)
|
|
|
-
|
|
|
- if line.startswith("RECURRENCE-ID:"):
|
|
|
- assert line in ["RECURRENCE-ID:20060103", "RECURRENCE-ID:20060104", "RECURRENCE-ID:20060105"]
|
|
|
- recurrence_ids.append(line)
|
|
|
-
|
|
|
- if line.startswith("DTSTART:"):
|
|
|
- assert line in ["DTSTART:20060103", "DTSTART:20060104", "DTSTART:20060105"]
|
|
|
+ assert line in expected_start_times
|
|
|
|
|
|
if line.startswith("DTEND:"):
|
|
|
- assert line in ["DTEND:20060104", "DTEND:20060105", "DTEND:20060106"]
|
|
|
+ assert line in expected_end_times
|
|
|
|
|
|
- assert len(uids) == 3
|
|
|
- assert len(set(recurrence_ids)) == 3
|
|
|
+ assert len(uids) == len(expected_recurrence_ids)
|
|
|
+ assert len(set(recurrence_ids)) == len(expected_recurrence_ids)
|
|
|
|
|
|
- def test_report_with_expand_property_overridden(self) -> None:
|
|
|
+ def test_report_with_expand_property(self) -> None:
|
|
|
"""Test report with expand property"""
|
|
|
- self.put("/calendar.ics/", get_file_content("event_daily_rrule_overridden.ics"))
|
|
|
- req_body_without_expand = \
|
|
|
- """<?xml version="1.0" encoding="utf-8" ?>
|
|
|
- <C:calendar-query xmlns:D="DAV:" xmlns:C="urn:ietf:params:xml:ns:caldav">
|
|
|
- <D:prop>
|
|
|
- <C:calendar-data>
|
|
|
- </C:calendar-data>
|
|
|
- </D:prop>
|
|
|
- <C:filter>
|
|
|
- <C:comp-filter name="VCALENDAR">
|
|
|
- <C:comp-filter name="VEVENT">
|
|
|
- <C:time-range start="20060103T000000Z" end="20060105T000000Z"/>
|
|
|
- </C:comp-filter>
|
|
|
- </C:comp-filter>
|
|
|
- </C:filter>
|
|
|
- </C:calendar-query>
|
|
|
- """
|
|
|
- _, responses = self.report("/calendar.ics/", req_body_without_expand)
|
|
|
- assert len(responses) == 1
|
|
|
-
|
|
|
- response_without_expand = responses['/calendar.ics/event_daily_rrule_overridden.ics']
|
|
|
- assert not isinstance(response_without_expand, int)
|
|
|
- status, element = response_without_expand["C:calendar-data"]
|
|
|
+ self._test_expand(
|
|
|
+ "event_daily_rrule",
|
|
|
+ ["RECURRENCE-ID:20060103T170000Z", "RECURRENCE-ID:20060104T170000Z"],
|
|
|
+ ["DTSTART:20060103T170000Z", "DTSTART:20060104T170000Z"],
|
|
|
+ [],
|
|
|
+ CONTAINS_TIMES,
|
|
|
+ 1
|
|
|
+ )
|
|
|
|
|
|
- assert status == 200 and element.text
|
|
|
-
|
|
|
- assert "RRULE" in element.text
|
|
|
- assert "BEGIN:VTIMEZONE" in element.text
|
|
|
-
|
|
|
- uids: List[str] = []
|
|
|
- for line in element.text.split("\n"):
|
|
|
- if line.startswith("UID:"):
|
|
|
- uid = line[len("UID:"):]
|
|
|
- assert uid == "event_daily_rrule_overridden"
|
|
|
- uids.append(uid)
|
|
|
-
|
|
|
- assert len(uids) == 2
|
|
|
-
|
|
|
- req_body_with_expand = \
|
|
|
- """<?xml version="1.0" encoding="utf-8" ?>
|
|
|
- <C:calendar-query xmlns:D="DAV:" xmlns:C="urn:ietf:params:xml:ns:caldav">
|
|
|
- <D:prop>
|
|
|
- <C:calendar-data>
|
|
|
- <C:expand start="20060103T000000Z" end="20060105T000000Z"/>
|
|
|
- </C:calendar-data>
|
|
|
- </D:prop>
|
|
|
- <C:filter>
|
|
|
- <C:comp-filter name="VCALENDAR">
|
|
|
- <C:comp-filter name="VEVENT">
|
|
|
- <C:time-range start="20060103T000000Z" end="20060105T000000Z"/>
|
|
|
- </C:comp-filter>
|
|
|
- </C:comp-filter>
|
|
|
- </C:filter>
|
|
|
- </C:calendar-query>
|
|
|
- """
|
|
|
-
|
|
|
- _, responses = self.report("/calendar.ics/", req_body_with_expand)
|
|
|
-
|
|
|
- assert len(responses) == 1
|
|
|
-
|
|
|
- response_with_expand = responses['/calendar.ics/event_daily_rrule_overridden.ics']
|
|
|
- assert not isinstance(response_with_expand, int)
|
|
|
- status, element = response_with_expand["C:calendar-data"]
|
|
|
-
|
|
|
- assert status == 200 and element.text
|
|
|
- assert "RRULE" not in element.text
|
|
|
- assert "BEGIN:VTIMEZONE" not in element.text
|
|
|
-
|
|
|
- uids = []
|
|
|
- recurrence_ids = []
|
|
|
- for line in element.text.split("\n"):
|
|
|
- if line.startswith("UID:"):
|
|
|
- assert line == "UID:event_daily_rrule_overridden"
|
|
|
- uids.append(line)
|
|
|
-
|
|
|
- if line.startswith("RECURRENCE-ID:"):
|
|
|
- assert line in ["RECURRENCE-ID:20060103T170000Z", "RECURRENCE-ID:20060104T170000Z"]
|
|
|
- recurrence_ids.append(line)
|
|
|
-
|
|
|
- if line.startswith("DTSTART:"):
|
|
|
- assert line in ["DTSTART:20060103T170000Z", "DTSTART:20060104T190000Z"]
|
|
|
+ def test_report_with_expand_property_all_day_event(self) -> None:
|
|
|
+ """Test report with expand property for all day events"""
|
|
|
+ self._test_expand(
|
|
|
+ "event_full_day_rrule",
|
|
|
+ ["RECURRENCE-ID:20060103", "RECURRENCE-ID:20060104", "RECURRENCE-ID:20060105"],
|
|
|
+ ["DTSTART:20060103", "DTSTART:20060104", "DTSTART:20060105"],
|
|
|
+ ["DTEND:20060104", "DTEND:20060105", "DTEND:20060106"],
|
|
|
+ ONLY_DATES,
|
|
|
+ 1
|
|
|
+ )
|
|
|
|
|
|
- assert len(uids) == 2
|
|
|
- assert len(set(recurrence_ids)) == 2
|
|
|
+ def test_report_with_expand_property_overridden(self) -> None:
|
|
|
+ """Test report with expand property with overridden events"""
|
|
|
+ self._test_expand(
|
|
|
+ "event_daily_rrule_overridden",
|
|
|
+ ["RECURRENCE-ID:20060103T170000Z", "RECURRENCE-ID:20060104T170000Z"],
|
|
|
+ ["DTSTART:20060103T170000Z", "DTSTART:20060104T190000Z"],
|
|
|
+ [],
|
|
|
+ CONTAINS_TIMES,
|
|
|
+ 2
|
|
|
+ )
|