From f73658b32f78501e11e86407c65cf13dfc350a42 Mon Sep 17 00:00:00 2001 From: Lennart <18233294+lennart-k@users.noreply.github.com> Date: Mon, 19 Jan 2026 12:09:34 +0100 Subject: [PATCH] Re-enable calendar-query test and fix calendar expansion --- Cargo.lock | 79 +++++----- Cargo.toml | 1 + .../caldav/calendar_report.rs | 137 ++++++++++-------- src/integration_tests/caldav/mod.rs | 2 +- .../caldav/resources/rfc4791_appb.ics | 1 + ...__caldav__calendar_import__1_get_body.snap | 1 + ...aldav__calendar_report__0_report_body.snap | 3 +- ...aldav__calendar_report__1_report_body.snap | 1 + ...aldav__calendar_report__2_report_body.snap | 11 +- 9 files changed, 128 insertions(+), 108 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 83a59e7..b4a8517 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -573,9 +573,9 @@ checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" [[package]] name = "cc" -version = "1.2.52" +version = "1.2.53" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd4932aefd12402b36c60956a4fe0035421f544799057659ff86f923657aada3" +checksum = "755d2fce177175ffca841e9a06afdb2c4ab0f593d53b4dee48147dfaade85932" dependencies = [ "find-msvc-tools", "shlex", @@ -1241,9 +1241,9 @@ dependencies = [ [[package]] name = "find-msvc-tools" -version = "0.1.7" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f449e6c6c08c865631d4890cfacf252b3d396c9bcc83adb6623cdb02a8336c41" +checksum = "8591b0bcc8a98a64310a2fae1bb3e9b8564dd10e381e6e28010fde8e8e8568db" [[package]] name = "flume" @@ -1771,7 +1771,7 @@ dependencies = [ [[package]] name = "ical" version = "0.12.0-dev" -source = "git+https://github.com/lennart-k/ical-rs?branch=dev#5e61c25646c3785448d349e7d18b2833fc483c53" +source = "git+https://github.com/lennart-k/ical-rs?branch=dev#8697656303f182ce173efdaf6aa7e842ffdb3f33" dependencies = [ "chrono", "chrono-tz", @@ -1781,7 +1781,7 @@ dependencies = [ "phf 0.13.1", "regex", "rrule", - "thiserror 2.0.17", + "thiserror 2.0.18", ] [[package]] @@ -2118,7 +2118,7 @@ dependencies = [ "matchit 0.9.1", "percent-encoding", "serde", - "thiserror 2.0.17", + "thiserror 2.0.18", ] [[package]] @@ -2370,7 +2370,7 @@ dependencies = [ "futures-sink", "js-sys", "pin-project-lite", - "thiserror 2.0.17", + "thiserror 2.0.18", "tracing", ] @@ -2400,7 +2400,7 @@ dependencies = [ "opentelemetry_sdk", "prost", "reqwest", - "thiserror 2.0.17", + "thiserror 2.0.18", "tokio", "tonic", "tracing", @@ -2437,7 +2437,7 @@ dependencies = [ "opentelemetry", "percent-encoding", "rand 0.9.2", - "thiserror 2.0.17", + "thiserror 2.0.18", "tokio", "tokio-stream", ] @@ -2891,7 +2891,7 @@ dependencies = [ "rustc-hash", "rustls", "socket2", - "thiserror 2.0.17", + "thiserror 2.0.18", "tokio", "tracing", "web-time", @@ -2912,7 +2912,7 @@ dependencies = [ "rustls", "rustls-pki-types", "slab", - "thiserror 2.0.17", + "thiserror 2.0.18", "tinyvec", "tracing", "web-time", @@ -3187,7 +3187,7 @@ dependencies = [ "chrono-tz", "log", "regex", - "thiserror 2.0.17", + "thiserror 2.0.18", ] [[package]] @@ -3349,6 +3349,7 @@ dependencies = [ "rustical_store", "rustical_store_sqlite", "serde", + "similar-asserts", "sqlx", "tokio", "toml 0.9.11+spec-1.1.0", @@ -3393,7 +3394,7 @@ dependencies = [ "similar-asserts", "strum", "strum_macros", - "thiserror 2.0.17", + "thiserror 2.0.18", "tokio", "tower", "tower-http", @@ -3428,7 +3429,7 @@ dependencies = [ "serde", "strum", "strum_macros", - "thiserror 2.0.17", + "thiserror 2.0.18", "tokio", "tower", "tower-http", @@ -3457,7 +3458,7 @@ dependencies = [ "rustical_xml", "serde", "strum", - "thiserror 2.0.17", + "thiserror 2.0.18", "tokio", "tower", "tracing", @@ -3483,7 +3484,7 @@ dependencies = [ "rustical_store", "rustical_xml", "serde", - "thiserror 2.0.17", + "thiserror 2.0.18", "tokio", "tracing", ] @@ -3513,7 +3514,7 @@ dependencies = [ "rustical_store", "serde", "serde_json", - "thiserror 2.0.17", + "thiserror 2.0.18", "tokio", "tower", "tower-http", @@ -3540,7 +3541,7 @@ dependencies = [ "serde", "sha2", "similar-asserts", - "thiserror 2.0.17", + "thiserror 2.0.18", ] [[package]] @@ -3554,7 +3555,7 @@ dependencies = [ "openidconnect", "reqwest", "serde", - "thiserror 2.0.17", + "thiserror 2.0.18", "tower-sessions", "tracing", ] @@ -3584,7 +3585,7 @@ dependencies = [ "rustical_xml", "serde", "sha2", - "thiserror 2.0.17", + "thiserror 2.0.18", "tokio", "tower", "tower-sessions", @@ -3611,7 +3612,7 @@ dependencies = [ "serde", "sha2", "sqlx", - "thiserror 2.0.17", + "thiserror 2.0.18", "tokio", "tracing", "uuid", @@ -3622,7 +3623,7 @@ name = "rustical_xml" version = "0.11.17" dependencies = [ "quick-xml", - "thiserror 2.0.17", + "thiserror 2.0.18", "xml_derive", ] @@ -3655,9 +3656,9 @@ dependencies = [ [[package]] name = "rustls-pki-types" -version = "1.13.3" +version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4910321ebe4151be888e35fe062169554e74aad01beafed60410131420ceffbc" +checksum = "be040f8b0a225e40375822a563fa9524378b9d63112f53e19ffff34df5d33fdd" dependencies = [ "web-time", "zeroize", @@ -3665,9 +3666,9 @@ dependencies = [ [[package]] name = "rustls-webpki" -version = "0.103.8" +version = "0.103.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ffdfa2f5286e2247234e03f680868ac2815974dc39e00ea15adc445d0aafe52" +checksum = "d7df23109aa6c1567d1c575b9952556388da57401e4ace1d15f79eedad0d8f53" dependencies = [ "ring", "rustls-pki-types", @@ -4047,7 +4048,7 @@ dependencies = [ "serde_json", "sha2", "smallvec", - "thiserror 2.0.17", + "thiserror 2.0.18", "tokio", "tokio-stream", "tracing", @@ -4131,7 +4132,7 @@ dependencies = [ "smallvec", "sqlx-core", "stringprep", - "thiserror 2.0.17", + "thiserror 2.0.18", "tracing", "uuid", "whoami", @@ -4170,7 +4171,7 @@ dependencies = [ "smallvec", "sqlx-core", "stringprep", - "thiserror 2.0.17", + "thiserror 2.0.18", "tracing", "uuid", "whoami", @@ -4196,7 +4197,7 @@ dependencies = [ "serde", "serde_urlencoded", "sqlx-core", - "thiserror 2.0.17", + "thiserror 2.0.18", "tracing", "url", "uuid", @@ -4315,11 +4316,11 @@ dependencies = [ [[package]] name = "thiserror" -version = "2.0.17" +version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f63587ca0f12b72a0600bcba1d40081f830876000bb46dd2337a3051618f4fc8" +checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4" dependencies = [ - "thiserror-impl 2.0.17", + "thiserror-impl 2.0.18", ] [[package]] @@ -4335,9 +4336,9 @@ dependencies = [ [[package]] name = "thiserror-impl" -version = "2.0.17" +version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913" +checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" dependencies = [ "proc-macro2", "quote", @@ -4719,7 +4720,7 @@ dependencies = [ "rand 0.8.5", "serde", "serde_json", - "thiserror 2.0.17", + "thiserror 2.0.18", "time", "tokio", "tracing", @@ -5562,6 +5563,6 @@ dependencies = [ [[package]] name = "zmij" -version = "1.0.14" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd8f3f50b848df28f887acb68e41201b5aea6bc8a8dacc00fb40635ff9a72fea" +checksum = "94f63c051f4fe3c1509da62131a678643c5b6fbdc9273b2b79d4378ebda003d2" diff --git a/Cargo.toml b/Cargo.toml index 488c0c1..c8ba8f2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -153,6 +153,7 @@ criterion = { version = "0.8", features = ["async_tokio"] } rstest.workspace = true rustical_store_sqlite = { workspace = true, features = ["test"] } insta.workspace = true +similar-asserts.workspace = true [dependencies] rustical_store.workspace = true diff --git a/src/integration_tests/caldav/calendar_report.rs b/src/integration_tests/caldav/calendar_report.rs index 879e6f3..02974ff 100644 --- a/src/integration_tests/caldav/calendar_report.rs +++ b/src/integration_tests/caldav/calendar_report.rs @@ -87,70 +87,79 @@ const REPORT_7_8_3: &str = r#" "#; -const OUTPUT_7_8_3: &str = r#" - - http://cal.example.com/bernard/work/abcd2.ics - - - "fffff-abcd2" - BEGIN:VCALENDAR - VERSION:2.0 - PRODID:-//Example Corp.//CalDAV Client//EN - BEGIN:VEVENT - DTSTAMP:20060206T001121Z - DTSTART:20060103T170000 - DURATION:PT1H - RECURRENCE-ID:20060103T170000 - SUMMARY:Event #2 - UID:00959BC664CA650E933C892C@example.com - END:VEVENT - BEGIN:VEVENT - DTSTAMP:20060206T001121Z - DTSTART:20060104T190000 - DURATION:PT1H - RECURRENCE-ID:20060104T170000 - SUMMARY:Event #2 bis - UID:00959BC664CA650E933C892C@example.com - END:VEVENT - END:VCALENDAR - - - HTTP/1.1 200 OK - - - - http://cal.example.com/bernard/work/abcd3.ics - - - "fffff-abcd3" - BEGIN:VCALENDAR - VERSION:2.0 - PRODID:-//Example Corp.//CalDAV Client//EN - BEGIN:VEVENT - ATTENDEE;PARTSTAT=ACCEPTED;ROLE=CHAIR:mailto:cyrus@example.com - ATTENDEE;PARTSTAT=NEEDS-ACTION:mailto:lisa@example.com - DTSTAMP:20060206T001220Z - DTSTART:20060104T150000 - 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 - - - HTTP/1.1 200 OK - -"#; +// Adapted from Example 7.8.3 of RFC 4791 +// In the RFC the output is wrong since it returns DTSTART in UTC as local time, e.g. +// DTSTART:20060103T170000 +// instead of +// DTSTART:20060103T170000Z +// In https://datatracker.ietf.org/doc/html/rfc4791#section-9.6.5 +// it is clearly stated that times with timezone information MUST be returned in UTC. +// Also, the RECURRENCE-ID needs to include the TIMEZONE, which is fixed here by converting it to +// UTC +const OUTPUT_7_8_3: &str = r#" + + + /caldav/principal/user/calendar/abcd2.ics + + + BEGIN:VCALENDAR +VERSION:2.0 +PRODID:-//Example Corp.//CalDAV Client//EN +BEGIN:VEVENT +DTSTAMP:20060206T001121Z +DTSTART:20060103T170000Z +DURATION:PT1H +SUMMARY:Event #2 +UID:abcd2 +RECURRENCE-ID:20060103T170000Z +END:VEVENT +BEGIN:VEVENT +DTSTAMP:20060206T001121Z +DTSTART:20060104T190000Z +DURATION:PT1H +RECURRENCE-ID:20060104T170000Z +SUMMARY:Event #2 bis +UID:abcd2 +END:VEVENT +END:VCALENDAR + + + HTTP/1.1 200 OK + + + + /caldav/principal/user/calendar/abcd3.ics + + + BEGIN:VCALENDAR +VERSION:2.0 +PRODID:-//Example Corp.//CalDAV Client//EN +BEGIN:VEVENT +ATTENDEE;PARTSTAT=ACCEPTED;ROLE=CHAIR:mailto:cyrus@example.com +ATTENDEE;PARTSTAT=NEEDS-ACTION:mailto:lisa@example.com +DTSTAMP:20060206T001220Z +DTSTART:20060104T150000Z +DURATION:PT1H +LAST-MODIFIED:20060206T001330Z +ORGANIZER:mailto:cyrus@example.com +SEQUENCE:1 +STATUS:TENTATIVE +SUMMARY:Event #3 +UID:abcd3 +X-ABC-GUID:E1CX5Dr-0007ym-Hz@example.com +END:VEVENT +END:VCALENDAR + + + HTTP/1.1 200 OK + + +"#; #[rstest] -#[case(0, ICS_1, REPORT_7_8_1)] -#[case(1, ICS_1, REPORT_7_8_2)] -#[case(2, ICS_1, REPORT_7_8_3)] +#[case(0, ICS_1, REPORT_7_8_1, None)] +#[case(1, ICS_1, REPORT_7_8_2, None)] +#[case(2, ICS_1, REPORT_7_8_3, Some(OUTPUT_7_8_3))] #[tokio::test] async fn test_report( #[from(test_store_context)] @@ -159,6 +168,7 @@ async fn test_report( #[case] case: usize, #[case] ics: &'static str, #[case] report: &'static str, + #[case] output: Option<&'static str>, ) { let context = context.await; let app = get_app(context.clone()); @@ -193,4 +203,7 @@ async fn test_report( assert_eq!(response.status(), StatusCode::MULTI_STATUS); let body = response.extract_string().await; insta::assert_snapshot!(format!("{case}_report_body"), body); + if let Some(output) = output { + similar_asserts::assert_eq!(output, body.replace('\r', "")); + } } diff --git a/src/integration_tests/caldav/mod.rs b/src/integration_tests/caldav/mod.rs index 3378fbe..4a91cd7 100644 --- a/src/integration_tests/caldav/mod.rs +++ b/src/integration_tests/caldav/mod.rs @@ -9,7 +9,7 @@ use tower::ServiceExt; mod calendar; mod calendar_import; -// mod calendar_report; +mod calendar_report; #[rstest] #[tokio::test] diff --git a/src/integration_tests/caldav/resources/rfc4791_appb.ics b/src/integration_tests/caldav/resources/rfc4791_appb.ics index ea74a96..4ab2a03 100644 --- a/src/integration_tests/caldav/resources/rfc4791_appb.ics +++ b/src/integration_tests/caldav/resources/rfc4791_appb.ics @@ -55,6 +55,7 @@ SEQUENCE:1 STATUS:TENTATIVE SUMMARY:Event #3 UID:abcd3 +X-ABC-GUID:E1CX5Dr-0007ym-Hz@example.com END:VEVENT BEGIN:VTODO DTSTAMP:20060205T235335Z diff --git a/src/integration_tests/caldav/snapshots/rustical__integration_tests__caldav__calendar_import__1_get_body.snap b/src/integration_tests/caldav/snapshots/rustical__integration_tests__caldav__calendar_import__1_get_body.snap index 2cdafb5..059168d 100644 --- a/src/integration_tests/caldav/snapshots/rustical__integration_tests__caldav__calendar_import__1_get_body.snap +++ b/src/integration_tests/caldav/snapshots/rustical__integration_tests__caldav__calendar_import__1_get_body.snap @@ -60,6 +60,7 @@ SEQUENCE:1 STATUS:TENTATIVE SUMMARY:Event #3 UID:[UID] +X-ABC-GUID:[UID] END:VEVENT BEGIN:VTODO DTSTAMP:20060205T235335Z diff --git a/src/integration_tests/caldav/snapshots/rustical__integration_tests__caldav__calendar_report__0_report_body.snap b/src/integration_tests/caldav/snapshots/rustical__integration_tests__caldav__calendar_report__0_report_body.snap index b179127..79834cc 100644 --- a/src/integration_tests/caldav/snapshots/rustical__integration_tests__caldav__calendar_report__0_report_body.snap +++ b/src/integration_tests/caldav/snapshots/rustical__integration_tests__caldav__calendar_report__0_report_body.snap @@ -56,7 +56,7 @@ END:VCALENDAR /caldav/principal/user/calendar/abcd3.ics - "c6a5b1cf6985805686df99e7f2e1cf286567dcb3383fc6fa1b12ce42d3fbc01c" + "a84fd022dfc742bf8f17ac04fca3aad687e9ae724180185e8e0df11e432dae30" BEGIN:VCALENDAR VERSION:2.0 PRODID:-//Example Corp.//CalDAV Client//EN @@ -90,6 +90,7 @@ SEQUENCE:1 STATUS:TENTATIVE SUMMARY:Event #3 UID:abcd3 +X-ABC-GUID:E1CX5Dr-0007ym-Hz@example.com END:VEVENT END:VCALENDAR diff --git a/src/integration_tests/caldav/snapshots/rustical__integration_tests__caldav__calendar_report__1_report_body.snap b/src/integration_tests/caldav/snapshots/rustical__integration_tests__caldav__calendar_report__1_report_body.snap index f3e413b..09add03 100644 --- a/src/integration_tests/caldav/snapshots/rustical__integration_tests__caldav__calendar_report__1_report_body.snap +++ b/src/integration_tests/caldav/snapshots/rustical__integration_tests__caldav__calendar_report__1_report_body.snap @@ -88,6 +88,7 @@ SEQUENCE:1 STATUS:TENTATIVE SUMMARY:Event #3 UID:abcd3 +X-ABC-GUID:E1CX5Dr-0007ym-Hz@example.com END:VEVENT END:VCALENDAR diff --git a/src/integration_tests/caldav/snapshots/rustical__integration_tests__caldav__calendar_report__2_report_body.snap b/src/integration_tests/caldav/snapshots/rustical__integration_tests__caldav__calendar_report__2_report_body.snap index 9801e29..0ae78e9 100644 --- a/src/integration_tests/caldav/snapshots/rustical__integration_tests__caldav__calendar_report__2_report_body.snap +++ b/src/integration_tests/caldav/snapshots/rustical__integration_tests__caldav__calendar_report__2_report_body.snap @@ -13,19 +13,19 @@ VERSION:2.0 PRODID:-//Example Corp.//CalDAV Client//EN BEGIN:VEVENT DTSTAMP:20060206T001121Z +DTSTART:20060103T170000Z DURATION:PT1H SUMMARY:Event #2 UID:abcd2 RECURRENCE-ID:20060103T170000Z -DTSTART:20060103T170000Z END:VEVENT BEGIN:VEVENT DTSTAMP:20060206T001121Z +DTSTART:20060104T190000Z DURATION:PT1H -SUMMARY:Event #2 -UID:abcd2 RECURRENCE-ID:20060104T170000Z -DTSTART:20060104T170000Z +SUMMARY:Event #2 bis +UID:abcd2 END:VEVENT END:VCALENDAR @@ -44,7 +44,7 @@ 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 +DTSTART:20060104T150000Z DURATION:PT1H LAST-MODIFIED:20060206T001330Z ORGANIZER:mailto:cyrus@example.com @@ -52,6 +52,7 @@ SEQUENCE:1 STATUS:TENTATIVE SUMMARY:Event #3 UID:abcd3 +X-ABC-GUID:E1CX5Dr-0007ym-Hz@example.com END:VEVENT END:VCALENDAR