Add test to make sure that objects from Thunderbird are accepted

see #173
This commit is contained in:
Lennart K
2026-01-31 14:16:57 +01:00
parent 5ec40b97e3
commit cc333f7182
2 changed files with 256 additions and 0 deletions

View File

@@ -72,3 +72,53 @@ END:VCALENDAR";
</error>
"#);
}
/// Thunderbird creates VTIMEZONE objects with invalid RRULEs.
/// While invalid, we still want to accept them since Thunderbird is quite commonly used.
/// In the future, we might fix invalid timezones ourself.
#[rstest]
#[tokio::test]
async fn test_put_thunderbird(
#[from(test_store_context)]
#[future]
context: TestStoreContext,
) {
let context = context.await;
let app = get_app(context.clone());
let calendar_meta = CalendarMetadata {
displayname: Some("Calendar".to_string()),
description: Some("Description".to_string()),
color: Some("#00FF00".to_string()),
order: 0,
};
let (principal, cal_id) = ("user", "calendar");
let url = format!("/caldav/principal/{principal}/{cal_id}");
let mut request = Request::builder()
.method("MKCALENDAR")
.uri(&url)
.body(Body::from(mkcalendar_template(&calendar_meta)))
.unwrap();
request
.headers_mut()
.typed_insert(Authorization::basic("user", "pass"));
let response = app.clone().oneshot(request).await.unwrap();
assert_eq!(response.status(), StatusCode::CREATED);
let ical = include_str!("resources/ical_thunderbird.ics");
let mut request = Request::builder()
.method("PUT")
.uri(format!("{url}/qwue23489.ics"))
.header("If-None-Match", "*")
.header("Content-Type", "text/calendar")
.body(Body::from(ical))
.unwrap();
request
.headers_mut()
.typed_insert(Authorization::basic("user", "pass"));
let response = app.clone().oneshot(request).await.unwrap();
assert_eq!(response.status(), StatusCode::CREATED);
}

View File

@@ -0,0 +1,206 @@
BEGIN:VCALENDAR
PRODID:-//Mozilla.org/NONSGML Mozilla Calendar V1.1//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Europe/Berlin
X-TZINFO:Europe/Berlin[2025b]
BEGIN:STANDARD
TZOFFSETTO:+010000
TZOFFSETFROM:+005328
TZNAME:Europe/Berlin(STD)
DTSTART:18930401T000000
RDATE:18930401T000000
END:STANDARD
BEGIN:DAYLIGHT
TZOFFSETTO:+020000
TZOFFSETFROM:+010000
TZNAME:Europe/Berlin(DST)
DTSTART:19160430T230000
RDATE:19160430T230000
END:DAYLIGHT
BEGIN:STANDARD
TZOFFSETTO:+010000
TZOFFSETFROM:+020000
TZNAME:Europe/Berlin(STD)
DTSTART:19161001T010000
RDATE:19161001T010000
END:STANDARD
BEGIN:DAYLIGHT
TZOFFSETTO:+020000
TZOFFSETFROM:+010000
TZNAME:Europe/Berlin(DST)
DTSTART:19170416T020000
RRULE:FREQ=YEARLY;BYMONTH=4;BYDAY=3MO;UNTIL=19180415T020000
END:DAYLIGHT
BEGIN:STANDARD
TZOFFSETTO:+010000
TZOFFSETFROM:+020000
TZNAME:Europe/Berlin(STD)
DTSTART:19170917T030000
RRULE:FREQ=YEARLY;BYMONTH=9;BYDAY=3MO;UNTIL=19180916T030000
END:STANDARD
BEGIN:DAYLIGHT
TZOFFSETTO:+020000
TZOFFSETFROM:+010000
TZNAME:Europe/Berlin(DST)
DTSTART:19400401T020000
RDATE:19400401T020000
END:DAYLIGHT
BEGIN:STANDARD
TZOFFSETTO:+010000
TZOFFSETFROM:+020000
TZNAME:Europe/Berlin(STD)
DTSTART:19421102T030000
RDATE:19421102T030000
END:STANDARD
BEGIN:DAYLIGHT
TZOFFSETTO:+020000
TZOFFSETFROM:+010000
TZNAME:Europe/Berlin(DST)
DTSTART:19430329T020000
RDATE:19430329T020000
END:DAYLIGHT
BEGIN:DAYLIGHT
TZOFFSETTO:+020000
TZOFFSETFROM:+010000
TZNAME:Europe/Berlin(DST)
DTSTART:19440403T020000
RRULE:FREQ=YEARLY;BYMONTH=4;BYDAY=1MO;UNTIL=19450402T020000
END:DAYLIGHT
BEGIN:DAYLIGHT
TZOFFSETTO:+030000
TZOFFSETFROM:+020000
TZNAME:Europe/Berlin(DST)
DTSTART:19450524T020000
RDATE:19450524T020000
END:DAYLIGHT
BEGIN:STANDARD
TZOFFSETTO:+010000
TZOFFSETFROM:+020000
TZNAME:Europe/Berlin(STD)
DTSTART:19431004T030000
RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=1MO;UNTIL=19441002T030000
END:STANDARD
BEGIN:DAYLIGHT
TZOFFSETTO:+020000
TZOFFSETFROM:+030000
TZNAME:Europe/Berlin(DST)
DTSTART:19450924T030000
RDATE:19450924T030000
END:DAYLIGHT
BEGIN:STANDARD
TZOFFSETTO:+010000
TZOFFSETFROM:+020000
TZNAME:Europe/Berlin(STD)
DTSTART:19451118T030000
RDATE:19451118T030000
END:STANDARD
BEGIN:DAYLIGHT
TZOFFSETTO:+020000
TZOFFSETFROM:+010000
TZNAME:Europe/Berlin(DST)
DTSTART:19460414T020000
RDATE:19460414T020000
END:DAYLIGHT
BEGIN:DAYLIGHT
TZOFFSETTO:+020000
TZOFFSETFROM:+010000
TZNAME:Europe/Berlin(DST)
DTSTART:19470406T030000
RDATE:19470406T030000
END:DAYLIGHT
BEGIN:DAYLIGHT
TZOFFSETTO:+030000
TZOFFSETFROM:+020000
TZNAME:Europe/Berlin(DST)
DTSTART:19470511T030000
RDATE:19470511T030000
END:DAYLIGHT
BEGIN:STANDARD
TZOFFSETTO:+010000
TZOFFSETFROM:+020000
TZNAME:Europe/Berlin(STD)
DTSTART:19461007T030000
RDATE:19461007T030000
END:STANDARD
BEGIN:DAYLIGHT
TZOFFSETTO:+020000
TZOFFSETFROM:+030000
TZNAME:Europe/Berlin(DST)
DTSTART:19470629T030000
RDATE:19470629T030000
END:DAYLIGHT
BEGIN:DAYLIGHT
TZOFFSETTO:+020000
TZOFFSETFROM:+010000
TZNAME:Europe/Berlin(DST)
DTSTART:19480418T020000
RDATE:19480418T020000
END:DAYLIGHT
BEGIN:DAYLIGHT
TZOFFSETTO:+020000
TZOFFSETFROM:+010000
TZNAME:Europe/Berlin(DST)
DTSTART:19490410T020000
RDATE:19490410T020000
END:DAYLIGHT
BEGIN:STANDARD
TZOFFSETTO:+010000
TZOFFSETFROM:+020000
TZNAME:Europe/Berlin(STD)
DTSTART:19471005T030000
RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=1SU;UNTIL=19491002T030000
END:STANDARD
BEGIN:DAYLIGHT
TZOFFSETTO:+020000
TZOFFSETFROM:+010000
TZNAME:Europe/Berlin(DST)
DTSTART:19800406T020000
RDATE:19800406T020000
END:DAYLIGHT
BEGIN:STANDARD
TZOFFSETTO:+010000
TZOFFSETFROM:+020000
TZNAME:Europe/Berlin(STD)
DTSTART:19800928T030000
RRULE:FREQ=YEARLY;BYMONTH=9;BYDAY=-1SU;UNTIL=19950924T030000
END:STANDARD
BEGIN:DAYLIGHT
TZOFFSETTO:+020000
TZOFFSETFROM:+010000
TZNAME:Europe/Berlin(DST)
DTSTART:19810329T020000
RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU;UNTIL=19960331T020000
END:DAYLIGHT
BEGIN:STANDARD
TZOFFSETTO:+010000
TZOFFSETFROM:+020000
TZNAME:Europe/Berlin(STD)
DTSTART:19961027T030000
RDATE:19961027T030000
END:STANDARD
BEGIN:DAYLIGHT
TZOFFSETTO:+020000
TZOFFSETFROM:+010000
TZNAME:(DST)
DTSTART:19970330T020000
RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU
END:DAYLIGHT
BEGIN:STANDARD
TZOFFSETTO:+010000
TZOFFSETFROM:+020000
TZNAME:(STD)
DTSTART:19971026T030000
RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU
END:STANDARD
END:VTIMEZONE
BEGIN:VEVENT
CREATED:20260130T134029Z
LAST-MODIFIED:20260130T134029Z
DTSTAMP:20260130T134029Z
UID:620c612d-2b03-4fcf-97c7-8fecd6e18565
DTSTART;TZID=Europe/Berlin:20260130T050000
DTEND;TZID=Europe/Berlin:20260130T070000
TRANSP:OPAQUE
END:VEVENT
END:VCALENDAR