From 1ee873ac93e9a4d1d542d9ccc8d715046d32d5d7 Mon Sep 17 00:00:00 2001 From: Lennart <18233294+lennart-k@users.noreply.github.com> Date: Wed, 31 Dec 2025 13:31:07 +0100 Subject: [PATCH] caldav: Add basic filtering test --- .../methods/report/calendar_query/elements.rs | 5 +- .../methods/report/calendar_query/mod.rs | 22 ++--- .../methods/report/calendar_query/tests.rs | 84 +++++++++++++++++++ 3 files changed, 99 insertions(+), 12 deletions(-) create mode 100644 crates/caldav/src/calendar/methods/report/calendar_query/tests.rs diff --git a/crates/caldav/src/calendar/methods/report/calendar_query/elements.rs b/crates/caldav/src/calendar/methods/report/calendar_query/elements.rs index 9c9820b..d9ca17b 100644 --- a/crates/caldav/src/calendar/methods/report/calendar_query/elements.rs +++ b/crates/caldav/src/calendar/methods/report/calendar_query/elements.rs @@ -4,7 +4,7 @@ use ical::property::Property; use rustical_dav::xml::{PropfindType, TextMatchElement}; use rustical_ical::{CalendarObject, UtcDateTime}; use rustical_store::calendar_store::CalendarQuery; -use rustical_xml::XmlDeserialize; +use rustical_xml::{XmlDeserialize, XmlRootTag}; #[derive(XmlDeserialize, Clone, Debug, PartialEq, Eq)] #[allow(dead_code)] @@ -45,7 +45,8 @@ impl ParamFilterElement { } } -#[derive(XmlDeserialize, Clone, Debug, PartialEq)] +#[derive(XmlDeserialize, XmlRootTag, Clone, Debug, PartialEq)] +#[xml(root = "filter", ns = "rustical_dav::namespace::NS_CALDAV")] #[allow(dead_code)] // https://datatracker.ietf.org/doc/html/rfc4791#section-9.7 pub struct FilterElement { diff --git a/crates/caldav/src/calendar/methods/report/calendar_query/mod.rs b/crates/caldav/src/calendar/methods/report/calendar_query/mod.rs index 11d081b..d46d271 100644 --- a/crates/caldav/src/calendar/methods/report/calendar_query/mod.rs +++ b/crates/caldav/src/calendar/methods/report/calendar_query/mod.rs @@ -5,6 +5,8 @@ use rustical_store::CalendarStore; mod comp_filter; mod elements; mod prop_filter; +#[cfg(test)] +mod tests; #[allow(unused_imports)] pub use comp_filter::{CompFilterElement, CompFilterable}; pub use elements::*; @@ -27,7 +29,7 @@ pub async fn get_objects_calendar_query( } #[cfg(test)] -mod tests { +mod xml_tests { use super::{ CalendarQueryRequest, FilterElement, ParamFilterElement, comp_filter::CompFilterElement, prop_filter::PropFilterElement, @@ -51,16 +53,16 @@ mod tests { - - - - mailto:lisa@example.com - - NEEDS-ACTION - - + + + + mailto:lisa@example.com + + NEEDS-ACTION + + + - "#; diff --git a/crates/caldav/src/calendar/methods/report/calendar_query/tests.rs b/crates/caldav/src/calendar/methods/report/calendar_query/tests.rs new file mode 100644 index 0000000..c7f57a1 --- /dev/null +++ b/crates/caldav/src/calendar/methods/report/calendar_query/tests.rs @@ -0,0 +1,84 @@ +use rstest::rstest; +use rustical_ical::CalendarObject; +use rustical_xml::XmlDocument; + +use crate::calendar::methods::report::calendar_query::FilterElement; + +const ICS_1: &str = r"BEGIN:VCALENDAR +VERSION:2.0 +PRODID:-//Example Corp.//CalDAV Client//EN +BEGIN:VTIMEZONE +LAST-MODIFIED:20040110T032845Z +TZID:US/Eastern +BEGIN:DAYLIGHT +DTSTART:20000404T020000 +RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4 +TZNAME:EDT +TZOFFSETFROM:-0500 +TZOFFSETTO:-0400 +END:DAYLIGHT +BEGIN:STANDARD +DTSTART:20001026T020000 +RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10 +TZNAME:EST +TZOFFSETFROM:-0400 +TZOFFSETTO:-0500 +END:STANDARD +END:VTIMEZONE +BEGIN:VEVENT +ATTENDEE;PARTSTAT=ACCEPTED;ROLE=CHAIR:mailto:cyrus@example.com +ATTENDEE;PARTSTAT=NEEDS-ACTION:mailto:lisa@example.com +DTSTAMP:20060206T001220Z +DTSTART;TZID=US/Eastern:20060104T100000 +DURATION:PT1H +LAST-MODIFIED:20060206T001330Z +ORGANIZER:mailto:cyrus@example.com +SEQUENCE:1 +STATUS:TENTATIVE +SUMMARY:Event #3 +UID:DC6C50A017428C5216A2F1CD@example.com +X-ABC-GUID:E1CX5Dr-0007ym-Hz@example.com +END:VEVENT +END:VCALENDAR +"; + +const FILTER_1: &str = r#" + + + + + + mailto:lisa@example.com + + NEEDS-ACTION + + + + + +"#; + +const FILTER_2: &str = r#" + + + + + + mailto:lisa@example.com + + ACCEPTED + + + + + +"#; + +#[rstest] +#[case(ICS_1, FILTER_1, true)] +#[case(ICS_1, FILTER_2, false)] +fn yeet(#[case] ics: &str, #[case] filter: &str, #[case] matches: bool) { + let obj = CalendarObject::from_ics(ics.to_owned(), None).unwrap(); + let filter = FilterElement::parse_str(filter).unwrap(); + assert_eq!(matches, filter.matches(&obj)); +}