diff --git a/src/integration_tests/caldav/calendar.rs b/src/integration_tests/caldav/calendar.rs new file mode 100644 index 0000000..d09d7eb --- /dev/null +++ b/src/integration_tests/caldav/calendar.rs @@ -0,0 +1,105 @@ +use crate::integration_tests::{ResponseExtractString, get_app}; +use axum::body::{Body, Bytes}; +use axum::extract::Request; +use headers::{Authorization, HeaderMapExt}; +use http::{HeaderValue, StatusCode}; +use rstest::rstest; +use rustical_store::{Calendar, CalendarMetadata}; +use tower::ServiceExt; + +const MKCOL_REQUEST: &str = r#" + + + + + + + + + Amazing Calendar + Description + #FFF8DCFF + Europe/Berlin + + + + + + + + + "#; + +#[rstest] +#[tokio::test] +async fn test_caldav_calendar( + #[from(get_app)] + #[future] + app: axum::Router, +) { + let app = app.await; + + let request_template = || { + Request::builder() + .method("MKCALENDAR") + .uri("/caldav/principal/user/calendar") + .body(Body::from(MKCOL_REQUEST)) + .unwrap() + }; + + // Try without authentication + let request = request_template(); + let response = app.clone().oneshot(request).await.unwrap(); + assert_eq!(response.status(), StatusCode::UNAUTHORIZED); + let body = response.extract_string().await; + insta::assert_snapshot!(body); + + // Try with correct credentials + let mut request = request_template(); + request + .headers_mut() + .typed_insert(Authorization::basic("user", "pass")); + let response = app.clone().oneshot(request).await.unwrap(); + assert_eq!(response.status(), StatusCode::CREATED); + let body = response.extract_string().await; + insta::assert_snapshot!(body); + + let mut request = Request::builder() + .method("GET") + .uri("/caldav/principal/user/calendar") + .body(Body::empty()) + .unwrap(); + request + .headers_mut() + .typed_insert(Authorization::basic("user", "pass")); + let response = app.clone().oneshot(request).await.unwrap(); + assert_eq!(response.status(), StatusCode::OK); + let body = response.extract_string().await; + insta::assert_snapshot!(body); + + let mut request = Request::builder() + .method("PROPFIND") + .uri("/caldav/principal/user/calendar") + .body(Body::empty()) + .unwrap(); + request + .headers_mut() + .typed_insert(Authorization::basic("user", "pass")); + let response = app.clone().oneshot(request).await.unwrap(); + assert_eq!(response.status(), StatusCode::MULTI_STATUS); + let body = response.extract_string().await; + insta::assert_snapshot!(body); + + let mut request = Request::builder() + .method("DELETE") + .uri("/caldav/principal/user/calendar") + .body(Body::empty()) + .unwrap(); + request + .headers_mut() + .typed_insert(Authorization::basic("user", "pass")); + let response = app.clone().oneshot(request).await.unwrap(); + assert_eq!(response.status(), StatusCode::OK); + let body = response.extract_string().await; + insta::assert_snapshot!(body); +} diff --git a/src/integration_tests/caldav/mod.rs b/src/integration_tests/caldav/mod.rs index 72cd78d..85cffbc 100644 --- a/src/integration_tests/caldav/mod.rs +++ b/src/integration_tests/caldav/mod.rs @@ -6,6 +6,8 @@ use http::{HeaderValue, StatusCode}; use rstest::rstest; use tower::ServiceExt; +mod calendar; + #[rstest] #[tokio::test] async fn test_caldav_root( diff --git a/src/integration_tests/caldav/snapshots/rustical__integration_tests__caldav__caldav_principal-4.snap b/src/integration_tests/caldav/snapshots/rustical__integration_tests__caldav__caldav_principal-4.snap index dfabdac..46158ec 100644 --- a/src/integration_tests/caldav/snapshots/rustical__integration_tests__caldav__caldav_principal-4.snap +++ b/src/integration_tests/caldav/snapshots/rustical__integration_tests__caldav__caldav_principal-4.snap @@ -50,4 +50,192 @@ expression: body HTTP/1.1 200 OK + + /caldav/principal/user/calendar/ + + + #FFF8DCFF + Description + BEGIN:VCALENDAR +PRODID:-//github.com/lennart-k/vzic-rs//RustiCal Calendar server//EN +VERSION:2.0 +BEGIN:VTIMEZONE +TZID:Europe/Berlin +LAST-MODIFIED:20250723T190331Z +X-LIC-LOCATION:Europe/Berlin +X-PROLEPTIC-TZNAME:LMT +BEGIN:STANDARD +TZNAME:CET +TZOFFSETFROM:+005328 +TZOFFSETTO:+0100 +DTSTART:18930401T000000 +END:STANDARD +BEGIN:DAYLIGHT +TZNAME:CEST +TZOFFSETFROM:+0100 +TZOFFSETTO:+0200 +DTSTART:19160430T230000 +RDATE:19400401T020000 +RDATE:19430329T020000 +RDATE:19460414T020000 +RDATE:19470406T030000 +RDATE:19480418T020000 +RDATE:19490410T020000 +RDATE:19800406T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZNAME:CET +TZOFFSETFROM:+0200 +TZOFFSETTO:+0100 +DTSTART:19161001T010000 +RDATE:19421102T030000 +RDATE:19431004T030000 +RDATE:19441002T030000 +RDATE:19451118T030000 +RDATE:19461007T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZNAME:CEST +TZOFFSETFROM:+0100 +TZOFFSETTO:+0200 +DTSTART:19170416T020000 +RRULE:FREQ=YEARLY;BYMONTH=4;BYDAY=3MO;UNTIL=19180415T010000Z +END:DAYLIGHT +BEGIN:STANDARD +TZNAME:CET +TZOFFSETFROM:+0200 +TZOFFSETTO:+0100 +DTSTART:19170917T030000 +RRULE:FREQ=YEARLY;BYMONTH=9;BYDAY=3MO;UNTIL=19180916T010000Z +END:STANDARD +BEGIN:DAYLIGHT +TZNAME:CEST +TZOFFSETFROM:+0100 +TZOFFSETTO:+0200 +DTSTART:19440403T020000 +RRULE:FREQ=YEARLY;BYMONTH=4;BYDAY=1MO;UNTIL=19450402T010000Z +END:DAYLIGHT +BEGIN:DAYLIGHT +TZNAME:CEMT +TZOFFSETFROM:+0200 +TZOFFSETTO:+0300 +DTSTART:19450524T020000 +RDATE:19470511T030000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZNAME:CEST +TZOFFSETFROM:+0300 +TZOFFSETTO:+0200 +DTSTART:19450924T030000 +RDATE:19470629T030000 +END:DAYLIGHT +BEGIN:STANDARD +TZNAME:CET +TZOFFSETFROM:+0100 +TZOFFSETTO:+0100 +DTSTART:19460101T000000 +RDATE:19800101T000000 +END:STANDARD +BEGIN:STANDARD +TZNAME:CET +TZOFFSETFROM:+0200 +TZOFFSETTO:+0100 +DTSTART:19471005T030000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=1SU;UNTIL=19491002T010000Z +END:STANDARD +BEGIN:STANDARD +TZNAME:CET +TZOFFSETFROM:+0200 +TZOFFSETTO:+0100 +DTSTART:19800928T030000 +RRULE:FREQ=YEARLY;BYMONTH=9;BYDAY=-1SU;UNTIL=19950924T010000Z +END:STANDARD +BEGIN:DAYLIGHT +TZNAME:CEST +TZOFFSETFROM:+0100 +TZOFFSETTO:+0200 +DTSTART:19810329T020000 +RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU +END:DAYLIGHT +BEGIN:STANDARD +TZNAME:CET +TZOFFSETFROM:+0200 +TZOFFSETTO:+0100 +DTSTART:19961027T030000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU +END:STANDARD +END:VTIMEZONE +END:VCALENDAR + + + https://www.iana.org/time-zones + + Europe/Berlin + 0 + + + + + + + + + + i;ascii-casemap + i;octet + + 10000000 + + + + + + + + + + + + + + + + + + -2621430101T000000Z + +2621421231T235959Z + github.com/lennart-k/rustical/ns/0 + github.com/lennart-k/rustical/ns/0 + + + + 89828c25-cc5c-481a-bb3b-cde435cf9393 + + + 1 + + + 1 + + + + + + + Amazing Calendar + + /caldav/principal/user/ + + + + + + + + /caldav/principal/user/ + + + HTTP/1.1 200 OK + + diff --git a/src/integration_tests/caldav/snapshots/rustical__integration_tests__caldav__calendar__caldav_calendar-2.snap b/src/integration_tests/caldav/snapshots/rustical__integration_tests__caldav__calendar__caldav_calendar-2.snap new file mode 100644 index 0000000..ae58472 --- /dev/null +++ b/src/integration_tests/caldav/snapshots/rustical__integration_tests__caldav__calendar__caldav_calendar-2.snap @@ -0,0 +1,5 @@ +--- +source: src/integration_tests/caldav/calendar.rs +expression: body +--- + diff --git a/src/integration_tests/caldav/snapshots/rustical__integration_tests__caldav__calendar__caldav_calendar-3.snap b/src/integration_tests/caldav/snapshots/rustical__integration_tests__caldav__calendar__caldav_calendar-3.snap new file mode 100644 index 0000000..5963b3c --- /dev/null +++ b/src/integration_tests/caldav/snapshots/rustical__integration_tests__caldav__calendar__caldav_calendar-3.snap @@ -0,0 +1,12 @@ +--- +source: src/integration_tests/caldav/calendar.rs +expression: body +--- +BEGIN:VCALENDAR +VERSION:4.0 +CALSCALE:GREGORIAN +PRODID:RustiCal +X-WR-CALNAME:Amazing Calendar +X-WR-CALDESC:Description +X-WR-TIMEZONE:Europe/Berlin +END:VCALENDAR diff --git a/src/integration_tests/caldav/snapshots/rustical__integration_tests__caldav__calendar__caldav_calendar-4.snap b/src/integration_tests/caldav/snapshots/rustical__integration_tests__caldav__calendar__caldav_calendar-4.snap new file mode 100644 index 0000000..9231300 --- /dev/null +++ b/src/integration_tests/caldav/snapshots/rustical__integration_tests__caldav__calendar__caldav_calendar-4.snap @@ -0,0 +1,195 @@ +--- +source: src/integration_tests/caldav/calendar.rs +expression: body +--- + + + + /caldav/principal/user/calendar/ + + + #FFF8DCFF + Description + BEGIN:VCALENDAR +PRODID:-//github.com/lennart-k/vzic-rs//RustiCal Calendar server//EN +VERSION:2.0 +BEGIN:VTIMEZONE +TZID:Europe/Berlin +LAST-MODIFIED:20250723T190331Z +X-LIC-LOCATION:Europe/Berlin +X-PROLEPTIC-TZNAME:LMT +BEGIN:STANDARD +TZNAME:CET +TZOFFSETFROM:+005328 +TZOFFSETTO:+0100 +DTSTART:18930401T000000 +END:STANDARD +BEGIN:DAYLIGHT +TZNAME:CEST +TZOFFSETFROM:+0100 +TZOFFSETTO:+0200 +DTSTART:19160430T230000 +RDATE:19400401T020000 +RDATE:19430329T020000 +RDATE:19460414T020000 +RDATE:19470406T030000 +RDATE:19480418T020000 +RDATE:19490410T020000 +RDATE:19800406T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZNAME:CET +TZOFFSETFROM:+0200 +TZOFFSETTO:+0100 +DTSTART:19161001T010000 +RDATE:19421102T030000 +RDATE:19431004T030000 +RDATE:19441002T030000 +RDATE:19451118T030000 +RDATE:19461007T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZNAME:CEST +TZOFFSETFROM:+0100 +TZOFFSETTO:+0200 +DTSTART:19170416T020000 +RRULE:FREQ=YEARLY;BYMONTH=4;BYDAY=3MO;UNTIL=19180415T010000Z +END:DAYLIGHT +BEGIN:STANDARD +TZNAME:CET +TZOFFSETFROM:+0200 +TZOFFSETTO:+0100 +DTSTART:19170917T030000 +RRULE:FREQ=YEARLY;BYMONTH=9;BYDAY=3MO;UNTIL=19180916T010000Z +END:STANDARD +BEGIN:DAYLIGHT +TZNAME:CEST +TZOFFSETFROM:+0100 +TZOFFSETTO:+0200 +DTSTART:19440403T020000 +RRULE:FREQ=YEARLY;BYMONTH=4;BYDAY=1MO;UNTIL=19450402T010000Z +END:DAYLIGHT +BEGIN:DAYLIGHT +TZNAME:CEMT +TZOFFSETFROM:+0200 +TZOFFSETTO:+0300 +DTSTART:19450524T020000 +RDATE:19470511T030000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZNAME:CEST +TZOFFSETFROM:+0300 +TZOFFSETTO:+0200 +DTSTART:19450924T030000 +RDATE:19470629T030000 +END:DAYLIGHT +BEGIN:STANDARD +TZNAME:CET +TZOFFSETFROM:+0100 +TZOFFSETTO:+0100 +DTSTART:19460101T000000 +RDATE:19800101T000000 +END:STANDARD +BEGIN:STANDARD +TZNAME:CET +TZOFFSETFROM:+0200 +TZOFFSETTO:+0100 +DTSTART:19471005T030000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=1SU;UNTIL=19491002T010000Z +END:STANDARD +BEGIN:STANDARD +TZNAME:CET +TZOFFSETFROM:+0200 +TZOFFSETTO:+0100 +DTSTART:19800928T030000 +RRULE:FREQ=YEARLY;BYMONTH=9;BYDAY=-1SU;UNTIL=19950924T010000Z +END:STANDARD +BEGIN:DAYLIGHT +TZNAME:CEST +TZOFFSETFROM:+0100 +TZOFFSETTO:+0200 +DTSTART:19810329T020000 +RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU +END:DAYLIGHT +BEGIN:STANDARD +TZNAME:CET +TZOFFSETFROM:+0200 +TZOFFSETTO:+0100 +DTSTART:19961027T030000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU +END:STANDARD +END:VTIMEZONE +END:VCALENDAR + + + https://www.iana.org/time-zones + + Europe/Berlin + 0 + + + + + + + + + + i;ascii-casemap + i;octet + + 10000000 + + + + + + + + + + + + + + + + + + -2621430101T000000Z + +2621421231T235959Z + github.com/lennart-k/rustical/ns/0 + github.com/lennart-k/rustical/ns/0 + + + + 89828c25-cc5c-481a-bb3b-cde435cf9393 + + + 1 + + + 1 + + + + + + + Amazing Calendar + + /caldav/principal/user/ + + + + + + + + /caldav/principal/user/ + + + HTTP/1.1 200 OK + + + diff --git a/src/integration_tests/caldav/snapshots/rustical__integration_tests__caldav__calendar__caldav_calendar-5.snap b/src/integration_tests/caldav/snapshots/rustical__integration_tests__caldav__calendar__caldav_calendar-5.snap new file mode 100644 index 0000000..ae58472 --- /dev/null +++ b/src/integration_tests/caldav/snapshots/rustical__integration_tests__caldav__calendar__caldav_calendar-5.snap @@ -0,0 +1,5 @@ +--- +source: src/integration_tests/caldav/calendar.rs +expression: body +--- + diff --git a/src/integration_tests/caldav/snapshots/rustical__integration_tests__caldav__calendar__caldav_calendar.snap b/src/integration_tests/caldav/snapshots/rustical__integration_tests__caldav__calendar__caldav_calendar.snap new file mode 100644 index 0000000..ae58472 --- /dev/null +++ b/src/integration_tests/caldav/snapshots/rustical__integration_tests__caldav__calendar__caldav_calendar.snap @@ -0,0 +1,5 @@ +--- +source: src/integration_tests/caldav/calendar.rs +expression: body +--- +