use fake::{
faker::internet::en::{Password, SafeEmail},
Fake,
};
use lazy_static::lazy_static;
use lettre::{
message::{header, Mailboxes},
transport::smtp::{
authentication::{Credentials, Mechanism},
client::{Certificate, TlsParameters, TlsParametersBuilder},
PoolConfig, SmtpTransport, SmtpTransportBuilder,
},
Message,
};
use maik::{MockServer, MockServerBuilder};
use std::collections::HashSet;
use std::time::Duration;
pub struct TestInfo {
pub mailer_builder: SmtpTransportBuilder,
pub tls_params: TlsParameters,
pub server: MockServer,
}
pub struct TestInfoBuilder {
server_builder: MockServerBuilder,
auth_user: Option<String>,
auth_password: Option<String>,
use_pool: bool,
}
pub const DEFAULT_SENDER: &str = "sender@domain1.com";
pub const DEFAULT_RECIPIENT: &str = "recipient@domain2.com";
pub const DEFAULT_BODY: &str = "Here is your verification code: 123456";
pub const DNE_USER: &str = "user_dne@xxx.com";
const DEFAULT_RECIPIENTS: &str = "r1@d.com, r2@d.com";
lazy_static! {
pub static ref DEFAULT_MESSAGE: Message = new_message(DEFAULT_RECIPIENT, DEFAULT_BODY);
pub static ref DEFAULT_MESSAGES: Message = new_message(DEFAULT_RECIPIENTS, DEFAULT_BODY);
pub static ref EMPTY_MESSAGE: Message = new_message(DEFAULT_RECIPIENT, "");
pub static ref EMPTY_MESSAGES: Message = new_message(DEFAULT_RECIPIENTS, "");
pub static ref DEFAULT_RECIPIENTS_SET: HashSet<&'static str> =
DEFAULT_RECIPIENTS.split(',').map(|s| s.trim()).collect();
}
impl TestInfoBuilder {
pub fn new() -> Self {
Self {
server_builder: MockServer::builder(),
auth_user: None,
auth_password: None,
use_pool: false,
}
}
pub fn set_require_tls(mut self) -> Self {
self.server_builder = self.server_builder.require_tls();
self
}
pub fn close_after_n(mut self, n: u8) -> Self {
self.server_builder = self.server_builder.assert_after_n_emails(n);
self.use_pool = true;
self
}
pub fn add_mailbox(mut self, smtp_user: &str, password: &str) -> Self {
self.server_builder = self.server_builder.add_mailbox(smtp_user, password);
self
}
pub fn auth_as(mut self, smtp_user: &str, password: &str) -> Self {
self.auth_user = Some(smtp_user.to_string());
self.auth_password = Some(password.to_string());
self
}
pub fn default_auth_user(mut self) -> Self {
self.server_builder = self.server_builder.no_verify_credentials();
self.auth_as(
&SafeEmail().fake::<String>(),
&Password(8..16).fake::<String>(),
)
}
pub fn build(self) -> TestInfo {
let server = self.server_builder.build();
let certificate = Certificate::from_pem(server.cert_pem()).unwrap();
server.start();
let mut mailer_builder = SmtpTransport::relay(&server.host().to_string())
.unwrap()
.port(server.port())
.timeout(Some(Duration::from_millis(200)));
if self.auth_user.is_some() && self.auth_user.is_some() {
let creds = Credentials::new(
self.auth_user.as_ref().unwrap().clone(),
self.auth_password.as_ref().unwrap().clone(),
);
mailer_builder = mailer_builder
.credentials(creds)
.authentication(vec![Mechanism::Plain]);
}
if !self.use_pool {
mailer_builder = mailer_builder.pool_config(PoolConfig::new().max_size(0));
}
TestInfo {
mailer_builder,
tls_params: TlsParametersBuilder::new(server.host().to_string())
.add_root_certificate(certificate)
.build()
.unwrap(),
server,
}
}
}
pub fn new_message(recipients: &str, body: &str) -> Message {
let mailboxes: Mailboxes = recipients.parse().unwrap();
let to_header: header::To = mailboxes.into();
Message::builder()
.from(DEFAULT_SENDER.parse().unwrap())
.mailbox(to_header)
.body(body.to_string())
.unwrap()
}