webdav propfind integration tests
This commit is contained in:
parent
742beeeafb
commit
649a7b8b1b
7 changed files with 370 additions and 19 deletions
228
Cargo.lock
generated
228
Cargo.lock
generated
|
@ -152,6 +152,7 @@ dependencies = [
|
|||
name = "aerogramme"
|
||||
version = "0.3.0"
|
||||
dependencies = [
|
||||
"aero-dav",
|
||||
"aero-proto",
|
||||
"aero-user",
|
||||
"anyhow",
|
||||
|
@ -160,6 +161,8 @@ dependencies = [
|
|||
"futures",
|
||||
"log",
|
||||
"nix",
|
||||
"quick-xml",
|
||||
"reqwest",
|
||||
"rpassword",
|
||||
"tokio",
|
||||
"tracing",
|
||||
|
@ -952,6 +955,12 @@ version = "0.21.7"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567"
|
||||
|
||||
[[package]]
|
||||
name = "base64"
|
||||
version = "0.22.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
|
||||
|
||||
[[package]]
|
||||
name = "base64-simd"
|
||||
version = "0.8.0"
|
||||
|
@ -1515,6 +1524,21 @@ version = "1.0.7"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
|
||||
|
||||
[[package]]
|
||||
name = "foreign-types"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1"
|
||||
dependencies = [
|
||||
"foreign-types-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "foreign-types-shared"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
|
||||
|
||||
[[package]]
|
||||
name = "form_urlencoded"
|
||||
version = "1.2.1"
|
||||
|
@ -1933,6 +1957,22 @@ dependencies = [
|
|||
"tower-service",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hyper-tls"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"http-body-util",
|
||||
"hyper 1.2.0",
|
||||
"hyper-util",
|
||||
"native-tls",
|
||||
"tokio",
|
||||
"tokio-native-tls",
|
||||
"tower-service",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hyper-util"
|
||||
version = "0.1.3"
|
||||
|
@ -2103,6 +2143,12 @@ dependencies = [
|
|||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ipnet"
|
||||
version = "2.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3"
|
||||
|
||||
[[package]]
|
||||
name = "iso8601"
|
||||
version = "0.6.1"
|
||||
|
@ -2297,6 +2343,12 @@ version = "2.3.4"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525"
|
||||
|
||||
[[package]]
|
||||
name = "mime"
|
||||
version = "0.3.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a"
|
||||
|
||||
[[package]]
|
||||
name = "minimal-lexical"
|
||||
version = "0.2.1"
|
||||
|
@ -2324,6 +2376,24 @@ dependencies = [
|
|||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "native-tls"
|
||||
version = "0.2.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
"libc",
|
||||
"log",
|
||||
"openssl",
|
||||
"openssl-probe",
|
||||
"openssl-sys",
|
||||
"schannel",
|
||||
"security-framework",
|
||||
"security-framework-sys",
|
||||
"tempfile",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nix"
|
||||
version = "0.27.1"
|
||||
|
@ -2435,12 +2505,50 @@ version = "1.19.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
|
||||
|
||||
[[package]]
|
||||
name = "openssl"
|
||||
version = "0.10.64"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "95a0481286a310808298130d22dd1fef0fa571e05a8f44ec801801e84b216b1f"
|
||||
dependencies = [
|
||||
"bitflags 2.4.2",
|
||||
"cfg-if",
|
||||
"foreign-types",
|
||||
"libc",
|
||||
"once_cell",
|
||||
"openssl-macros",
|
||||
"openssl-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "openssl-macros"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.48",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "openssl-probe"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf"
|
||||
|
||||
[[package]]
|
||||
name = "openssl-sys"
|
||||
version = "0.9.102"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c597637d56fbc83893a35eb0dd04b2b8e7a50c91e64e9493e398b5df4fb45fa2"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc",
|
||||
"pkg-config",
|
||||
"vcpkg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "os_str_bytes"
|
||||
version = "6.6.1"
|
||||
|
@ -2724,6 +2832,49 @@ version = "0.6.29"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1"
|
||||
|
||||
[[package]]
|
||||
name = "reqwest"
|
||||
version = "0.12.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "566cafdd92868e0939d3fb961bd0dc25fcfaaed179291093b3d43e6b3150ea10"
|
||||
dependencies = [
|
||||
"base64 0.22.1",
|
||||
"bytes",
|
||||
"encoding_rs",
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
"futures-util",
|
||||
"h2 0.4.2",
|
||||
"http 1.1.0",
|
||||
"http-body 1.0.0",
|
||||
"http-body-util",
|
||||
"hyper 1.2.0",
|
||||
"hyper-tls",
|
||||
"hyper-util",
|
||||
"ipnet",
|
||||
"js-sys",
|
||||
"log",
|
||||
"mime",
|
||||
"native-tls",
|
||||
"once_cell",
|
||||
"percent-encoding",
|
||||
"pin-project-lite 0.2.13",
|
||||
"rustls-pemfile 2.1.1",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"serde_urlencoded",
|
||||
"sync_wrapper",
|
||||
"system-configuration",
|
||||
"tokio",
|
||||
"tokio-native-tls",
|
||||
"tower-service",
|
||||
"url",
|
||||
"wasm-bindgen",
|
||||
"wasm-bindgen-futures",
|
||||
"web-sys",
|
||||
"winreg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rfc6979"
|
||||
version = "0.3.1"
|
||||
|
@ -3075,6 +3226,18 @@ dependencies = [
|
|||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_urlencoded"
|
||||
version = "0.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd"
|
||||
dependencies = [
|
||||
"form_urlencoded",
|
||||
"itoa",
|
||||
"ryu",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sha1"
|
||||
version = "0.10.6"
|
||||
|
@ -3299,6 +3462,12 @@ dependencies = [
|
|||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sync_wrapper"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160"
|
||||
|
||||
[[package]]
|
||||
name = "synstructure"
|
||||
version = "0.12.6"
|
||||
|
@ -3311,12 +3480,45 @@ dependencies = [
|
|||
"unicode-xid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "system-configuration"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"core-foundation",
|
||||
"system-configuration-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "system-configuration-sys"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9"
|
||||
dependencies = [
|
||||
"core-foundation-sys",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tap"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369"
|
||||
|
||||
[[package]]
|
||||
name = "tempfile"
|
||||
version = "3.10.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"fastrand 2.0.1",
|
||||
"rustix 0.38.31",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "termcolor"
|
||||
version = "1.4.1"
|
||||
|
@ -3435,6 +3637,16 @@ dependencies = [
|
|||
"syn 2.0.48",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-native-tls"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2"
|
||||
dependencies = [
|
||||
"native-tls",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-rustls"
|
||||
version = "0.23.4"
|
||||
|
@ -3678,6 +3890,12 @@ version = "1.7.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "126e423afe2dd9ac52142e7e9d5ce4135d7e13776c529d27fd6bc49f19e3280b"
|
||||
|
||||
[[package]]
|
||||
name = "vcpkg"
|
||||
version = "0.2.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
|
||||
|
||||
[[package]]
|
||||
name = "version_check"
|
||||
version = "0.9.4"
|
||||
|
@ -3979,6 +4197,16 @@ version = "0.52.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04"
|
||||
|
||||
[[package]]
|
||||
name = "winreg"
|
||||
version = "0.52.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a277a57398d4bfa075df44f501a17cfdf8542d224f0d36095a2adc7aee4ef0a5"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wyz"
|
||||
version = "0.2.0"
|
||||
|
|
|
@ -66,6 +66,7 @@ http-body-util = "0.1.1"
|
|||
hyper = "1.2"
|
||||
hyper-rustls = { version = "0.26", features = ["http2"] }
|
||||
hyper-util = { version = "0.1", features = ["full"] }
|
||||
reqwest = { version = "0.12", features = [ "blocking" ]} # for testing purposes only
|
||||
|
||||
# serialization, compression & parsing
|
||||
serde = "1.0.137"
|
||||
|
|
|
@ -638,10 +638,10 @@ mod tests {
|
|||
use imap_codec::ResponseCodec;
|
||||
use std::fs;
|
||||
|
||||
use aero_user::cryptoblob;
|
||||
use aero_collections::mail::mailbox::MailMeta;
|
||||
use aero_collections::mail::query::QueryResult;
|
||||
use aero_collections::unique_ident;
|
||||
use aero_user::cryptoblob;
|
||||
|
||||
use crate::imap::index::MailIndex;
|
||||
use crate::imap::mime_view;
|
||||
|
|
|
@ -21,6 +21,11 @@ tracing.workspace = true
|
|||
tracing-subscriber.workspace = true
|
||||
rpassword.workspace = true
|
||||
|
||||
[dev-dependencies]
|
||||
reqwest.workspace = true
|
||||
aero-dav.workspace = true
|
||||
quick-xml.workspace = true
|
||||
|
||||
[[test]]
|
||||
name = "behavior"
|
||||
path = "tests/behavior.rs"
|
||||
|
|
|
@ -5,21 +5,25 @@ use crate::common::constants::*;
|
|||
use crate::common::fragments::*;
|
||||
|
||||
fn main() {
|
||||
rfc3501_imap4rev1_base();
|
||||
// IMAP
|
||||
/*rfc3501_imap4rev1_base();
|
||||
rfc6851_imapext_move();
|
||||
rfc4551_imapext_condstore();
|
||||
rfc2177_imapext_idle();
|
||||
rfc5161_imapext_enable(); // 1
|
||||
rfc3691_imapext_unselect(); // 2
|
||||
rfc7888_imapext_literal(); // 3
|
||||
rfc4315_imapext_uidplus(); // 4
|
||||
rfc5819_imapext_liststatus(); // 5
|
||||
rfc5161_imapext_enable();
|
||||
rfc3691_imapext_unselect();
|
||||
rfc7888_imapext_literal();
|
||||
rfc4315_imapext_uidplus();
|
||||
rfc5819_imapext_liststatus();*/
|
||||
|
||||
// WebDAV
|
||||
rfc4918_webdav_core();
|
||||
println!("✅ SUCCESS 🌟🚀🥳🙏🥹");
|
||||
}
|
||||
|
||||
fn rfc3501_imap4rev1_base() {
|
||||
println!("🧪 rfc3501_imap4rev1_base");
|
||||
common::aerogramme_provider_daemon_dev(|imap_socket, lmtp_socket| {
|
||||
common::aerogramme_provider_daemon_dev(|imap_socket, lmtp_socket, _dav_socket| {
|
||||
connect(imap_socket).context("server says hello")?;
|
||||
capability(imap_socket, Extension::None).context("check server capabilities")?;
|
||||
login(imap_socket, Account::Alice).context("login test")?;
|
||||
|
@ -69,7 +73,7 @@ fn rfc3501_imap4rev1_base() {
|
|||
|
||||
fn rfc3691_imapext_unselect() {
|
||||
println!("🧪 rfc3691_imapext_unselect");
|
||||
common::aerogramme_provider_daemon_dev(|imap_socket, lmtp_socket| {
|
||||
common::aerogramme_provider_daemon_dev(|imap_socket, lmtp_socket, _dav_socket| {
|
||||
connect(imap_socket).context("server says hello")?;
|
||||
|
||||
lmtp_handshake(lmtp_socket).context("handshake lmtp done")?;
|
||||
|
@ -118,7 +122,7 @@ fn rfc3691_imapext_unselect() {
|
|||
|
||||
fn rfc5161_imapext_enable() {
|
||||
println!("🧪 rfc5161_imapext_enable");
|
||||
common::aerogramme_provider_daemon_dev(|imap_socket, _lmtp_socket| {
|
||||
common::aerogramme_provider_daemon_dev(|imap_socket, _lmtp_socket, _dav_socket| {
|
||||
connect(imap_socket).context("server says hello")?;
|
||||
login(imap_socket, Account::Alice).context("login test")?;
|
||||
enable(imap_socket, Enable::Utf8Accept, Some(Enable::Utf8Accept))?;
|
||||
|
@ -132,7 +136,7 @@ fn rfc5161_imapext_enable() {
|
|||
|
||||
fn rfc6851_imapext_move() {
|
||||
println!("🧪 rfc6851_imapext_move");
|
||||
common::aerogramme_provider_daemon_dev(|imap_socket, lmtp_socket| {
|
||||
common::aerogramme_provider_daemon_dev(|imap_socket, lmtp_socket, _dav_socket| {
|
||||
connect(imap_socket).context("server says hello")?;
|
||||
|
||||
capability(imap_socket, Extension::Move).context("check server capabilities")?;
|
||||
|
@ -174,7 +178,7 @@ fn rfc6851_imapext_move() {
|
|||
|
||||
fn rfc7888_imapext_literal() {
|
||||
println!("🧪 rfc7888_imapext_literal");
|
||||
common::aerogramme_provider_daemon_dev(|imap_socket, _lmtp_socket| {
|
||||
common::aerogramme_provider_daemon_dev(|imap_socket, _lmtp_socket, _dav_socket| {
|
||||
connect(imap_socket).context("server says hello")?;
|
||||
|
||||
capability(imap_socket, Extension::LiteralPlus).context("check server capabilities")?;
|
||||
|
@ -187,7 +191,7 @@ fn rfc7888_imapext_literal() {
|
|||
|
||||
fn rfc4551_imapext_condstore() {
|
||||
println!("🧪 rfc4551_imapext_condstore");
|
||||
common::aerogramme_provider_daemon_dev(|imap_socket, lmtp_socket| {
|
||||
common::aerogramme_provider_daemon_dev(|imap_socket, lmtp_socket, _dav_socket| {
|
||||
// Setup the test
|
||||
connect(imap_socket).context("server says hello")?;
|
||||
|
||||
|
@ -245,7 +249,7 @@ fn rfc4551_imapext_condstore() {
|
|||
|
||||
fn rfc2177_imapext_idle() {
|
||||
println!("🧪 rfc2177_imapext_idle");
|
||||
common::aerogramme_provider_daemon_dev(|imap_socket, lmtp_socket| {
|
||||
common::aerogramme_provider_daemon_dev(|imap_socket, lmtp_socket, _dav_socket| {
|
||||
// Test setup, check capability
|
||||
connect(imap_socket).context("server says hello")?;
|
||||
capability(imap_socket, Extension::Idle).context("check server capabilities")?;
|
||||
|
@ -266,7 +270,7 @@ fn rfc2177_imapext_idle() {
|
|||
|
||||
fn rfc4315_imapext_uidplus() {
|
||||
println!("🧪 rfc4315_imapext_uidplus");
|
||||
common::aerogramme_provider_daemon_dev(|imap_socket, lmtp_socket| {
|
||||
common::aerogramme_provider_daemon_dev(|imap_socket, lmtp_socket, _dav_socket| {
|
||||
// Test setup, check capability, insert 2 emails
|
||||
connect(imap_socket).context("server says hello")?;
|
||||
capability(imap_socket, Extension::UidPlus).context("check server capabilities")?;
|
||||
|
@ -320,7 +324,7 @@ fn rfc4315_imapext_uidplus() {
|
|||
/// ```
|
||||
fn rfc5819_imapext_liststatus() {
|
||||
println!("🧪 rfc5819_imapext_liststatus");
|
||||
common::aerogramme_provider_daemon_dev(|imap_socket, lmtp_socket| {
|
||||
common::aerogramme_provider_daemon_dev(|imap_socket, lmtp_socket, _dav_socket| {
|
||||
// Test setup, check capability, add 2 emails, read 1
|
||||
connect(imap_socket).context("server says hello")?;
|
||||
capability(imap_socket, Extension::ListStatus).context("check server capabilities")?;
|
||||
|
@ -355,3 +359,94 @@ fn rfc5819_imapext_liststatus() {
|
|||
})
|
||||
.expect("test fully run");
|
||||
}
|
||||
|
||||
use aero_dav::caltypes as cal;
|
||||
use aero_dav::realization::All;
|
||||
use aero_dav::types as dav;
|
||||
|
||||
use crate::common::dav_deserialize;
|
||||
|
||||
fn rfc4918_webdav_core() {
|
||||
println!("🧪 rfc4918_webdav_core");
|
||||
common::aerogramme_provider_daemon_dev(|_imap, _lmtp, http| {
|
||||
// --- PROPFIND ---
|
||||
// empty request body (assume "allprop")
|
||||
let body = http.request(reqwest::Method::from_bytes(b"PROPFIND")?, "http://localhost:8087").send()?.text()?;
|
||||
let multistatus = dav_deserialize::<dav::Multistatus<All>>(&body);
|
||||
let root_propstats = multistatus.responses.iter()
|
||||
.find_map(|v| match &v.status_or_propstat {
|
||||
dav::StatusOrPropstat::PropStat(dav::Href(p), x) if p.as_str() == "/" => Some(x),
|
||||
_ => None,
|
||||
})
|
||||
.expect("propstats for root must exist");
|
||||
|
||||
let root_success = root_propstats.iter().find(|p| p.status.0.as_u16() == 200).expect("some propstats for root must be 200");
|
||||
let display_name = root_success.prop.0.iter()
|
||||
.find_map(|v| match v { dav::AnyProperty::Value(dav::Property::DisplayName(x)) => Some(x), _ => None } )
|
||||
.expect("root has a display name");
|
||||
let content_type = root_success.prop.0.iter()
|
||||
.find_map(|v| match v { dav::AnyProperty::Value(dav::Property::GetContentType(x)) => Some(x), _ => None } )
|
||||
.expect("root has a content type");
|
||||
let resource_type = root_success.prop.0.iter()
|
||||
.find_map(|v| match v { dav::AnyProperty::Value(dav::Property::ResourceType(x)) => Some(x), _ => None } )
|
||||
.expect("root has a resource type");
|
||||
|
||||
assert_eq!(display_name, "DAV Root");
|
||||
assert_eq!(content_type, "httpd/unix-directory");
|
||||
assert_eq!(resource_type, &[ dav::ResourceType::Collection ]);
|
||||
|
||||
// propname
|
||||
let propfind_req = r#"<?xml version="1.0" encoding="utf-8" ?><propfind xmlns="DAV:"><propname/></propfind>"#;
|
||||
let body = http.request(reqwest::Method::from_bytes(b"PROPFIND")?, "http://localhost:8087").body(propfind_req).send()?.text()?;
|
||||
let multistatus = dav_deserialize::<dav::Multistatus<All>>(&body);
|
||||
let root_propstats = multistatus.responses.iter()
|
||||
.find_map(|v| match &v.status_or_propstat {
|
||||
dav::StatusOrPropstat::PropStat(dav::Href(p), x) if p.as_str() == "/" => Some(x),
|
||||
_ => None,
|
||||
})
|
||||
.expect("propstats for root must exist");
|
||||
let root_success = root_propstats.iter().find(|p| p.status.0.as_u16() == 200).expect("some propstats for root must be 200");
|
||||
assert!(root_success.prop.0.iter().find(|p| matches!(p, dav::AnyProperty::Request(dav::PropertyRequest::DisplayName))).is_some());
|
||||
assert!(root_success.prop.0.iter().find(|p| matches!(p, dav::AnyProperty::Request(dav::PropertyRequest::ResourceType))).is_some());
|
||||
assert!(root_success.prop.0.iter().find(|p| matches!(p, dav::AnyProperty::Request(dav::PropertyRequest::GetContentType))).is_some());
|
||||
|
||||
// list of properties
|
||||
let propfind_req = r#"<?xml version="1.0" encoding="utf-8" ?><propfind xmlns="DAV:"><prop><displayname/><getcontentlength/></prop></propfind>"#;
|
||||
let body = http.request(reqwest::Method::from_bytes(b"PROPFIND")?, "http://localhost:8087").body(propfind_req).send()?.text()?;
|
||||
let multistatus = dav_deserialize::<dav::Multistatus<All>>(&body);
|
||||
let root_propstats = multistatus.responses.iter()
|
||||
.find_map(|v| match &v.status_or_propstat {
|
||||
dav::StatusOrPropstat::PropStat(dav::Href(p), x) if p.as_str() == "/" => Some(x),
|
||||
_ => None,
|
||||
})
|
||||
.expect("propstats for root must exist");
|
||||
|
||||
let root_success = root_propstats.iter().find(|p| p.status.0.as_u16() == 200).expect("some propstats for root must be 200");
|
||||
let root_not_found = root_propstats.iter().find(|p| p.status.0.as_u16() == 404).expect("some propstats for root must be not found");
|
||||
|
||||
assert!(root_success.prop.0.iter().find(|p| matches!(p, dav::AnyProperty::Value(dav::Property::DisplayName(x)) if x == "DAV Root")).is_some());
|
||||
assert!(root_success.prop.0.iter().find(|p| matches!(p, dav::AnyProperty::Value(dav::Property::ResourceType(_)))).is_none());
|
||||
assert!(root_success.prop.0.iter().find(|p| matches!(p, dav::AnyProperty::Value(dav::Property::GetContentType(_)))).is_none());
|
||||
assert!(root_not_found.prop.0.iter().find(|p| matches!(p, dav::AnyProperty::Request(dav::PropertyRequest::GetContentLength))).is_some());
|
||||
|
||||
// depth 1
|
||||
|
||||
// check tree (calendar, Personal)
|
||||
|
||||
// --- PUT ---
|
||||
|
||||
// --- GET ---
|
||||
|
||||
// --- DELETE ---
|
||||
|
||||
|
||||
Ok(())
|
||||
})
|
||||
.expect("test fully run");
|
||||
}
|
||||
|
||||
// @TODO ACL
|
||||
|
||||
// @TODO CALDAV
|
||||
|
||||
// @TODO SYNC
|
||||
|
|
|
@ -8,10 +8,13 @@ use std::net::{Shutdown, TcpStream};
|
|||
use std::process::Command;
|
||||
use std::thread;
|
||||
|
||||
use reqwest::blocking::Client;
|
||||
use reqwest::header;
|
||||
|
||||
use constants::SMALL_DELAY;
|
||||
|
||||
pub fn aerogramme_provider_daemon_dev(
|
||||
mut fx: impl FnMut(&mut TcpStream, &mut TcpStream) -> Result<()>,
|
||||
mut fx: impl FnMut(&mut TcpStream, &mut TcpStream, &mut Client) -> Result<()>,
|
||||
) -> Result<()> {
|
||||
// Check port is not used (= free) before starting the test
|
||||
let mut max_retry = 20;
|
||||
|
@ -53,8 +56,15 @@ pub fn aerogramme_provider_daemon_dev(
|
|||
let mut lmtp_socket =
|
||||
TcpStream::connect("[::1]:1025").context("lmtp socket must be connected")?;
|
||||
|
||||
println!("-- ready to test imap features --");
|
||||
let result = fx(&mut imap_socket, &mut lmtp_socket);
|
||||
let mut headers = header::HeaderMap::new();
|
||||
headers.insert(
|
||||
header::AUTHORIZATION,
|
||||
header::HeaderValue::from_static("Basic YWxpY2U6aHVudGVyMg=="),
|
||||
);
|
||||
let mut http_client = Client::builder().default_headers(headers).build()?;
|
||||
|
||||
println!("-- ready to test features --");
|
||||
let result = fx(&mut imap_socket, &mut lmtp_socket, &mut http_client);
|
||||
println!("-- test teardown --");
|
||||
|
||||
imap_socket
|
||||
|
@ -97,3 +107,13 @@ pub fn read_first_u32(inp: &str) -> Result<u32> {
|
|||
.collect::<String>()
|
||||
.parse::<u32>()?)
|
||||
}
|
||||
|
||||
use aero_dav::xml::{Node, Reader};
|
||||
pub fn dav_deserialize<T: Node<T>>(src: &str) -> T {
|
||||
futures::executor::block_on(async {
|
||||
let mut rdr = Reader::new(quick_xml::NsReader::from_reader(src.as_bytes()))
|
||||
.await
|
||||
.expect("build reader");
|
||||
rdr.find().await.expect("parse XML")
|
||||
})
|
||||
}
|
||||
|
|
|
@ -185,6 +185,8 @@
|
|||
# Shell
|
||||
shell = gpkgs.mkShell {
|
||||
buildInputs = [
|
||||
gpkgs.openssl
|
||||
gpkgs.pkg-config
|
||||
cargo2nix.packages.x86_64-linux.default
|
||||
fenix.packages.x86_64-linux.complete.toolchain
|
||||
#fenix.packages.x86_64-linux.rust-analyzer
|
||||
|
|
Loading…
Reference in a new issue