extern crate chrono;
extern crate imap;
extern crate lettre;
extern crate memory_logger;
use imap::ImapConnection;
use tempfile::tempdir;
use memory_logger::blocking::MemoryLogger;
use std::io;
use vomit_sync::*;
const USER: &str = "vsync@localhost";
fn test_host() -> String {
std::env::var("TEST_HOST").unwrap_or("127.0.0.1".to_string())
}
fn test_imaps_port() -> u16 {
std::env::var("TEST_IMAPS_PORT")
.unwrap_or("3143".to_string())
.parse()
.unwrap_or(3143)
}
fn clean_mailbox<T: io::Read + io::Write>(session: &mut imap::Session<T>) {
session.select("INBOX").unwrap();
let inbox = session.search("ALL").unwrap();
if !inbox.is_empty() {
session.uid_store("1:*", "+FLAGS (\\Deleted)").unwrap();
}
session.expunge().unwrap();
}
fn session(user: &str) -> imap::Session<Box<dyn ImapConnection>> {
let host = test_host();
let mut s = imap::ClientBuilder::new(&host, test_imaps_port())
.mode(imap::ConnectionMode::Plaintext)
.connect()
.unwrap()
.login(user, user)
.unwrap();
s.debug = true;
clean_mailbox(&mut s);
s
}
#[test]
fn basic_sync() {
let logger = MemoryLogger::setup(log::Level::Trace).unwrap();
let dir = tempdir().unwrap();
let tmp_path = dir.path().to_owned();
assert!(tmp_path.exists());
let maildir = maildir::Maildir::from(tmp_path);
maildir.create_dirs().unwrap();
assert_eq!(maildir.count_new(), 0);
let mbox = "INBOX";
let mut c = session(USER);
c.run_command_and_read_response("ENABLE QRESYNC").unwrap();
let e: lettre::Message = lettre::message::Message::builder()
.from("sender@localhost".parse().unwrap())
.to(USER.parse().unwrap())
.subject("My second e-mail")
.body("Hello world".to_string())
.unwrap()
.into();
c.append(mbox, &e.formatted()).finish().unwrap();
let opts = SyncOptions {
local: String::from(maildir.path().to_str().unwrap()),
remote: String::from(format!("{}:{}", test_host(), test_imaps_port())),
user: String::from(USER),
password: String::from(USER),
threads: 1,
unsafe_tls: true,
disable_tls: true,
list_mailbox_actions: false,
include: Vec::new(),
exclude: Vec::new(),
force: true,
};
pull(&opts).unwrap();
let logs = logger.read();
let text: &str = &logs;
println!("{}", text);
assert!(logs.contains("Discarding local state"));
assert!(logs.contains("forces full resync"));
assert!(logs.contains("full fetch for INBOX"));
drop(logs);
logger.clear();
pull(&opts).unwrap();
let logs = logger.read();
let text: &str = &logs;
println!("{}", text);
assert!(logs.contains("Skipping INBOX because HIGHESTMODSEQ is in sync"));
drop(logs);
logger.clear();
let maildir = maildir::Maildir::from(dir.path().to_owned());
assert_eq!(maildir.count_new() + maildir.count_cur(), 1);
let inbox = c.uid_search("ALL").unwrap();
assert_eq!(inbox.len(), 1);
clean_mailbox(&mut c);
let inbox = c.search("ALL").unwrap();
assert_eq!(inbox.len(), 0);
push(&opts).unwrap();
let logs = logger.read();
let text: &str = &logs;
println!("{}", text);
assert!(logs.contains("restoring mail deleted on remote"));
assert!(logs.contains("uploading local mail"));
drop(logs);
logger.clear();
push(&opts).unwrap();
let logs = logger.read();
let text: &str = &logs;
println!("{}", text);
assert!(logs.contains("Skipping INBOX because HIGHESTMODSEQ is in sync"));
drop(logs);
logger.clear();
assert_eq!(maildir.count_new() + maildir.count_cur(), 1);
let inbox = c.search("ALL").unwrap();
assert_eq!(inbox.len(), 1);
let mail_id = maildir.store_cur_with_flags(&e.formatted(), "S").unwrap();
c.append(mbox, &e.formatted()).finish().unwrap();
sync(&opts).unwrap();
let logs = logger.read();
let text: &str = &logs;
println!("{}", text);
drop(logs);
logger.clear();
sync(&opts).unwrap();
let logs = logger.read();
let text: &str = &logs;
println!("{}", text);
assert!(logs.contains("Skipping INBOX because HIGHESTMODSEQ is in sync"));
drop(logs);
logger.clear();
assert_eq!(maildir.count_new() + maildir.count_cur(), 3);
let inbox = c.uid_search("ALL").unwrap();
assert_eq!(inbox.len(), 3);
maildir.delete(&mail_id).unwrap();
sync(&opts).unwrap();
let logs = logger.read();
let text: &str = &logs;
println!("{}", text);
assert!(logs.contains("deleting remote UID"));
drop(logs);
logger.clear();
assert_eq!(maildir.count_new() + maildir.count_cur(), 2);
let inbox = c.uid_search("ALL").unwrap();
assert_eq!(inbox.len(), 2);
}