maildir: add mailbox creation tests
Signed-off-by: Manos Pitsidianakis <manos@pitsidianak.is>
This commit is contained in:
parent
36a63e8878
commit
fd243fa5ab
1 changed files with 316 additions and 3 deletions
|
@ -20,15 +20,19 @@
|
|||
//
|
||||
// SPDX-License-Identifier: EUPL-1.2 OR GPL-3.0-or-later
|
||||
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::{
|
||||
path::{Path, PathBuf},
|
||||
sync::Arc,
|
||||
};
|
||||
|
||||
use regex::Regex;
|
||||
use tempfile::TempDir;
|
||||
|
||||
use crate::{
|
||||
backends::FlagOp,
|
||||
backends::prelude::*,
|
||||
email::Flag,
|
||||
error::Result,
|
||||
maildir::{move_to_cur, Configuration, MaildirPathTrait},
|
||||
maildir::{move_to_cur, Configuration, MaildirMailbox, MaildirPathTrait, MaildirType},
|
||||
};
|
||||
|
||||
fn set_flags(config: &Configuration, path: &Path, flag_ops: &[FlagOp]) -> Result<PathBuf> {
|
||||
|
@ -232,3 +236,312 @@ fn test_maildir_place_in_dir_regexp() {
|
|||
"place_in_dir() should add missing `:2,` substring"
|
||||
);
|
||||
}
|
||||
|
||||
fn new_maildir_backend(
|
||||
temp_dir: &TempDir,
|
||||
acc_name: &str,
|
||||
event_consumer: BackendEventConsumer,
|
||||
with_root_mailbox: bool,
|
||||
) -> Result<(PathBuf, AccountSettings, Box<MaildirType>)> {
|
||||
let root_mailbox = temp_dir.path().join("INBOX");
|
||||
{
|
||||
std::fs::create_dir(&root_mailbox).expect("Could not create root mailbox directory.");
|
||||
if with_root_mailbox {
|
||||
for d in &["cur", "new", "tmp"] {
|
||||
std::fs::create_dir(root_mailbox.join(d))
|
||||
.expect("Could not create root mailbox directory contents.");
|
||||
}
|
||||
}
|
||||
}
|
||||
let subscribed_mailboxes = if with_root_mailbox {
|
||||
vec!["INBOX".into()]
|
||||
} else {
|
||||
vec![]
|
||||
};
|
||||
let mailboxes = if with_root_mailbox {
|
||||
vec![(
|
||||
"INBOX".into(),
|
||||
crate::conf::MailboxConf {
|
||||
extra: indexmap::indexmap! {
|
||||
"path".into() => root_mailbox.display().to_string(),
|
||||
},
|
||||
..Default::default()
|
||||
},
|
||||
)]
|
||||
.into_iter()
|
||||
.collect()
|
||||
} else {
|
||||
indexmap::indexmap! {}
|
||||
};
|
||||
let extra = if with_root_mailbox {
|
||||
indexmap::indexmap! {
|
||||
"root_mailbox".into() => root_mailbox.display().to_string(),
|
||||
}
|
||||
} else {
|
||||
indexmap::indexmap! {}
|
||||
};
|
||||
|
||||
let account_conf = AccountSettings {
|
||||
name: acc_name.to_string(),
|
||||
root_mailbox: root_mailbox.display().to_string(),
|
||||
format: "maildir".to_string(),
|
||||
identity: "user@localhost".to_string(),
|
||||
extra_identities: vec![],
|
||||
read_only: false,
|
||||
display_name: None,
|
||||
order: Default::default(),
|
||||
subscribed_mailboxes,
|
||||
mailboxes,
|
||||
manual_refresh: true,
|
||||
extra,
|
||||
};
|
||||
|
||||
let maildir = MaildirType::new(&account_conf, Default::default(), event_consumer)?;
|
||||
Ok((root_mailbox, account_conf, maildir))
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_maildir_mailbox_paths() {
|
||||
let temp_dir = TempDir::new().unwrap();
|
||||
let backend_event_queue = Arc::new(std::sync::Mutex::new(
|
||||
std::collections::VecDeque::with_capacity(16),
|
||||
));
|
||||
|
||||
let backend_event_consumer = {
|
||||
let backend_event_queue = Arc::clone(&backend_event_queue);
|
||||
|
||||
BackendEventConsumer::new(Arc::new(move |ah, be| {
|
||||
backend_event_queue.lock().unwrap().push_back((ah, be));
|
||||
}))
|
||||
};
|
||||
|
||||
// Perform tests on a maildir backend where the root mailbox, is not a valid
|
||||
// maildir mailbox (e.g. has no cur,new,tmp sub directories.
|
||||
{
|
||||
let (root_mailbox, _settings, maildir) =
|
||||
new_maildir_backend(&temp_dir, "maildir", backend_event_consumer.clone(), false)
|
||||
.unwrap();
|
||||
assert!(!maildir.config.is_root_a_mailbox);
|
||||
// Assert that giving a file system path to MaildirBox::new is valid
|
||||
let new_mailbox = MaildirMailbox::new(
|
||||
root_mailbox.join("Archive").display().to_string(),
|
||||
"Archive".into(),
|
||||
None,
|
||||
vec![],
|
||||
true,
|
||||
&maildir.config,
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(new_mailbox.name, "Archive");
|
||||
assert_eq!(&new_mailbox.path, &Path::new("Archive"));
|
||||
assert_eq!(&new_mailbox.fs_path, &root_mailbox.join("Archive"));
|
||||
// Assert that giving a mailbox path to MaildirBox::new is valid
|
||||
let new_mailbox = MaildirMailbox::new(
|
||||
"INBOX/Archive".into(),
|
||||
"Archive".into(),
|
||||
None,
|
||||
vec![],
|
||||
true,
|
||||
&maildir.config,
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(new_mailbox.name, "Archive");
|
||||
assert_eq!(&new_mailbox.path, &Path::new("Archive"));
|
||||
assert_eq!(&new_mailbox.fs_path, &root_mailbox.join("Archive"));
|
||||
let mut backend = maildir as Box<dyn MailBackend>;
|
||||
let ref_mailboxes = smol::block_on(backend.mailboxes().unwrap()).unwrap();
|
||||
// Assert that backend has no mailboxes at all");
|
||||
assert!(
|
||||
ref_mailboxes.is_empty(),
|
||||
"ref_mailboxes were not empty: {:?}",
|
||||
ref_mailboxes
|
||||
);
|
||||
let (new_hash, ref_mailboxes) =
|
||||
smol::block_on(backend.create_mailbox("Archive".into()).unwrap()).unwrap();
|
||||
assert_eq!(ref_mailboxes[&new_hash].name(), "Archive");
|
||||
assert_eq!(ref_mailboxes[&new_hash].path(), "Archive");
|
||||
assert_eq!(
|
||||
ref_mailboxes[&new_hash]
|
||||
.as_any()
|
||||
.downcast_ref::<MaildirMailbox>()
|
||||
.unwrap()
|
||||
.fs_path(),
|
||||
&root_mailbox.join("Archive")
|
||||
);
|
||||
// Assert that even if we accidentally give a file system path to a maildir
|
||||
// backend's create_mailbox() method, it still does the correct thing.
|
||||
let (new_hash, ref_mailboxes) = smol::block_on(
|
||||
backend
|
||||
.create_mailbox(root_mailbox.join("Archive2").display().to_string())
|
||||
.unwrap(),
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(ref_mailboxes[&new_hash].name(), "Archive2");
|
||||
assert_eq!(ref_mailboxes[&new_hash].path(), "Archive2");
|
||||
assert_eq!(
|
||||
ref_mailboxes[&new_hash]
|
||||
.as_any()
|
||||
.downcast_ref::<MaildirMailbox>()
|
||||
.unwrap()
|
||||
.fs_path(),
|
||||
&root_mailbox.join("Archive2")
|
||||
);
|
||||
let ref_mailboxes = smol::block_on(backend.mailboxes().unwrap()).unwrap();
|
||||
// Assert that backend has all the created mailboxes so far
|
||||
assert_eq!(
|
||||
ref_mailboxes.len(),
|
||||
2,
|
||||
"mailboxes() return value content not what expected: {:?}",
|
||||
ref_mailboxes
|
||||
);
|
||||
// Assert that giving an absolute path returns an error
|
||||
assert_eq!(
|
||||
&smol::block_on(backend.create_mailbox("/Archive3".to_string()).unwrap())
|
||||
.unwrap_err()
|
||||
.to_string(),
|
||||
"Path given (`/Archive3`) is absolute. Please provide a path relative to the \
|
||||
account's root mailbox."
|
||||
);
|
||||
// Assert that attempting to create a mailbox outside of the root mailbox
|
||||
// returns an error
|
||||
assert_eq!(
|
||||
&smol::block_on(
|
||||
backend
|
||||
.create_mailbox(temp_dir.path().join("Archive3").display().to_string())
|
||||
.unwrap()
|
||||
)
|
||||
.unwrap_err()
|
||||
.to_string(),
|
||||
&format!(
|
||||
"Path given, `{}`, is not included in the root mailbox path `{}`. A maildir \
|
||||
backend cannot contain mailboxes outside of its root path.",
|
||||
temp_dir.path().join("Archive3").display(),
|
||||
root_mailbox.display(),
|
||||
)
|
||||
);
|
||||
|
||||
std::fs::remove_dir_all(root_mailbox).unwrap();
|
||||
}
|
||||
|
||||
// Perform same tests on a maildir backend where the root mailbox is a valid
|
||||
// maildir mailbox (e.g. has cur,new,tmp sub directories.
|
||||
{
|
||||
let (root_mailbox, _settings, maildir) =
|
||||
new_maildir_backend(&temp_dir, "maildir", backend_event_consumer, true).unwrap();
|
||||
assert!(maildir.config.is_root_a_mailbox);
|
||||
// Assert that giving a file system path to MaildirBox::new is valid
|
||||
let new_mailbox = MaildirMailbox::new(
|
||||
root_mailbox.join("Archive").display().to_string(),
|
||||
"Archive".into(),
|
||||
None,
|
||||
vec![],
|
||||
true,
|
||||
&maildir.config,
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(new_mailbox.name, "Archive");
|
||||
assert_eq!(&new_mailbox.path, &Path::new("INBOX/Archive"));
|
||||
assert_eq!(&new_mailbox.fs_path, &root_mailbox.join("Archive"));
|
||||
// Assert that giving a mailbox path to MaildirBox::new is valid
|
||||
let new_mailbox = MaildirMailbox::new(
|
||||
"INBOX/Archive".into(),
|
||||
"Archive".into(),
|
||||
None,
|
||||
vec![],
|
||||
true,
|
||||
&maildir.config,
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(new_mailbox.name, "Archive");
|
||||
assert_eq!(&new_mailbox.path, &Path::new("INBOX/Archive"));
|
||||
assert_eq!(&new_mailbox.fs_path, &root_mailbox.join("Archive"));
|
||||
let mut backend = maildir as Box<dyn MailBackend>;
|
||||
let ref_mailboxes = smol::block_on(backend.mailboxes().unwrap()).unwrap();
|
||||
// Assert that backend has only INBOX as a mailbox
|
||||
assert_eq!(
|
||||
ref_mailboxes.len(),
|
||||
1,
|
||||
"ref_mailboxes is not just INBOX: {:?}",
|
||||
ref_mailboxes
|
||||
);
|
||||
// Assert that creating a mailbox without the root mailbox as a prefix does the
|
||||
// correct thing.
|
||||
let (new_hash, ref_mailboxes) =
|
||||
smol::block_on(backend.create_mailbox("Archive".into()).unwrap()).unwrap();
|
||||
assert_eq!(ref_mailboxes[&new_hash].name(), "Archive");
|
||||
assert_eq!(ref_mailboxes[&new_hash].path(), "INBOX/Archive");
|
||||
assert_eq!(
|
||||
ref_mailboxes[&new_hash]
|
||||
.as_any()
|
||||
.downcast_ref::<MaildirMailbox>()
|
||||
.unwrap()
|
||||
.fs_path(),
|
||||
&root_mailbox.join("Archive")
|
||||
);
|
||||
// Assert that creating a mailbox with the root mailbox as a prefix does the
|
||||
// correct thing.
|
||||
let (new_hash, ref_mailboxes) =
|
||||
smol::block_on(backend.create_mailbox("INBOX/Archive2".into()).unwrap()).unwrap();
|
||||
assert_eq!(ref_mailboxes[&new_hash].name(), "Archive2");
|
||||
assert_eq!(ref_mailboxes[&new_hash].path(), "INBOX/Archive2");
|
||||
assert_eq!(
|
||||
ref_mailboxes[&new_hash]
|
||||
.as_any()
|
||||
.downcast_ref::<MaildirMailbox>()
|
||||
.unwrap()
|
||||
.fs_path(),
|
||||
&root_mailbox.join("Archive2")
|
||||
);
|
||||
// Assert that even if we accidentally give a file system path to a maildir
|
||||
// backend's create_mailbox() method, it still does the correct thing.
|
||||
let (new_hash, ref_mailboxes) = smol::block_on(
|
||||
backend
|
||||
.create_mailbox(root_mailbox.join("Archive3").display().to_string())
|
||||
.unwrap(),
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(ref_mailboxes[&new_hash].name(), "Archive3");
|
||||
assert_eq!(ref_mailboxes[&new_hash].path(), "INBOX/Archive3");
|
||||
assert_eq!(
|
||||
ref_mailboxes[&new_hash]
|
||||
.as_any()
|
||||
.downcast_ref::<MaildirMailbox>()
|
||||
.unwrap()
|
||||
.fs_path(),
|
||||
&root_mailbox.join("Archive3")
|
||||
);
|
||||
let ref_mailboxes = smol::block_on(backend.mailboxes().unwrap()).unwrap();
|
||||
// Assert that backend has all the created mailboxes so far
|
||||
assert_eq!(
|
||||
ref_mailboxes.len(),
|
||||
4,
|
||||
"mailboxes() return value content not what expected: {:?}",
|
||||
ref_mailboxes
|
||||
);
|
||||
// Assert that giving an absolute path returns an error
|
||||
assert_eq!(
|
||||
&smol::block_on(backend.create_mailbox("/Archive4".to_string()).unwrap())
|
||||
.unwrap_err()
|
||||
.to_string(),
|
||||
"Path given (`/Archive4`) is absolute. Please provide a path relative to the \
|
||||
account's root mailbox."
|
||||
);
|
||||
// Assert that attempting to create a mailbox outside of the root mailbox
|
||||
// returns an error
|
||||
assert_eq!(
|
||||
&smol::block_on(
|
||||
backend
|
||||
.create_mailbox(temp_dir.path().join("Archive4").display().to_string())
|
||||
.unwrap()
|
||||
)
|
||||
.unwrap_err()
|
||||
.to_string(),
|
||||
&format!(
|
||||
"Path given, `{}`, is not included in the root mailbox path `{}`. A maildir \
|
||||
backend cannot contain mailboxes outside of its root path.",
|
||||
temp_dir.path().join("Archive4").display(),
|
||||
root_mailbox.display(),
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue