use crate::model::email::EmailMessage;
use crate::repository::email::EmailClient;
use lightspeed_core::error::LsError;
use log::warn;
use parking_lot::Mutex;
use std::future::Future;
use std::pin::Pin;
use std::sync::Arc;
#[derive(Clone, Default)]
pub struct InMemoryEmailClient {
emails: Arc<Mutex<Vec<EmailMessage>>>,
}
impl InMemoryEmailClient {
pub fn new() -> Self {
Self::default()
}
}
impl EmailClient for InMemoryEmailClient {
fn send(&self, email_message: EmailMessage) -> Pin<Box<dyn Future<Output = Result<(), LsError>> + Send>> {
let emails = self.emails.clone();
Box::pin(async move {
warn!("InMemoryEmailService - Received an email. The email is NOT going to be sent but kept in memory");
let mut lock = emails.lock();
lock.push(email_message);
Ok(())
})
}
fn get_emails(&self) -> Result<Vec<EmailMessage>, LsError> {
let lock = self.emails.lock();
Ok(lock.clone())
}
fn clear_emails(&self) -> Result<(), LsError> {
let mut lock = self.emails.lock();
lock.clear();
Ok(())
}
fn retain_emails(&self, mut retain: Box<dyn FnMut(&EmailMessage) -> bool>) -> Result<(), LsError> {
let mut lock = self.emails.lock();
lock.retain(|email| retain(email));
Ok(())
}
}
#[cfg(test)]
pub mod test {
use super::*;
use lightspeed_core::utils::new_hyphenated_uuid;
#[tokio::test]
async fn should_keep_emails_in_memory() {
let mut email_1 = EmailMessage::new();
email_1.subject = Some(new_hyphenated_uuid());
let mut email_2 = EmailMessage::new();
email_2.subject = Some(new_hyphenated_uuid());
let email_service = InMemoryEmailClient::new();
email_service.send(email_1.clone()).await.unwrap();
email_service.send(email_2.clone()).await.unwrap();
email_service.send(email_1.clone()).await.unwrap();
let emails = email_service.get_emails().unwrap();
assert_eq!(3, emails.len());
assert_eq!(email_1.subject, emails[0].subject);
assert_eq!(email_2.subject, emails[1].subject);
assert_eq!(email_1.subject, emails[2].subject);
}
#[tokio::test]
async fn should_clear_emails() {
let mut email_1 = EmailMessage::new();
email_1.subject = Some(new_hyphenated_uuid());
let email_service = InMemoryEmailClient::new();
email_service.send(email_1.clone()).await.unwrap();
email_service.send(email_1.clone()).await.unwrap();
{
let emails = email_service.get_emails().unwrap();
assert!(!emails.is_empty());
}
email_service.clear_emails().unwrap();
let emails = email_service.get_emails().unwrap();
assert!(emails.is_empty());
}
}