diff options
| author | Gustav Sörnäs <gustav@sornas.net> | 2021-04-25 16:58:17 +0200 |
|---|---|---|
| committer | Gustav Sörnäs <gustav@sornas.net> | 2021-04-25 16:58:17 +0200 |
| commit | 72c2b83748a601d02c82d5bcb4220d3b238281cc (patch) | |
| tree | 38acb17db4a48fc9f340680ea5b86c6cd49d8f2a /notmuch/tests/fixtures.rs | |
| parent | 51fa75397dda2c280f29760e7b525caefc03642e (diff) | |
| parent | 2231a5cf6cdeb90c1cdb75d161a0063d4a385576 (diff) | |
| download | mail-72c2b83748a601d02c82d5bcb4220d3b238281cc.tar.gz | |
Add 'notmuch/' from commit '2231a5cf6cdeb90c1cdb75d161a0063d4a385576'
git-subtree-dir: notmuch
git-subtree-mainline: 51fa75397dda2c280f29760e7b525caefc03642e
git-subtree-split: 2231a5cf6cdeb90c1cdb75d161a0063d4a385576
Diffstat (limited to 'notmuch/tests/fixtures.rs')
| -rw-r--r-- | notmuch/tests/fixtures.rs | 198 |
1 files changed, 198 insertions, 0 deletions
diff --git a/notmuch/tests/fixtures.rs b/notmuch/tests/fixtures.rs new file mode 100644 index 0000000..7075905 --- /dev/null +++ b/notmuch/tests/fixtures.rs @@ -0,0 +1,198 @@ +extern crate dirs; +extern crate tempfile; +extern crate notmuch; +extern crate gethostname; +extern crate maildir; +extern crate lettre; +extern crate lettre_email; + +use std::ffi::OsStr; +use std::io::{Result, Write}; +use std::fs::{self, File}; +use std::path::PathBuf; +use tempfile::{tempdir, TempDir}; +use std::process::Command; +use maildir::Maildir; +use lettre_email::{EmailBuilder, Header}; +use lettre::SendableEmail; + + +// A basic test interface to a valid maildir directory. +// +// This creates a valid maildir and provides a simple mechanism to +// deliver test emails to it. It also writes a notmuch-config file +// in the top of the maildir. +pub struct MailBox { + root_dir: TempDir, + maildir: Maildir +} + +impl MailBox { + + // Creates a new maildir fixture. Since this is only used for tests, + // may just panic of something is wrong + pub fn new() -> Self { + + let root_dir = tempdir().unwrap(); + let root_path = root_dir.path().to_path_buf(); + + let tmp_path = root_path.join("tmp"); + fs::create_dir(&tmp_path).unwrap(); + + let cfg_fname = root_path.join("notmuch-config"); + let mut cfg_file = File::create(cfg_fname).unwrap(); + write!(cfg_file, r#" + [database] + path={tmppath} + [user] + name=Some Hacker + primary_email=dst@example.com + [new] + tags=unread;inbox; + ignore= + [search] + exclude_tags=deleted;spam; + [maildir] + synchronize_flags=true + [crypto] + gpg_path=gpg + "#, tmppath=root_path.to_string_lossy()).unwrap(); + + let maildir = Maildir::from(root_path.to_path_buf()); + maildir.create_dirs().unwrap(); + + Self { + root_dir, + maildir + } + } + + /// Return a new unique message ID + // fn next_msgid(&mut self) -> String{ + // let hostname = gethostname::gethostname(); + // let msgid = format!("{}@{}", self.idcount, hostname.to_string_lossy()); + // self.idcount += 1; + // msgid + // } + + pub fn path(&self) -> PathBuf { + self.root_dir.path().into() + } + + /// Deliver a new mail message in the mbox. + /// This does only adds the message to maildir, does not insert it + /// into the notmuch database. + /// returns a tuple of (msgid, pathname). + pub fn deliver(&self, + subject: Option<String>, + body: Option<String>, + to: Option<String>, + from: Option<String>, + headers: Vec<(String, String)>, + is_new: bool, // Move to new dir or cur dir? + _keywords: Option<Vec<String>>, // List of keywords or labels + seen: bool, // Seen flag (cur dir only) + replied: bool, // Replied flag (cur dir only) + flagged: bool) // Flagged flag (cur dir only) + -> Result<(String, PathBuf)> + { + + let mut builder = EmailBuilder::new() + .subject(subject.unwrap_or_else(|| "Test mail".to_string())); + + + if let Some(val) = body { + builder = builder.text(val); + } + + builder = builder.to(to.unwrap_or_else(|| "to@example.com".to_string())) + .from(from.unwrap_or_else(|| "src@example.com".to_string())); + + for h in headers.into_iter(){ + let hdr: Header = h.into(); + builder = builder.header(hdr); + } + + let msg:SendableEmail = builder.build().unwrap().into(); + + // not sure why lettre doesn't add the host suffix itself + let msg_id = msg.message_id().to_string() + ".lettre@localhost"; + let id = if is_new { + self.maildir.store_new(&msg.message_to_string().unwrap().as_bytes()).unwrap() + }else{ + let mut flags = String::from(""); + if flagged { + flags += "F"; + } + if replied { + flags += "R"; + } + if seen { + flags += "S"; + } + println!("flags: {:?}", flags); + let mid = self.maildir.store_cur_with_flags(&msg.message_to_string().unwrap().as_bytes(), flags.as_str()).unwrap(); + + // I have no idea what the reasoning for the :2 here is, but ok. + format!("{}:2,{}", mid, flags) + }; + + + let mut msgpath = self.path(); + msgpath = if is_new { + msgpath.join("new") + } else { + msgpath.join("cur") + }; + + msgpath = msgpath.join(&id); + + Ok((msg_id, msgpath)) + } +} + +impl Drop for MailBox { + fn drop(&mut self) { + } +} + + +#[derive(Clone, Debug)] +pub struct NotmuchCommand { + maildir_path: PathBuf +} + +impl NotmuchCommand { + + /// Return a function which runs notmuch commands on our test maildir. + /// + /// This uses the notmuch-config file created by the ``maildir`` + /// fixture. + pub fn new(maildir_path: &PathBuf) -> Self { + Self { + maildir_path: maildir_path.clone() + } + } + + /// Run a notmuch comand. + /// + /// This function runs with a timeout error as many notmuch + /// commands may block if multiple processes are trying to open + /// the database in write-mode. It is all too easy to + /// accidentally do this in the unittests. + pub fn run<I, S>(&self, args: I) -> Result<()> + where + I: IntoIterator<Item=S>, + S: AsRef<OsStr> + { + let cfg_fname = self.maildir_path.join("notmuch-config"); + + Command::new("notmuch").env("NOTMUCH_CONFIG", &cfg_fname) + .args(args) + .status()?; + Ok(()) + } + +} + + |
