Restored WebDAV encoder tests
This commit is contained in:
parent
8e5d8a8aaa
commit
f376e88c73
2 changed files with 26 additions and 39 deletions
|
@ -640,16 +640,20 @@ impl<E: Extension> QWrite for Violation<E> {
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
use crate::dav::realization::Core;
|
||||||
use tokio::io::AsyncWriteExt;
|
use tokio::io::AsyncWriteExt;
|
||||||
|
|
||||||
/// To run only the unit tests and avoid the behavior ones:
|
/// To run only the unit tests and avoid the behavior ones:
|
||||||
/// cargo test --bin aerogramme
|
/// cargo test --bin aerogramme
|
||||||
|
|
||||||
async fn serialize<C: Context, Q: QuickWritable<C>>(ctx: C, elem: &Q) -> String {
|
async fn serialize(elem: &impl QWrite) -> String {
|
||||||
let mut buffer = Vec::new();
|
let mut buffer = Vec::new();
|
||||||
let mut tokio_buffer = tokio::io::BufWriter::new(&mut buffer);
|
let mut tokio_buffer = tokio::io::BufWriter::new(&mut buffer);
|
||||||
let mut writer = Writer::new_with_indent(&mut tokio_buffer, b' ', 4);
|
let q = quick_xml::writer::Writer::new_with_indent(&mut tokio_buffer, b' ', 4);
|
||||||
elem.write(&mut writer, ctx).await.expect("xml serialization");
|
let ns_to_apply = vec![ ("xmlns:D".into(), "DAV:".into()) ];
|
||||||
|
let mut writer = Writer { q, ns_to_apply };
|
||||||
|
|
||||||
|
elem.qwrite(&mut writer).await.expect("xml serialization");
|
||||||
tokio_buffer.flush().await.expect("tokio buffer flush");
|
tokio_buffer.flush().await.expect("tokio buffer flush");
|
||||||
let got = std::str::from_utf8(buffer.as_slice()).unwrap();
|
let got = std::str::from_utf8(buffer.as_slice()).unwrap();
|
||||||
|
|
||||||
|
@ -660,20 +664,17 @@ mod tests {
|
||||||
async fn basic_href() {
|
async fn basic_href() {
|
||||||
|
|
||||||
let got = serialize(
|
let got = serialize(
|
||||||
NoExtension { root: false },
|
|
||||||
&Href("/SOGo/dav/so/".into())
|
&Href("/SOGo/dav/so/".into())
|
||||||
).await;
|
).await;
|
||||||
let expected = "<D:href>/SOGo/dav/so/</D:href>";
|
let expected = r#"<D:href xmlns:D="DAV:">/SOGo/dav/so/</D:href>"#;
|
||||||
|
|
||||||
assert_eq!(&got, expected);
|
assert_eq!(&got, expected, "\n---GOT---\n{got}\n---EXP---\n{expected}\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn basic_multistatus() {
|
async fn basic_multistatus() {
|
||||||
let got = serialize(
|
let got = serialize(
|
||||||
NoExtension { root: true },
|
&Multistatus::<Core> {
|
||||||
&Multistatus {
|
|
||||||
responses: vec![],
|
responses: vec![],
|
||||||
responsedescription: Some(ResponseDescription("Hello world".into()))
|
responsedescription: Some(ResponseDescription("Hello world".into()))
|
||||||
},
|
},
|
||||||
|
@ -683,15 +684,14 @@ mod tests {
|
||||||
<D:responsedescription>Hello world</D:responsedescription>
|
<D:responsedescription>Hello world</D:responsedescription>
|
||||||
</D:multistatus>"#;
|
</D:multistatus>"#;
|
||||||
|
|
||||||
assert_eq!(&got, expected);
|
assert_eq!(&got, expected, "\n---GOT---\n{got}\n---EXP---\n{expected}\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn rfc_error_delete_locked() {
|
async fn rfc_error_delete_locked() {
|
||||||
let got = serialize(
|
let got = serialize(
|
||||||
NoExtension { root: true },
|
&Error::<Core>(vec![
|
||||||
&Error(vec![
|
|
||||||
Violation::LockTokenSubmitted(vec![
|
Violation::LockTokenSubmitted(vec![
|
||||||
Href("/locked/".into())
|
Href("/locked/".into())
|
||||||
])
|
])
|
||||||
|
@ -704,28 +704,26 @@ mod tests {
|
||||||
</D:lock-token-submitted>
|
</D:lock-token-submitted>
|
||||||
</D:error>"#;
|
</D:error>"#;
|
||||||
|
|
||||||
assert_eq!(&got, expected);
|
assert_eq!(&got, expected, "\n---GOT---\n{got}\n---EXP---\n{expected}\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn rfc_propname_req() {
|
async fn rfc_propname_req() {
|
||||||
let got = serialize(
|
let got = serialize(
|
||||||
NoExtension { root: true },
|
&PropFind::<Core>::PropName,
|
||||||
&PropFind::PropName,
|
|
||||||
).await;
|
).await;
|
||||||
|
|
||||||
let expected = r#"<D:propfind xmlns:D="DAV:">
|
let expected = r#"<D:propfind xmlns:D="DAV:">
|
||||||
<D:propname/>
|
<D:propname/>
|
||||||
</D:propfind>"#;
|
</D:propfind>"#;
|
||||||
|
|
||||||
assert_eq!(&got, expected);
|
assert_eq!(&got, expected, "\n---GOT---\n{got}\n---EXP---\n{expected}\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn rfc_propname_res() {
|
async fn rfc_propname_res() {
|
||||||
let got = serialize(
|
let got = serialize(
|
||||||
NoExtension { root: true },
|
&Multistatus::<Core> {
|
||||||
&Multistatus {
|
|
||||||
responses: vec![
|
responses: vec![
|
||||||
Response {
|
Response {
|
||||||
href: Href("http://www.example.com/container/".into()),
|
href: Href("http://www.example.com/container/".into()),
|
||||||
|
@ -808,8 +806,7 @@ mod tests {
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn rfc_allprop_req() {
|
async fn rfc_allprop_req() {
|
||||||
let got = serialize(
|
let got = serialize(
|
||||||
NoExtension { root: true },
|
&PropFind::<Core>::AllProp(None),
|
||||||
&PropFind::AllProp(None),
|
|
||||||
).await;
|
).await;
|
||||||
|
|
||||||
let expected = r#"<D:propfind xmlns:D="DAV:">
|
let expected = r#"<D:propfind xmlns:D="DAV:">
|
||||||
|
@ -823,8 +820,7 @@ mod tests {
|
||||||
async fn rfc_allprop_res() {
|
async fn rfc_allprop_res() {
|
||||||
use chrono::{DateTime,FixedOffset,TimeZone};
|
use chrono::{DateTime,FixedOffset,TimeZone};
|
||||||
let got = serialize(
|
let got = serialize(
|
||||||
NoExtension { root: true },
|
&Multistatus::<Core> {
|
||||||
&Multistatus {
|
|
||||||
responses: vec![
|
responses: vec![
|
||||||
Response {
|
Response {
|
||||||
href: Href("/container/".into()),
|
href: Href("/container/".into()),
|
||||||
|
@ -966,12 +962,10 @@ mod tests {
|
||||||
assert_eq!(&got, expected, "\n---GOT---\n{got}\n---EXP---\n{expected}\n");
|
assert_eq!(&got, expected, "\n---GOT---\n{got}\n---EXP---\n{expected}\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn rfc_allprop_include() {
|
async fn rfc_allprop_include() {
|
||||||
let got = serialize(
|
let got = serialize(
|
||||||
NoExtension { root: true },
|
&PropFind::<Core>::AllProp(Some(Include(vec![
|
||||||
&PropFind::AllProp(Some(Include(vec![
|
|
||||||
PropertyRequest::DisplayName,
|
PropertyRequest::DisplayName,
|
||||||
PropertyRequest::ResourceType,
|
PropertyRequest::ResourceType,
|
||||||
]))),
|
]))),
|
||||||
|
@ -991,8 +985,7 @@ mod tests {
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn rfc_propertyupdate() {
|
async fn rfc_propertyupdate() {
|
||||||
let got = serialize(
|
let got = serialize(
|
||||||
NoExtension { root: true },
|
&PropertyUpdate::<Core>(vec![
|
||||||
&PropertyUpdate(vec![
|
|
||||||
PropertyUpdateItem::Set(Set(PropValue(vec![
|
PropertyUpdateItem::Set(Set(PropValue(vec![
|
||||||
Property::GetContentLanguage("fr-FR".into()),
|
Property::GetContentLanguage("fr-FR".into()),
|
||||||
]))),
|
]))),
|
||||||
|
@ -1021,8 +1014,7 @@ mod tests {
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn rfc_delete_locked2() {
|
async fn rfc_delete_locked2() {
|
||||||
let got = serialize(
|
let got = serialize(
|
||||||
NoExtension { root: true },
|
&Multistatus::<Core> {
|
||||||
&Multistatus {
|
|
||||||
responses: vec![Response {
|
responses: vec![Response {
|
||||||
href: Href("http://www.example.com/container/resource3".into()),
|
href: Href("http://www.example.com/container/resource3".into()),
|
||||||
status_or_propstat: StatusOrPropstat::Status(Status(http::status::StatusCode::from_u16(423).unwrap())),
|
status_or_propstat: StatusOrPropstat::Status(Status(http::status::StatusCode::from_u16(423).unwrap())),
|
||||||
|
@ -1050,7 +1042,6 @@ mod tests {
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn rfc_simple_lock_request() {
|
async fn rfc_simple_lock_request() {
|
||||||
let got = serialize(
|
let got = serialize(
|
||||||
NoExtension { root: true },
|
|
||||||
&LockInfo {
|
&LockInfo {
|
||||||
lockscope: LockScope::Exclusive,
|
lockscope: LockScope::Exclusive,
|
||||||
locktype: LockType::Write,
|
locktype: LockType::Write,
|
||||||
|
@ -1076,8 +1067,7 @@ mod tests {
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn rfc_simple_lock_response() {
|
async fn rfc_simple_lock_response() {
|
||||||
let got = serialize(
|
let got = serialize(
|
||||||
NoExtension { root: true },
|
&PropValue::<Core>(vec![
|
||||||
&PropValue(vec![
|
|
||||||
Property::LockDiscovery(vec![ActiveLock {
|
Property::LockDiscovery(vec![ActiveLock {
|
||||||
lockscope: LockScope::Exclusive,
|
lockscope: LockScope::Exclusive,
|
||||||
locktype: LockType::Write,
|
locktype: LockType::Write,
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
use std::collections::HashMap;
|
|
||||||
use tokio::io::{AsyncWrite, AsyncBufRead};
|
use tokio::io::{AsyncWrite, AsyncBufRead};
|
||||||
use quick_xml::events::{Event, BytesEnd, BytesStart, BytesText};
|
use quick_xml::events::{Event, BytesEnd, BytesStart, BytesText};
|
||||||
use quick_xml::name::{Namespace, QName, PrefixDeclaration, ResolveResult, ResolveResult::*};
|
use quick_xml::name::{Namespace, QName, PrefixDeclaration, ResolveResult, ResolveResult::*};
|
||||||
|
@ -21,7 +20,7 @@ pub trait QRead<T> {
|
||||||
/// Transform a Rust object into an XML stream of characters
|
/// Transform a Rust object into an XML stream of characters
|
||||||
pub struct Writer<T: IWrite> {
|
pub struct Writer<T: IWrite> {
|
||||||
pub q: quick_xml::writer::Writer<T>,
|
pub q: quick_xml::writer::Writer<T>,
|
||||||
root: bool,
|
pub ns_to_apply: Vec<(String, String)>,
|
||||||
}
|
}
|
||||||
impl<T: IWrite> Writer<T> {
|
impl<T: IWrite> Writer<T> {
|
||||||
pub fn create_dav_element(&mut self, name: &str) -> BytesStart<'static> {
|
pub fn create_dav_element(&mut self, name: &str) -> BytesStart<'static> {
|
||||||
|
@ -33,11 +32,9 @@ impl<T: IWrite> Writer<T> {
|
||||||
|
|
||||||
fn create_ns_element(&mut self, ns: &str, name: &str) -> BytesStart<'static> {
|
fn create_ns_element(&mut self, ns: &str, name: &str) -> BytesStart<'static> {
|
||||||
let mut start = BytesStart::new(format!("{}:{}", ns, name));
|
let mut start = BytesStart::new(format!("{}:{}", ns, name));
|
||||||
//@FIXME not what we want
|
if !self.ns_to_apply.is_empty() {
|
||||||
if self.root {
|
start.extend_attributes(self.ns_to_apply.iter().map(|(k, n)| (k.as_str(), n.as_str())));
|
||||||
start.push_attribute(("xmlns:D", "DAV:"));
|
self.ns_to_apply.clear()
|
||||||
start.push_attribute(("xmlns:C", "urn:ietf:params:xml:ns:caldav"));
|
|
||||||
self.root = false;
|
|
||||||
}
|
}
|
||||||
start
|
start
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue