use http::Uri;
use crate::{
dav::{FindPropertyHrefs, WebDavError},
names,
requests::{DavRequest, ParseResponseError, PreparedRequest},
};
pub struct FindCalendarHomeSet<'a> {
inner: FindPropertyHrefs<'a>,
}
impl FindCalendarHomeSet<'_> {
#[must_use]
pub fn new(principal: &Uri) -> Self {
Self {
inner: FindPropertyHrefs::new(principal, &names::CALENDAR_HOME_SET),
}
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct FindCalendarHomeSetResponse {
pub home_sets: Vec<Uri>,
}
impl DavRequest for FindCalendarHomeSet<'_> {
type Response = FindCalendarHomeSetResponse;
type ParseError = ParseResponseError;
type Error<E> = WebDavError<E>;
fn prepare_request(&self) -> Result<PreparedRequest, http::Error> {
self.inner.prepare_request()
}
fn parse_response(
&self,
parts: &http::response::Parts,
body: &[u8],
) -> Result<Self::Response, ParseResponseError> {
let response = self.inner.parse_response(parts, body)?;
Ok(FindCalendarHomeSetResponse {
home_sets: response.hrefs,
})
}
}
#[cfg(test)]
mod tests {
use super::*;
use http::{Method, StatusCode};
#[test]
fn test_prepare_request() {
let principal = Uri::from_static("https://example.com/principals/user/");
let req = FindCalendarHomeSet::new(&principal);
let prepared = req.prepare_request().unwrap();
assert_eq!(prepared.method, Method::from_bytes(b"PROPFIND").unwrap());
assert_eq!(prepared.path, "/principals/user/");
assert!(
prepared
.body
.contains(r#"xmlns:C="urn:ietf:params:xml:ns:caldav""#)
);
assert!(prepared.body.contains("<C:calendar-home-set/>"));
assert_eq!(
prepared.headers,
vec![
("Depth".to_string(), "0".to_string()),
(
"Content-Type".to_string(),
"application/xml; charset=utf-8".to_string()
)
]
);
}
#[test]
fn test_parse_response() {
let principal = Uri::from_static("https://example.com/principals/user/");
let req = FindCalendarHomeSet::new(&principal);
let response_xml = r#"<?xml version="1.0"?>
<multistatus xmlns="DAV:" xmlns:C="urn:ietf:params:xml:ns:caldav">
<response>
<href>/principals/user/</href>
<propstat>
<prop>
<C:calendar-home-set>
<href>/calendars/user/</href>
</C:calendar-home-set>
</prop>
<status>HTTP/1.1 200 OK</status>
</propstat>
</response>
</multistatus>"#;
let response = http::Response::builder()
.status(StatusCode::MULTI_STATUS)
.body(())
.unwrap();
let (parts, ()) = response.into_parts();
let result = req.parse_response(&parts, response_xml.as_bytes()).unwrap();
assert_eq!(result.home_sets.len(), 1);
assert_eq!(result.home_sets[0].path(), "/calendars/user/");
}
#[test]
fn test_parse_response_multiple_home_sets() {
let principal = Uri::from_static("https://example.com/principals/user/");
let req = FindCalendarHomeSet::new(&principal);
let response_xml = r#"<?xml version="1.0"?>
<multistatus xmlns="DAV:" xmlns:C="urn:ietf:params:xml:ns:caldav">
<response>
<href>/principals/user/</href>
<propstat>
<prop>
<C:calendar-home-set>
<href>/calendars/user/</href>
<href>/shared-calendars/</href>
</C:calendar-home-set>
</prop>
<status>HTTP/1.1 200 OK</status>
</propstat>
</response>
</multistatus>"#;
let response = http::Response::builder()
.status(StatusCode::MULTI_STATUS)
.body(())
.unwrap();
let (parts, ()) = response.into_parts();
let result = req.parse_response(&parts, response_xml.as_bytes()).unwrap();
assert_eq!(result.home_sets.len(), 2);
assert_eq!(result.home_sets[0].path(), "/calendars/user/");
assert_eq!(result.home_sets[1].path(), "/shared-calendars/");
}
#[test]
fn test_parse_response_bad_status() {
let principal = Uri::from_static("https://example.com/principals/user/");
let req = FindCalendarHomeSet::new(&principal);
let response_xml = b"";
let response = http::Response::builder()
.status(StatusCode::NOT_FOUND)
.body(())
.unwrap();
let (parts, ()) = response.into_parts();
let result = req.parse_response(&parts, response_xml);
assert!(result.is_err());
}
}