mirror of
https://github.com/soywod/himalaya.git
synced 2024-09-05 10:31:13 +00:00
init notmuch backend e2e tests
This commit is contained in:
parent
e544536e01
commit
886b66a017
|
@ -9,7 +9,7 @@ use std::{convert::TryInto, fs, path::PathBuf};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
backends::{Backend, IdMapper, MaildirEnvelopes, MaildirFlags, MaildirMboxes},
|
backends::{Backend, IdMapper, MaildirEnvelopes, MaildirFlags, MaildirMboxes},
|
||||||
config::{AccountConfig, MaildirBackendConfig, DEFAULT_INBOX_FOLDER},
|
config::{AccountConfig, MaildirBackendConfig},
|
||||||
mbox::Mboxes,
|
mbox::Mboxes,
|
||||||
msg::{Envelopes, Msg},
|
msg::{Envelopes, Msg},
|
||||||
};
|
};
|
||||||
|
@ -40,17 +40,10 @@ impl<'a> MaildirBackend<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a maildir instance from a string slice.
|
/// Creates a maildir instance from a string slice.
|
||||||
fn get_mdir_from_dir(&self, dir: &str) -> Result<maildir::Maildir> {
|
pub fn get_mdir_from_dir(&self, dir: &str) -> Result<maildir::Maildir> {
|
||||||
let inbox_folder = self
|
|
||||||
.account_config
|
|
||||||
.mailboxes
|
|
||||||
.get("inbox")
|
|
||||||
.map(|s| s.as_str())
|
|
||||||
.unwrap_or(DEFAULT_INBOX_FOLDER);
|
|
||||||
|
|
||||||
// If the dir points to the inbox folder, creates a maildir
|
// If the dir points to the inbox folder, creates a maildir
|
||||||
// instance from the root folder.
|
// instance from the root folder.
|
||||||
if dir == inbox_folder {
|
if dir == "inbox" {
|
||||||
self.validate_mdir_path(self.mdir.path().to_owned())
|
self.validate_mdir_path(self.mdir.path().to_owned())
|
||||||
.map(maildir::Maildir::from)
|
.map(maildir::Maildir::from)
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -4,17 +4,17 @@ use anyhow::{anyhow, Context, Result};
|
||||||
use log::{debug, info, trace};
|
use log::{debug, info, trace};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
backends::{Backend, IdMapper, NotmuchEnvelopes, NotmuchMbox, NotmuchMboxes},
|
backends::{Backend, IdMapper, MaildirBackend, NotmuchEnvelopes, NotmuchMbox, NotmuchMboxes},
|
||||||
config::{AccountConfig, NotmuchBackendConfig},
|
config::{AccountConfig, NotmuchBackendConfig},
|
||||||
mbox::Mboxes,
|
mbox::Mboxes,
|
||||||
msg::{Envelopes, Msg},
|
msg::{Envelopes, Msg},
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Represents the Notmuch backend.
|
/// Represents the Notmuch backend.
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct NotmuchBackend<'a> {
|
pub struct NotmuchBackend<'a> {
|
||||||
account_config: &'a AccountConfig,
|
account_config: &'a AccountConfig,
|
||||||
notmuch_config: &'a NotmuchBackendConfig,
|
notmuch_config: &'a NotmuchBackendConfig,
|
||||||
|
pub mdir: &'a mut MaildirBackend<'a>,
|
||||||
db: notmuch::Database,
|
db: notmuch::Database,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,12 +22,14 @@ impl<'a> NotmuchBackend<'a> {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
account_config: &'a AccountConfig,
|
account_config: &'a AccountConfig,
|
||||||
notmuch_config: &'a NotmuchBackendConfig,
|
notmuch_config: &'a NotmuchBackendConfig,
|
||||||
) -> Result<Self> {
|
mdir: &'a mut MaildirBackend<'a>,
|
||||||
|
) -> Result<NotmuchBackend<'a>> {
|
||||||
info!(">> create new notmuch backend");
|
info!(">> create new notmuch backend");
|
||||||
|
|
||||||
let backend = Self {
|
let backend = Self {
|
||||||
account_config,
|
account_config,
|
||||||
notmuch_config,
|
notmuch_config,
|
||||||
|
mdir,
|
||||||
db: notmuch::Database::open(
|
db: notmuch::Database::open(
|
||||||
notmuch_config.notmuch_database_dir.clone(),
|
notmuch_config.notmuch_database_dir.clone(),
|
||||||
notmuch::DatabaseMode::ReadWrite,
|
notmuch::DatabaseMode::ReadWrite,
|
||||||
|
@ -39,7 +41,6 @@ impl<'a> NotmuchBackend<'a> {
|
||||||
)
|
)
|
||||||
})?,
|
})?,
|
||||||
};
|
};
|
||||||
trace!("backend: {:?}", backend);
|
|
||||||
|
|
||||||
info!("<< create new notmuch backend");
|
info!("<< create new notmuch backend");
|
||||||
Ok(backend)
|
Ok(backend)
|
||||||
|
@ -68,10 +69,10 @@ impl<'a> NotmuchBackend<'a> {
|
||||||
let page_begin = page * page_size;
|
let page_begin = page * page_size;
|
||||||
debug!("page begin: {:?}", page_begin);
|
debug!("page begin: {:?}", page_begin);
|
||||||
if page_begin > envelopes.len() {
|
if page_begin > envelopes.len() {
|
||||||
return Err(anyhow!(format!(
|
return Err(anyhow!(
|
||||||
"cannot get notmuch envelopes at page {:?} (out of bounds)",
|
"cannot get notmuch envelopes at page {:?} (out of bounds)",
|
||||||
page_begin + 1,
|
page_begin + 1,
|
||||||
)));
|
));
|
||||||
}
|
}
|
||||||
let page_end = envelopes.len().min(page_begin + page_size);
|
let page_end = envelopes.len().min(page_begin + page_size);
|
||||||
debug!("page end: {:?}", page_end);
|
debug!("page end: {:?}", page_end);
|
||||||
|
@ -192,17 +193,75 @@ impl<'a> Backend<'a> for NotmuchBackend<'a> {
|
||||||
Ok(envelopes)
|
Ok(envelopes)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_msg(
|
fn add_msg(&mut self, dir: &str, msg: &[u8], tags: &str) -> Result<Box<dyn ToString>> {
|
||||||
&mut self,
|
|
||||||
_virt_mbox: &str,
|
|
||||||
_msg: &[u8],
|
|
||||||
_flags: &str,
|
|
||||||
) -> Result<Box<dyn ToString>> {
|
|
||||||
info!(">> add notmuch envelopes");
|
info!(">> add notmuch envelopes");
|
||||||
|
debug!("dir: {:?}", dir);
|
||||||
|
debug!("tags: {:?}", tags);
|
||||||
|
|
||||||
|
let mdir = self
|
||||||
|
.mdir
|
||||||
|
.get_mdir_from_dir(dir)
|
||||||
|
.with_context(|| format!("cannot get maildir instance from {:?}", dir))?;
|
||||||
|
let mdir_path_str = mdir
|
||||||
|
.path()
|
||||||
|
.to_str()
|
||||||
|
.ok_or_else(|| anyhow!("cannot parse maildir path to string"))?;
|
||||||
|
|
||||||
|
// Adds the message to the maildir folder and gets its hash.
|
||||||
|
let hash = self
|
||||||
|
.mdir
|
||||||
|
.add_msg(mdir_path_str, msg, "seen")
|
||||||
|
.with_context(|| {
|
||||||
|
format!(
|
||||||
|
"cannot add notmuch message to maildir {:?}",
|
||||||
|
self.notmuch_config.notmuch_database_dir
|
||||||
|
)
|
||||||
|
})?
|
||||||
|
.to_string();
|
||||||
|
debug!("hash: {:?}", hash);
|
||||||
|
|
||||||
|
// Retrieves the file path of the added message by its maildir
|
||||||
|
// identifier.
|
||||||
|
let id = IdMapper::new(mdir.path())
|
||||||
|
.with_context(|| format!("cannot create id mapper instance for {:?}", dir))?
|
||||||
|
.find(&hash)
|
||||||
|
.with_context(|| format!("cannot find notmuch message from short hash {:?}", hash))?;
|
||||||
|
debug!("id: {:?}", id);
|
||||||
|
let file_path = mdir.path().join("cur").join(format!("{}:2,S", id));
|
||||||
|
debug!("file path: {:?}", file_path);
|
||||||
|
|
||||||
|
// Adds the message to the notmuch database by indexing it.
|
||||||
|
let id = self
|
||||||
|
.db
|
||||||
|
.index_file(&file_path, None)
|
||||||
|
.with_context(|| format!("cannot index notmuch message from file {:?}", file_path))?
|
||||||
|
.id()
|
||||||
|
.to_string();
|
||||||
|
let hash = format!("{:x}", md5::compute(&id));
|
||||||
|
|
||||||
|
// Appends hash entry to the id mapper cache file.
|
||||||
|
let mut mapper =
|
||||||
|
IdMapper::new(&self.notmuch_config.notmuch_database_dir).with_context(|| {
|
||||||
|
format!(
|
||||||
|
"cannot create id mapper instance for {:?}",
|
||||||
|
self.notmuch_config.notmuch_database_dir
|
||||||
|
)
|
||||||
|
})?;
|
||||||
|
mapper
|
||||||
|
.append(vec![(hash.clone(), id.clone())])
|
||||||
|
.with_context(|| {
|
||||||
|
format!(
|
||||||
|
"cannot append hash {:?} with id {:?} to id mapper",
|
||||||
|
hash, id
|
||||||
|
)
|
||||||
|
})?;
|
||||||
|
|
||||||
|
// Attaches tags to the notmuch message.
|
||||||
|
self.add_flags("", &hash, tags)
|
||||||
|
.with_context(|| format!("cannot add flags to notmuch message {:?}", id))?;
|
||||||
|
|
||||||
info!("<< add notmuch envelopes");
|
info!("<< add notmuch envelopes");
|
||||||
Err(anyhow!(
|
Ok(Box::new(hash))
|
||||||
"cannot add notmuch envelopes: feature not implemented"
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_msg(&mut self, _virt_mbox: &str, short_hash: &str) -> Result<Msg> {
|
fn get_msg(&mut self, _virt_mbox: &str, short_hash: &str) -> Result<Msg> {
|
||||||
|
@ -288,34 +347,35 @@ impl<'a> Backend<'a> for NotmuchBackend<'a> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_flags(&mut self, virt_mbox: &str, query: &str, tags: &str) -> Result<()> {
|
fn add_flags(&mut self, _virt_mbox: &str, short_hash: &str, tags: &str) -> Result<()> {
|
||||||
info!(">> add notmuch message flags");
|
info!(">> add notmuch message flags");
|
||||||
debug!("tags: {:?}", tags);
|
debug!("tags: {:?}", tags);
|
||||||
debug!("query: {:?}", query);
|
|
||||||
|
|
||||||
let query = self
|
let dir = &self.notmuch_config.notmuch_database_dir;
|
||||||
.account_config
|
let id = IdMapper::new(dir)
|
||||||
.mailboxes
|
.with_context(|| format!("cannot create id mapper instance for {:?}", dir))?
|
||||||
.get(virt_mbox)
|
.find(short_hash)
|
||||||
.map(|s| s.as_str())
|
.with_context(|| {
|
||||||
.unwrap_or(query);
|
format!(
|
||||||
debug!("final query: {:?}", query);
|
"cannot find notmuch message from short hash {:?}",
|
||||||
|
short_hash
|
||||||
|
)
|
||||||
|
})?;
|
||||||
|
debug!("id: {:?}", id);
|
||||||
|
let query = format!("id:{}", id);
|
||||||
|
debug!("query: {:?}", query);
|
||||||
let tags: Vec<_> = tags.split_whitespace().collect();
|
let tags: Vec<_> = tags.split_whitespace().collect();
|
||||||
let query_builder = self
|
let query_builder = self
|
||||||
.db
|
.db
|
||||||
.create_query(query)
|
.create_query(&query)
|
||||||
.with_context(|| format!("cannot create notmuch query from {:?}", query))?;
|
.with_context(|| format!("cannot create notmuch query from {:?}", query))?;
|
||||||
let envelopes = query_builder
|
let msgs = query_builder
|
||||||
.search_messages()
|
.search_messages()
|
||||||
.with_context(|| format!("cannot find notmuch envelopes from query {:?}", query))?;
|
.with_context(|| format!("cannot find notmuch envelopes from query {:?}", query))?;
|
||||||
for envelope in envelopes {
|
for msg in msgs {
|
||||||
for tag in tags.iter() {
|
for tag in tags.iter() {
|
||||||
envelope.add_tag(*tag).with_context(|| {
|
msg.add_tag(*tag).with_context(|| {
|
||||||
format!(
|
format!("cannot add tag {:?} to notmuch message {:?}", tag, msg.id())
|
||||||
"cannot add tag {:?} to notmuch message {:?}",
|
|
||||||
tag,
|
|
||||||
envelope.id()
|
|
||||||
)
|
|
||||||
})?
|
})?
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -324,40 +384,38 @@ impl<'a> Backend<'a> for NotmuchBackend<'a> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_flags(&mut self, virt_mbox: &str, query: &str, tags: &str) -> Result<()> {
|
fn set_flags(&mut self, _virt_mbox: &str, short_hash: &str, tags: &str) -> Result<()> {
|
||||||
info!(">> set notmuch message flags");
|
info!(">> set notmuch message flags");
|
||||||
debug!("tags: {:?}", tags);
|
debug!("tags: {:?}", tags);
|
||||||
debug!("query: {:?}", query);
|
|
||||||
|
|
||||||
let query = self
|
let dir = &self.notmuch_config.notmuch_database_dir;
|
||||||
.account_config
|
let id = IdMapper::new(dir)
|
||||||
.mailboxes
|
.with_context(|| format!("cannot create id mapper instance for {:?}", dir))?
|
||||||
.get(virt_mbox)
|
.find(short_hash)
|
||||||
.map(|s| s.as_str())
|
.with_context(|| {
|
||||||
.unwrap_or(query);
|
format!(
|
||||||
debug!("final query: {:?}", query);
|
"cannot find notmuch message from short hash {:?}",
|
||||||
|
short_hash
|
||||||
|
)
|
||||||
|
})?;
|
||||||
|
debug!("id: {:?}", id);
|
||||||
|
let query = format!("id:{}", id);
|
||||||
|
debug!("query: {:?}", query);
|
||||||
let tags: Vec<_> = tags.split_whitespace().collect();
|
let tags: Vec<_> = tags.split_whitespace().collect();
|
||||||
let query_builder = self
|
let query_builder = self
|
||||||
.db
|
.db
|
||||||
.create_query(query)
|
.create_query(&query)
|
||||||
.with_context(|| format!("cannot create notmuch query from {:?}", query))?;
|
.with_context(|| format!("cannot create notmuch query from {:?}", query))?;
|
||||||
let envelopes = query_builder
|
let msgs = query_builder
|
||||||
.search_messages()
|
.search_messages()
|
||||||
.with_context(|| format!("cannot find notmuch envelopes from query {:?}", query))?;
|
.with_context(|| format!("cannot find notmuch envelopes from query {:?}", query))?;
|
||||||
for envelope in envelopes {
|
for msg in msgs {
|
||||||
envelope.remove_all_tags().with_context(|| {
|
msg.remove_all_tags().with_context(|| {
|
||||||
format!(
|
format!("cannot remove all tags from notmuch message {:?}", msg.id())
|
||||||
"cannot remove all tags from notmuch message {:?}",
|
|
||||||
envelope.id()
|
|
||||||
)
|
|
||||||
})?;
|
})?;
|
||||||
for tag in tags.iter() {
|
for tag in tags.iter() {
|
||||||
envelope.add_tag(*tag).with_context(|| {
|
msg.add_tag(*tag).with_context(|| {
|
||||||
format!(
|
format!("cannot add tag {:?} to notmuch message {:?}", tag, msg.id())
|
||||||
"cannot add tag {:?} to notmuch message {:?}",
|
|
||||||
tag,
|
|
||||||
envelope.id()
|
|
||||||
)
|
|
||||||
})?
|
})?
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -366,33 +424,38 @@ impl<'a> Backend<'a> for NotmuchBackend<'a> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn del_flags(&mut self, virt_mbox: &str, query: &str, tags: &str) -> Result<()> {
|
fn del_flags(&mut self, _virt_mbox: &str, short_hash: &str, tags: &str) -> Result<()> {
|
||||||
info!(">> delete notmuch message flags");
|
info!(">> delete notmuch message flags");
|
||||||
debug!("tags: {:?}", tags);
|
debug!("tags: {:?}", tags);
|
||||||
debug!("query: {:?}", query);
|
|
||||||
|
|
||||||
let query = self
|
let dir = &self.notmuch_config.notmuch_database_dir;
|
||||||
.account_config
|
let id = IdMapper::new(dir)
|
||||||
.mailboxes
|
.with_context(|| format!("cannot create id mapper instance for {:?}", dir))?
|
||||||
.get(virt_mbox)
|
.find(short_hash)
|
||||||
.map(|s| s.as_str())
|
.with_context(|| {
|
||||||
.unwrap_or(query);
|
format!(
|
||||||
debug!("final query: {:?}", query);
|
"cannot find notmuch message from short hash {:?}",
|
||||||
|
short_hash
|
||||||
|
)
|
||||||
|
})?;
|
||||||
|
debug!("id: {:?}", id);
|
||||||
|
let query = format!("id:{}", id);
|
||||||
|
debug!("query: {:?}", query);
|
||||||
let tags: Vec<_> = tags.split_whitespace().collect();
|
let tags: Vec<_> = tags.split_whitespace().collect();
|
||||||
let query_builder = self
|
let query_builder = self
|
||||||
.db
|
.db
|
||||||
.create_query(query)
|
.create_query(&query)
|
||||||
.with_context(|| format!("cannot create notmuch query from {:?}", query))?;
|
.with_context(|| format!("cannot create notmuch query from {:?}", query))?;
|
||||||
let envelopes = query_builder
|
let msgs = query_builder
|
||||||
.search_messages()
|
.search_messages()
|
||||||
.with_context(|| format!("cannot find notmuch envelopes from query {:?}", query))?;
|
.with_context(|| format!("cannot find notmuch envelopes from query {:?}", query))?;
|
||||||
for envelope in envelopes {
|
for msg in msgs {
|
||||||
for tag in tags.iter() {
|
for tag in tags.iter() {
|
||||||
envelope.remove_tag(*tag).with_context(|| {
|
msg.remove_tag(*tag).with_context(|| {
|
||||||
format!(
|
format!(
|
||||||
"cannot delete tag {:?} from notmuch message {:?}",
|
"cannot delete tag {:?} from notmuch message {:?}",
|
||||||
tag,
|
tag,
|
||||||
envelope.id()
|
msg.id()
|
||||||
)
|
)
|
||||||
})?
|
})?
|
||||||
}
|
}
|
||||||
|
|
16
src/main.rs
16
src/main.rs
|
@ -7,7 +7,7 @@ use himalaya::{
|
||||||
compl::{compl_arg, compl_handler},
|
compl::{compl_arg, compl_handler},
|
||||||
config::{
|
config::{
|
||||||
account_args, config_args, AccountConfig, BackendConfig, DeserializedConfig,
|
account_args, config_args, AccountConfig, BackendConfig, DeserializedConfig,
|
||||||
DEFAULT_INBOX_FOLDER,
|
MaildirBackendConfig, DEFAULT_INBOX_FOLDER,
|
||||||
},
|
},
|
||||||
mbox::{mbox_arg, mbox_handler},
|
mbox::{mbox_arg, mbox_handler},
|
||||||
msg::{flag_arg, flag_handler, msg_arg, msg_handler, tpl_arg, tpl_handler},
|
msg::{flag_arg, flag_handler, msg_arg, msg_handler, tpl_arg, tpl_handler},
|
||||||
|
@ -51,6 +51,7 @@ fn main() -> Result<()> {
|
||||||
|
|
||||||
let mut imap;
|
let mut imap;
|
||||||
let mut maildir;
|
let mut maildir;
|
||||||
|
let maildir_config;
|
||||||
#[cfg(feature = "notmuch")]
|
#[cfg(feature = "notmuch")]
|
||||||
let mut notmuch;
|
let mut notmuch;
|
||||||
let backend: Box<&mut dyn Backend> = match backend_config {
|
let backend: Box<&mut dyn Backend> = match backend_config {
|
||||||
|
@ -64,7 +65,11 @@ fn main() -> Result<()> {
|
||||||
}
|
}
|
||||||
#[cfg(feature = "notmuch")]
|
#[cfg(feature = "notmuch")]
|
||||||
BackendConfig::Notmuch(ref notmuch_config) => {
|
BackendConfig::Notmuch(ref notmuch_config) => {
|
||||||
notmuch = NotmuchBackend::new(&account_config, notmuch_config)?;
|
maildir_config = MaildirBackendConfig {
|
||||||
|
maildir_dir: notmuch_config.notmuch_database_dir.clone(),
|
||||||
|
};
|
||||||
|
maildir = MaildirBackend::new(&account_config, &maildir_config);
|
||||||
|
notmuch = NotmuchBackend::new(&account_config, notmuch_config, &mut maildir)?;
|
||||||
Box::new(&mut notmuch)
|
Box::new(&mut notmuch)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -95,6 +100,7 @@ fn main() -> Result<()> {
|
||||||
let mut printer = StdoutPrinter::try_from(m.value_of("output"))?;
|
let mut printer = StdoutPrinter::try_from(m.value_of("output"))?;
|
||||||
let mut imap;
|
let mut imap;
|
||||||
let mut maildir;
|
let mut maildir;
|
||||||
|
let maildir_config;
|
||||||
#[cfg(feature = "notmuch")]
|
#[cfg(feature = "notmuch")]
|
||||||
let mut notmuch;
|
let mut notmuch;
|
||||||
let backend: Box<&mut dyn Backend> = match backend_config {
|
let backend: Box<&mut dyn Backend> = match backend_config {
|
||||||
|
@ -108,7 +114,11 @@ fn main() -> Result<()> {
|
||||||
}
|
}
|
||||||
#[cfg(feature = "notmuch")]
|
#[cfg(feature = "notmuch")]
|
||||||
BackendConfig::Notmuch(ref notmuch_config) => {
|
BackendConfig::Notmuch(ref notmuch_config) => {
|
||||||
notmuch = NotmuchBackend::new(&account_config, notmuch_config)?;
|
maildir_config = MaildirBackendConfig {
|
||||||
|
maildir_dir: notmuch_config.notmuch_database_dir.clone(),
|
||||||
|
};
|
||||||
|
maildir = MaildirBackend::new(&account_config, &maildir_config);
|
||||||
|
notmuch = NotmuchBackend::new(&account_config, notmuch_config, &mut maildir)?;
|
||||||
Box::new(&mut notmuch)
|
Box::new(&mut notmuch)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -2,5 +2,6 @@ From: alice@localhost
|
||||||
To: patrick@localhost
|
To: patrick@localhost
|
||||||
Subject: Plain message
|
Subject: Plain message
|
||||||
Content-Type: text/plain; charset=utf-8
|
Content-Type: text/plain; charset=utf-8
|
||||||
|
Date: Tue, 1 Mar 2022 12:00:00 +0000
|
||||||
|
|
||||||
Ceci est un message.
|
Ceci est un message.
|
81
tests/test_notmuch_backend.rs
Normal file
81
tests/test_notmuch_backend.rs
Normal file
|
@ -0,0 +1,81 @@
|
||||||
|
use std::{collections::HashMap, env, fs, iter::FromIterator};
|
||||||
|
|
||||||
|
use himalaya::{
|
||||||
|
backends::{Backend, MaildirBackend, NotmuchBackend, NotmuchEnvelopes},
|
||||||
|
config::{AccountConfig, MaildirBackendConfig, NotmuchBackendConfig},
|
||||||
|
};
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_notmuch_backend() {
|
||||||
|
// set up maildir folders and notmuch database
|
||||||
|
let mdir: maildir::Maildir = env::temp_dir().join("himalaya-test-notmuch").into();
|
||||||
|
if let Err(_) = fs::remove_dir_all(mdir.path()) {}
|
||||||
|
mdir.create_dirs().unwrap();
|
||||||
|
notmuch::Database::create(mdir.path()).unwrap();
|
||||||
|
|
||||||
|
// configure accounts
|
||||||
|
let account_config = AccountConfig {
|
||||||
|
mailboxes: HashMap::from_iter([("inbox".into(), "*".into())]),
|
||||||
|
..AccountConfig::default()
|
||||||
|
};
|
||||||
|
let mdir_config = MaildirBackendConfig {
|
||||||
|
maildir_dir: mdir.path().to_owned(),
|
||||||
|
};
|
||||||
|
let notmuch_config = NotmuchBackendConfig {
|
||||||
|
notmuch_database_dir: mdir.path().to_owned(),
|
||||||
|
};
|
||||||
|
let mut mdir = MaildirBackend::new(&account_config, &mdir_config);
|
||||||
|
let mut notmuch = NotmuchBackend::new(&account_config, ¬much_config, &mut mdir).unwrap();
|
||||||
|
|
||||||
|
// check that a message can be added
|
||||||
|
let msg = include_bytes!("./emails/alice-to-patrick.eml");
|
||||||
|
let hash = notmuch.add_msg("", msg, "inbox seen").unwrap().to_string();
|
||||||
|
|
||||||
|
// check that the added message exists
|
||||||
|
let msg = notmuch.get_msg("", &hash).unwrap();
|
||||||
|
assert_eq!("alice@localhost", msg.from.clone().unwrap().to_string());
|
||||||
|
assert_eq!("patrick@localhost", msg.to.clone().unwrap().to_string());
|
||||||
|
assert_eq!("Ceci est un message.", msg.fold_text_plain_parts());
|
||||||
|
|
||||||
|
// check that the envelope of the added message exists
|
||||||
|
let envelopes = notmuch.get_envelopes("inbox", 10, 0).unwrap();
|
||||||
|
let envelopes: &NotmuchEnvelopes = envelopes.as_any().downcast_ref().unwrap();
|
||||||
|
let envelope = envelopes.first().unwrap();
|
||||||
|
assert_eq!(1, envelopes.len());
|
||||||
|
assert_eq!("alice@localhost", envelope.sender);
|
||||||
|
assert_eq!("Plain message", envelope.subject);
|
||||||
|
|
||||||
|
// check that a flag can be added to the message
|
||||||
|
notmuch
|
||||||
|
.add_flags("", &envelope.hash, "flagged passed")
|
||||||
|
.unwrap();
|
||||||
|
let envelopes = notmuch.get_envelopes("inbox", 1, 0).unwrap();
|
||||||
|
let envelopes: &NotmuchEnvelopes = envelopes.as_any().downcast_ref().unwrap();
|
||||||
|
let envelope = envelopes.first().unwrap();
|
||||||
|
assert!(envelope.flags.contains(&"inbox".into()));
|
||||||
|
assert!(envelope.flags.contains(&"seen".into()));
|
||||||
|
assert!(envelope.flags.contains(&"flagged".into()));
|
||||||
|
assert!(envelope.flags.contains(&"passed".into()));
|
||||||
|
|
||||||
|
// check that the message flags can be changed
|
||||||
|
notmuch
|
||||||
|
.set_flags("", &envelope.hash, "inbox passed")
|
||||||
|
.unwrap();
|
||||||
|
let envelopes = notmuch.get_envelopes("inbox", 1, 0).unwrap();
|
||||||
|
let envelopes: &NotmuchEnvelopes = envelopes.as_any().downcast_ref().unwrap();
|
||||||
|
let envelope = envelopes.first().unwrap();
|
||||||
|
assert!(envelope.flags.contains(&"inbox".into()));
|
||||||
|
assert!(!envelope.flags.contains(&"seen".into()));
|
||||||
|
assert!(!envelope.flags.contains(&"flagged".into()));
|
||||||
|
assert!(envelope.flags.contains(&"passed".into()));
|
||||||
|
|
||||||
|
// check that a flag can be removed from the message
|
||||||
|
notmuch.del_flags("", &envelope.hash, "passed").unwrap();
|
||||||
|
let envelopes = notmuch.get_envelopes("inbox", 1, 0).unwrap();
|
||||||
|
let envelopes: &NotmuchEnvelopes = envelopes.as_any().downcast_ref().unwrap();
|
||||||
|
let envelope = envelopes.first().unwrap();
|
||||||
|
assert!(envelope.flags.contains(&"inbox".into()));
|
||||||
|
assert!(!envelope.flags.contains(&"seen".into()));
|
||||||
|
assert!(!envelope.flags.contains(&"flagged".into()));
|
||||||
|
assert!(!envelope.flags.contains(&"passed".into()));
|
||||||
|
}
|
Loading…
Reference in a new issue