diff --git a/src/account/command/list.rs b/src/account/command/list.rs index 1c8e4ce..0c73275 100644 --- a/src/account/command/list.rs +++ b/src/account/command/list.rs @@ -34,106 +34,3 @@ impl AccountListCommand { ) } } - -#[cfg(test)] -mod tests { - use email::{account::config::AccountConfig, imap::config::ImapConfig}; - use std::{collections::HashMap, fmt::Debug, io}; - use termcolor::ColorSpec; - - use crate::{ - account::TomlAccountConfig, - backend::BackendKind, - printer::{Print, PrintTable, WriteColor}, - }; - - use super::*; - - #[test] - fn it_should_match_cmds_accounts() { - #[derive(Debug, Default, Clone)] - struct StringWriter { - content: String, - } - - impl io::Write for StringWriter { - fn write(&mut self, buf: &[u8]) -> io::Result { - self.content - .push_str(&String::from_utf8(buf.to_vec()).unwrap()); - Ok(buf.len()) - } - - fn flush(&mut self) -> io::Result<()> { - self.content = String::default(); - Ok(()) - } - } - - impl termcolor::WriteColor for StringWriter { - fn supports_color(&self) -> bool { - false - } - - fn set_color(&mut self, _spec: &ColorSpec) -> io::Result<()> { - io::Result::Ok(()) - } - - fn reset(&mut self) -> io::Result<()> { - io::Result::Ok(()) - } - } - - impl WriteColor for StringWriter {} - - #[derive(Debug, Default)] - struct PrinterServiceTest { - pub writer: StringWriter, - } - - impl Printer for PrinterServiceTest { - fn print_table( - &mut self, - data: Box, - opts: PrintTableOpts, - ) -> Result<()> { - data.print_table(&mut self.writer, opts)?; - Ok(()) - } - fn print_log(&mut self, _data: T) -> Result<()> { - unimplemented!() - } - fn print(&mut self, _data: T) -> Result<()> { - unimplemented!() - } - fn is_json(&self) -> bool { - unimplemented!() - } - } - - let mut printer = PrinterServiceTest::default(); - let config = AccountConfig::default(); - let deserialized_config = TomlConfig { - accounts: HashMap::from_iter([( - "account-1".into(), - TomlAccountConfig { - default: Some(true), - backend: Some(BackendKind::Imap), - imap: Some(ImapConfig::default()), - ..Default::default() - }, - )]), - ..TomlConfig::default() - }; - - assert!(list(None, &config, &deserialized_config, &mut printer).is_ok()); - assert_eq!( - concat![ - "\n", - "NAME │BACKEND │DEFAULT \n", - "account-1 │imap │yes \n", - "\n" - ], - printer.writer.content - ); - } -} diff --git a/src/config/mod.rs b/src/config/mod.rs index 8663e75..067e12f 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -236,495 +236,3 @@ pub fn path_parser(path: &str) -> Result { .map(canonicalize::path) .map_err(|err| err.to_string()) } - -#[cfg(test)] -mod tests { - use email::{ - account::config::passwd::PasswdConfig, maildir::config::MaildirConfig, - sendmail::config::SendmailConfig, - }; - use secret::Secret; - - #[cfg(feature = "notmuch")] - use email::backend::NotmuchConfig; - #[cfg(feature = "imap")] - use email::imap::config::{ImapAuthConfig, ImapConfig}; - #[cfg(feature = "smtp")] - use email::smtp::config::{SmtpAuthConfig, SmtpConfig}; - - use std::io::Write; - use tempfile::NamedTempFile; - - use super::*; - - async fn make_config(config: &str) -> Result { - let mut file = NamedTempFile::new().unwrap(); - write!(file, "{}", config).unwrap(); - TomlConfig::from_some_path_or_default(file.into_temp_path().to_str()).await - } - - #[tokio::test] - async fn empty_config() { - let config = make_config("").await; - - assert_eq!( - config.unwrap_err().root_cause().to_string(), - "config file must contain at least one account" - ); - } - - #[tokio::test] - async fn account_missing_email_field() { - let config = make_config("[account]").await; - - assert!(config - .unwrap_err() - .root_cause() - .to_string() - .contains("missing field `email`")); - } - - #[tokio::test] - async fn account_missing_backend_field() { - let config = make_config( - "[account] - email = \"test@localhost\"", - ) - .await; - - assert!(config - .unwrap_err() - .root_cause() - .to_string() - .contains("missing field `backend`")); - } - - #[tokio::test] - async fn account_invalid_backend_field() { - let config = make_config( - "[account] - email = \"test@localhost\" - backend = \"bad\"", - ) - .await; - - assert!(config - .unwrap_err() - .root_cause() - .to_string() - .contains("unknown variant `bad`")); - } - - #[tokio::test] - async fn imap_account_missing_host_field() { - let config = make_config( - "[account] - email = \"test@localhost\" - sender = \"none\" - backend = \"imap\"", - ) - .await; - - assert!(config - .unwrap_err() - .root_cause() - .to_string() - .contains("missing field `imap-host`")); - } - - #[tokio::test] - async fn account_backend_imap_missing_port_field() { - let config = make_config( - "[account] - email = \"test@localhost\" - sender = \"none\" - backend = \"imap\" - imap-host = \"localhost\"", - ) - .await; - - assert!(config - .unwrap_err() - .root_cause() - .to_string() - .contains("missing field `imap-port`")); - } - - #[tokio::test] - async fn account_backend_imap_missing_login_field() { - let config = make_config( - "[account] - email = \"test@localhost\" - sender = \"none\" - backend = \"imap\" - imap-host = \"localhost\" - imap-port = 993", - ) - .await; - - assert!(config - .unwrap_err() - .root_cause() - .to_string() - .contains("missing field `imap-login`")); - } - - #[tokio::test] - async fn account_backend_imap_missing_passwd_cmd_field() { - let config = make_config( - "[account] - email = \"test@localhost\" - sender = \"none\" - backend = \"imap\" - imap-host = \"localhost\" - imap-port = 993 - imap-login = \"login\"", - ) - .await; - - assert!(config - .unwrap_err() - .root_cause() - .to_string() - .contains("missing field `imap-auth`")); - } - - #[tokio::test] - async fn account_backend_maildir_missing_root_dir_field() { - let config = make_config( - "[account] - email = \"test@localhost\" - sender = \"none\" - backend = \"maildir\"", - ) - .await; - - assert!(config - .unwrap_err() - .root_cause() - .to_string() - .contains("missing field `maildir-root-dir`")); - } - - #[cfg(feature = "notmuch")] - #[tokio::test] - async fn account_backend_notmuch_missing_db_path_field() { - let config = make_config( - "[account] - email = \"test@localhost\" - sender = \"none\" - backend = \"notmuch\"", - ) - .await; - - assert!(config - .unwrap_err() - .root_cause() - .to_string() - .contains("missing field `notmuch-db-path`")); - } - - #[tokio::test] - async fn account_missing_sender_field() { - let config = make_config( - "[account] - email = \"test@localhost\" - backend = \"none\"", - ) - .await; - - assert!(config - .unwrap_err() - .root_cause() - .to_string() - .contains("missing field `sender`")); - } - - #[tokio::test] - async fn account_invalid_sender_field() { - let config = make_config( - "[account] - email = \"test@localhost\" - backend = \"none\" - sender = \"bad\"", - ) - .await; - - assert!(config - .unwrap_err() - .root_cause() - .to_string() - .contains("unknown variant `bad`, expected one of `none`, `smtp`, `sendmail`"),); - } - - #[tokio::test] - async fn account_smtp_sender_missing_host_field() { - let config = make_config( - "[account] - email = \"test@localhost\" - backend = \"none\" - sender = \"smtp\"", - ) - .await; - - assert!(config - .unwrap_err() - .root_cause() - .to_string() - .contains("missing field `smtp-host`")); - } - - #[tokio::test] - async fn account_smtp_sender_missing_port_field() { - let config = make_config( - "[account] - email = \"test@localhost\" - backend = \"none\" - sender = \"smtp\" - smtp-host = \"localhost\"", - ) - .await; - - assert!(config - .unwrap_err() - .root_cause() - .to_string() - .contains("missing field `smtp-port`")); - } - - #[tokio::test] - async fn account_smtp_sender_missing_login_field() { - let config = make_config( - "[account] - email = \"test@localhost\" - backend = \"none\" - sender = \"smtp\" - smtp-host = \"localhost\" - smtp-port = 25", - ) - .await; - - assert!(config - .unwrap_err() - .root_cause() - .to_string() - .contains("missing field `smtp-login`")); - } - - #[tokio::test] - async fn account_smtp_sender_missing_auth_field() { - let config = make_config( - "[account] - email = \"test@localhost\" - backend = \"none\" - sender = \"smtp\" - smtp-host = \"localhost\" - smtp-port = 25 - smtp-login = \"login\"", - ) - .await; - - assert!(config - .unwrap_err() - .root_cause() - .to_string() - .contains("missing field `smtp-auth`")); - } - - #[tokio::test] - async fn account_sendmail_sender_missing_cmd_field() { - let config = make_config( - "[account] - email = \"test@localhost\" - backend = \"none\" - sender = \"sendmail\"", - ) - .await; - - assert_eq!( - config.unwrap(), - TomlConfig { - accounts: HashMap::from_iter([( - "account".into(), - TomlAccountConfig { - email: "test@localhost".into(), - sender: SenderConfig::Sendmail(SendmailConfig { - cmd: "/usr/sbin/sendmail".into() - }), - ..TomlAccountConfig::default() - } - )]), - ..TomlConfig::default() - } - ) - } - - #[cfg(feature = "smtp")] - #[tokio::test] - async fn account_smtp_sender_minimum_config() { - use email::sender::SenderConfig; - - let config = make_config( - "[account] - email = \"test@localhost\" - backend = \"none\" - sender = \"smtp\" - smtp-host = \"localhost\" - smtp-port = 25 - smtp-login = \"login\" - smtp-auth = \"passwd\" - smtp-passwd = { cmd = \"echo password\" }", - ) - .await; - - assert_eq!( - config.unwrap(), - TomlConfig { - accounts: HashMap::from_iter([( - "account".into(), - TomlAccountConfig { - email: "test@localhost".into(), - sender: SenderConfig::Smtp(SmtpConfig { - host: "localhost".into(), - port: 25, - login: "login".into(), - auth: SmtpAuthConfig::Passwd(PasswdConfig { - passwd: Secret::new_cmd(String::from("echo password")) - }), - ..SmtpConfig::default() - }), - ..TomlAccountConfig::default() - } - )]), - ..TomlConfig::default() - } - ) - } - - #[tokio::test] - async fn account_sendmail_sender_minimum_config() { - let config = make_config( - "[account] - email = \"test@localhost\" - backend = \"none\" - sender = \"sendmail\" - sendmail-cmd = \"echo send\"", - ) - .await; - - assert_eq!( - config.unwrap(), - TomlConfig { - accounts: HashMap::from_iter([( - "account".into(), - TomlAccountConfig { - email: "test@localhost".into(), - sender: SenderConfig::Sendmail(SendmailConfig { - cmd: Cmd::from("echo send") - }), - ..TomlAccountConfig::default() - } - )]), - ..TomlConfig::default() - } - ) - } - - #[tokio::test] - async fn account_backend_imap_minimum_config() { - let config = make_config( - "[account] - email = \"test@localhost\" - sender = \"none\" - backend = \"imap\" - imap-host = \"localhost\" - imap-port = 993 - imap-login = \"login\" - imap-auth = \"passwd\" - imap-passwd = { cmd = \"echo password\" }", - ) - .await; - - assert_eq!( - config.unwrap(), - TomlConfig { - accounts: HashMap::from_iter([( - "account".into(), - TomlAccountConfig { - email: "test@localhost".into(), - backend: BackendConfig::Imap(ImapConfig { - host: "localhost".into(), - port: 993, - login: "login".into(), - auth: ImapAuthConfig::Passwd(PasswdConfig { - passwd: Secret::new_cmd(String::from("echo password")) - }), - ..ImapConfig::default() - }), - ..TomlAccountConfig::default() - } - )]), - ..TomlConfig::default() - } - ) - } - - #[tokio::test] - async fn account_backend_maildir_minimum_config() { - let config = make_config( - "[account] - email = \"test@localhost\" - sender = \"none\" - backend = \"maildir\" - maildir-root-dir = \"/tmp/maildir\"", - ) - .await; - - assert_eq!( - config.unwrap(), - TomlConfig { - accounts: HashMap::from_iter([( - "account".into(), - TomlAccountConfig { - email: "test@localhost".into(), - backend: BackendConfig::Maildir(MaildirConfig { - root_dir: "/tmp/maildir".into(), - }), - ..TomlAccountConfig::default() - } - )]), - ..TomlConfig::default() - } - ) - } - - #[cfg(feature = "notmuch")] - #[tokio::test] - async fn account_backend_notmuch_minimum_config() { - let config = make_config( - "[account] - email = \"test@localhost\" - sender = \"none\" - backend = \"notmuch\" - notmuch-db-path = \"/tmp/notmuch.db\"", - ) - .await; - - assert_eq!( - config.unwrap(), - TomlConfig { - accounts: HashMap::from_iter([( - "account".into(), - TomlAccountConfig { - email: "test@localhost".into(), - backend: BackendConfig::Notmuch(NotmuchConfig { - db_path: "/tmp/notmuch.db".into(), - }), - ..TomlAccountConfig::default() - } - )]), - ..TomlConfig::default() - } - ); - } -} diff --git a/src/email/envelope/mod.rs b/src/email/envelope/mod.rs index ab856b9..adde73b 100644 --- a/src/email/envelope/mod.rs +++ b/src/email/envelope/mod.rs @@ -121,74 +121,3 @@ impl PrintTable for Envelopes { Ok(()) } } - -#[cfg(test)] -mod tests { - use chrono::DateTime; - use email::account::config::AccountConfig; - use std::env; - - use crate::cache::IdMapper; - - use super::Envelopes; - - #[test] - fn default_datetime_fmt() { - let config = AccountConfig::default(); - let id_mapper = IdMapper::Dummy; - - let envelopes = email::envelope::Envelopes::from_iter([email::envelope::Envelope { - date: DateTime::parse_from_rfc3339("2023-06-15T09:42:00+04:00").unwrap(), - ..Default::default() - }]); - let envelopes = Envelopes::from_backend(&config, &id_mapper, envelopes).unwrap(); - - let expected_date = "2023-06-15 09:42+04:00"; - let date = &envelopes.first().unwrap().date; - - assert_eq!(date, expected_date); - } - - #[test] - fn custom_datetime_fmt() { - let id_mapper = IdMapper::Dummy; - let config = AccountConfig { - email_listing_datetime_fmt: Some("%d/%m/%Y %Hh%M".into()), - ..AccountConfig::default() - }; - - let envelopes = email::envelope::Envelopes::from_iter([email::envelope::Envelope { - date: DateTime::parse_from_rfc3339("2023-06-15T09:42:00+04:00").unwrap(), - ..Default::default() - }]); - let envelopes = Envelopes::from_backend(&config, &id_mapper, envelopes).unwrap(); - - let expected_date = "15/06/2023 09h42"; - let date = &envelopes.first().unwrap().date; - - assert_eq!(date, expected_date); - } - - #[test] - fn custom_datetime_fmt_with_local_tz() { - env::set_var("TZ", "UTC"); - - let id_mapper = IdMapper::Dummy; - let config = AccountConfig { - email_listing_datetime_fmt: Some("%d/%m/%Y %Hh%M".into()), - email_listing_datetime_local_tz: Some(true), - ..AccountConfig::default() - }; - - let envelopes = email::envelope::Envelopes::from_iter([email::envelope::Envelope { - date: DateTime::parse_from_rfc3339("2023-06-15T09:42:00+04:00").unwrap(), - ..Default::default() - }]); - let envelopes = Envelopes::from_backend(&config, &id_mapper, envelopes).unwrap(); - - let expected_date = "15/06/2023 05h42"; - let date = &envelopes.first().unwrap().date; - - assert_eq!(date, expected_date); - } -} diff --git a/src/folder/command/mod.rs b/src/folder/command/mod.rs index 5de0450..ec2d54b 100644 --- a/src/folder/command/mod.rs +++ b/src/folder/command/mod.rs @@ -47,194 +47,3 @@ impl FolderSubcommand { } } } - -#[cfg(test)] -mod tests { - use async_trait::async_trait; - use email::{ - account::config::AccountConfig, - backend::Backend, - envelope::{Envelope, Envelopes}, - flag::Flags, - folder::{Folder, Folders}, - message::Messages, - }; - use std::{any::Any, fmt::Debug, io}; - use termcolor::ColorSpec; - - use crate::printer::{Print, PrintTable, WriteColor}; - - use super::*; - - #[tokio::test] - async fn it_should_list_mboxes() { - #[derive(Debug, Default, Clone)] - struct StringWriter { - content: String, - } - - impl io::Write for StringWriter { - fn write(&mut self, buf: &[u8]) -> io::Result { - self.content - .push_str(&String::from_utf8(buf.to_vec()).unwrap()); - Ok(buf.len()) - } - - fn flush(&mut self) -> io::Result<()> { - self.content = String::default(); - Ok(()) - } - } - - impl termcolor::WriteColor for StringWriter { - fn supports_color(&self) -> bool { - false - } - - fn set_color(&mut self, _spec: &ColorSpec) -> io::Result<()> { - io::Result::Ok(()) - } - - fn reset(&mut self) -> io::Result<()> { - io::Result::Ok(()) - } - } - - impl WriteColor for StringWriter {} - - #[derive(Debug, Default)] - struct PrinterServiceTest { - pub writer: StringWriter, - } - - impl Printer for PrinterServiceTest { - fn print_table( - &mut self, - data: Box, - opts: PrintTableOpts, - ) -> anyhow::Result<()> { - data.print_table(&mut self.writer, opts)?; - Ok(()) - } - fn print_log(&mut self, _data: T) -> anyhow::Result<()> { - unimplemented!() - } - fn print( - &mut self, - _data: T, - ) -> anyhow::Result<()> { - unimplemented!() - } - fn is_json(&self) -> bool { - unimplemented!() - } - } - - struct TestBackend; - - #[async_trait] - impl Backend for TestBackend { - fn name(&self) -> String { - unimplemented!(); - } - async fn add_folder(&mut self, _: &str) -> email::Result<()> { - unimplemented!(); - } - async fn list_folders(&mut self) -> email::Result { - Ok(Folders::from_iter([ - Folder { - name: "INBOX".into(), - desc: "desc".into(), - }, - Folder { - name: "Sent".into(), - desc: "desc".into(), - }, - ])) - } - async fn expunge_folder(&mut self, _: &str) -> email::Result<()> { - unimplemented!(); - } - async fn purge_folder(&mut self, _: &str) -> email::Result<()> { - unimplemented!(); - } - async fn delete_folder(&mut self, _: &str) -> email::Result<()> { - unimplemented!(); - } - async fn get_envelope(&mut self, _: &str, _: &str) -> email::Result { - unimplemented!(); - } - async fn list_envelopes( - &mut self, - _: &str, - _: usize, - _: usize, - ) -> email::Result { - unimplemented!() - } - async fn search_envelopes( - &mut self, - _: &str, - _: &str, - _: &str, - _: usize, - _: usize, - ) -> email::Result { - unimplemented!() - } - async fn add_email(&mut self, _: &str, _: &[u8], _: &Flags) -> email::Result { - unimplemented!() - } - async fn get_emails(&mut self, _: &str, _: Vec<&str>) -> email::Result { - unimplemented!() - } - async fn preview_emails(&mut self, _: &str, _: Vec<&str>) -> email::Result { - unimplemented!() - } - async fn copy_emails(&mut self, _: &str, _: &str, _: Vec<&str>) -> email::Result<()> { - unimplemented!() - } - async fn move_emails(&mut self, _: &str, _: &str, _: Vec<&str>) -> email::Result<()> { - unimplemented!() - } - async fn delete_emails(&mut self, _: &str, _: Vec<&str>) -> email::Result<()> { - unimplemented!() - } - async fn add_flags(&mut self, _: &str, _: Vec<&str>, _: &Flags) -> email::Result<()> { - unimplemented!() - } - async fn set_flags(&mut self, _: &str, _: Vec<&str>, _: &Flags) -> email::Result<()> { - unimplemented!() - } - async fn remove_flags( - &mut self, - _: &str, - _: Vec<&str>, - _: &Flags, - ) -> email::Result<()> { - unimplemented!() - } - fn as_any(&self) -> &dyn Any { - unimplemented!() - } - } - - let account_config = AccountConfig::default(); - let mut printer = PrinterServiceTest::default(); - let mut backend = TestBackend {}; - - assert!(list(&account_config, &mut printer, &mut backend, None) - .await - .is_ok()); - assert_eq!( - concat![ - "\n", - "NAME │DESC \n", - "INBOX │desc \n", - "Sent │desc \n", - "\n" - ], - printer.writer.content - ); - } -}