aboutsummaryrefslogtreecommitdiffstats
path: root/notmuch/tests/fixtures.rs
diff options
context:
space:
mode:
authorGustav Sörnäs <gustav@sornas.net>2021-04-25 16:58:17 +0200
committerGustav Sörnäs <gustav@sornas.net>2021-04-25 16:58:17 +0200
commit72c2b83748a601d02c82d5bcb4220d3b238281cc (patch)
tree38acb17db4a48fc9f340680ea5b86c6cd49d8f2a /notmuch/tests/fixtures.rs
parent51fa75397dda2c280f29760e7b525caefc03642e (diff)
parent2231a5cf6cdeb90c1cdb75d161a0063d4a385576 (diff)
downloadmail-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.rs198
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(())
+ }
+
+}
+
+