Re-enable calendar-query test and fix calendar expansion

This commit is contained in:
Lennart
2026-01-19 12:09:34 +01:00
parent 7e099bcd6e
commit f73658b32f
9 changed files with 128 additions and 108 deletions

79
Cargo.lock generated
View File

@@ -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"

View File

@@ -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

View File

@@ -87,70 +87,79 @@ const REPORT_7_8_3: &str = r#"
</C:calendar-query>
"#;
const OUTPUT_7_8_3: &str = r#"
<D:response>
<D:href>http://cal.example.com/bernard/work/abcd2.ics</D:href>
<D:propstat>
<D:prop>
<D:getetag>"fffff-abcd2"</D:getetag>
<C:calendar-data>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
</C:calendar-data>
</D:prop>
<D:status>HTTP/1.1 200 OK</D:status>
</D:propstat>
</D:response>
<D:response>
<D:href>http://cal.example.com/bernard/work/abcd3.ics</D:href>
<D:propstat>
<D:prop>
<D:getetag>"fffff-abcd3"</D:getetag>
<C:calendar-data>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
</C:calendar-data>
</D:prop>
<D:status>HTTP/1.1 200 OK</D:status>
</D:propstat>
"#;
// 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#"<?xml version="1.0" encoding="utf-8"?>
<multistatus xmlns="DAV:" xmlns:CAL="urn:ietf:params:xml:ns:caldav" xmlns:CARD="urn:ietf:params:xml:ns:carddav" xmlns:CS="http://calendarserver.org/ns/" xmlns:PUSH="https://bitfire.at/webdav-push">
<response>
<href>/caldav/principal/user/calendar/abcd2.ics</href>
<propstat>
<prop>
<CAL:calendar-data>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
</CAL:calendar-data>
</prop>
<status>HTTP/1.1 200 OK</status>
</propstat>
</response>
<response>
<href>/caldav/principal/user/calendar/abcd3.ics</href>
<propstat>
<prop>
<CAL:calendar-data>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
</CAL:calendar-data>
</prop>
<status>HTTP/1.1 200 OK</status>
</propstat>
</response>
</multistatus>"#;
#[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', ""));
}
}

View File

@@ -9,7 +9,7 @@ use tower::ServiceExt;
mod calendar;
mod calendar_import;
// mod calendar_report;
mod calendar_report;
#[rstest]
#[tokio::test]

View File

@@ -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

View File

@@ -60,6 +60,7 @@ SEQUENCE:1
STATUS:TENTATIVE
SUMMARY:Event #3
UID:[UID]
X-ABC-GUID:[UID]
END:VEVENT
BEGIN:VTODO
DTSTAMP:20060205T235335Z

View File

@@ -56,7 +56,7 @@ END:VCALENDAR
<href>/caldav/principal/user/calendar/abcd3.ics</href>
<propstat>
<prop>
<getetag>&quot;c6a5b1cf6985805686df99e7f2e1cf286567dcb3383fc6fa1b12ce42d3fbc01c&quot;</getetag>
<getetag>&quot;a84fd022dfc742bf8f17ac04fca3aad687e9ae724180185e8e0df11e432dae30&quot;</getetag>
<CAL:calendar-data>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
</CAL:calendar-data>

View File

@@ -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
</CAL:calendar-data>

View File

@@ -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
</CAL:calendar-data>
@@ -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
</CAL:calendar-data>