feat: use util lib to interact with maildev

This commit is contained in:
Aravinth Manivannan 2024-09-13 16:04:25 +05:30
parent baedcb7719
commit cbe03ebaaa
Signed by: realaravinth
GPG key ID: F8F50389936984FF
6 changed files with 514 additions and 442 deletions

796
Cargo.lock generated

File diff suppressed because it is too large Load diff

View file

@ -5,7 +5,7 @@ edition = "2021"
[workspace]
exclude = ["utils/db-migrations"] #, "utils/cache-bust"]
memebers = ["."]
members = [".", "maildev_client"]
[dependencies]
actix-identity = "0.7.1"
@ -40,3 +40,4 @@ validator = { version = "0.18.1", features = ["derive"] }
[dev-dependencies]
reqwest = { version = "0.12.4", features = ["json"] }
maildev_client = { path = "./maildev_client" }

15
maildev_client/Cargo.toml Normal file
View file

@ -0,0 +1,15 @@
[package]
name = "maildev_client"
version = "0.1.0"
edition = "2021"
[dependencies]
reqwest = { version = "0.12.4", features = ["json"] }
serde = { version = "1.0.201", features = ["derive"] }
serde_json = "1.0.117"
actix-rt = "2.9.0"
derive-getters = "0.4.0"
derive_more = "0.99.17"
log = "0.4.21"
derive_builder = "0.20.0"
url = { version = "2.5.0", features = ["serde"] }

89
maildev_client/src/lib.rs Normal file
View file

@ -0,0 +1,89 @@
// SPDX-FileCopyrightText: 2024 Aravinth Manivannan <realaravinth@batsense.net>
//
// SPDX-License-Identifier: AGPL-3.0-or-later
use derive_builder::Builder;
use derive_getters::Getters;
#[allow(unused_imports)]
use log::*;
#[allow(unused_imports)]
#[cfg(test)]
use println as info;
use reqwest::Client;
use serde::{Deserialize, Serialize};
use url::Url;
#[derive(Serialize, Deserialize, Clone, Debug, Eq, PartialEq, Getters, Builder)]
#[serde(rename_all = "PascalCase")]
pub struct MaildevAddress {
address: String,
name: String,
}
#[derive(Serialize, Deserialize, Clone, Debug, Eq, PartialEq, Getters, Builder)]
#[serde(rename_all = "PascalCase")]
pub struct MaildevEmail {
#[serde(rename = "ID")]
id: String,
from: MaildevAddress,
to: Vec<MaildevAddress>,
subject: String,
#[serde(rename = "Snippet")]
text: String,
html: Option<String>,
}
#[derive(Clone, Debug, Getters, Builder)]
pub struct MaildevHTTPClient {
#[builder(default = "Client::default()")]
client: Client,
url: Url,
}
impl MaildevHTTPClient {
pub async fn list_emails(&self) -> Vec<MaildevEmail> {
#[derive(Serialize, Deserialize, Clone, Debug, Eq, PartialEq)]
struct List {
messages: Vec<MaildevEmail>,
}
let mut u = self.url.clone();
u.set_path("/api/v1/messages");
info!("trying to fetch emails: {}", u.as_str());
let list: List = self
.client
.get(u.clone())
.send()
.await
.unwrap()
.json()
.await
.unwrap();
list.messages
}
pub async fn get_email_addressed_to(&self, email_address: &str) -> MaildevEmail {
self.list_emails()
.await
.drain(0..)
.find(|e| e.to.iter().any(|f| f.address == email_address))
.unwrap()
}
pub async fn delete_email(&self, email: MaildevEmail) {
#[derive(Serialize, Deserialize, Clone, Debug, Eq, PartialEq)]
struct DeletePayload {
#[serde(rename = "IDs")]
id: Vec<String>,
}
let mut u = self.url.clone();
u.set_path("/api/v1/messages/");
info!("Deleting email from: {:?}", email.from);
let payload = DeletePayload { id: vec![email.id] };
self.client.delete(u).json(&payload).send().await.unwrap();
}
}

View file

@ -43,20 +43,7 @@ mod tests {
use serde::{Deserialize, Serialize};
//#[derive(Deserialize, Clone)]
//struct MaildevAddress {
// address: String,
// name: String,
//}
//#[derive(Deserialize, Clone)]
//struct MaildevEmail {
// id: String,
// from: Vec<MaildevAddress>,
// to: Vec<MaildevAddress>,
// subject: String,
// text: String,
// html: Option<String>,
//}
use maildev_client::*;
#[derive(Deserialize, Clone)]
struct MailPitAddress {
@ -113,38 +100,22 @@ mod tests {
.await
.unwrap();
let c = Client::default();
let maildev_url =
std::env::var("MAILDEV_URL").expect("Please set maildev instance URL in MAILDEV_URL");
let mut u = Url::parse(&maildev_url).unwrap();
u.set_path("/api/v1/messages");
let mailpit_emails: MailpitListEmails =
c.get(u.clone()).send().await.unwrap().json().await.unwrap();
let mailpit_summary = mailpit_emails
.messages
.iter()
.find(|e| e.to.iter().any(|f| f.address == email))
let mc = MaildevHTTPClientBuilder::default()
.url(Url::parse(&maildev_url).unwrap())
.build()
.unwrap();
u.set_path(&format!("/api/v1/message/{}", mailpit_summary.id));
let mailpit_email: MailpitEmail =
c.get(u.clone()).send().await.unwrap().json().await.unwrap();
let maildev_email = mc.get_email_addressed_to(email).await;
assert!(mailpit_email.text.contains(validation_secret));
assert!(mailpit_email.text.contains(username));
assert!(mailpit_email
.to
assert!(maildev_email.text().contains(validation_secret));
assert!(maildev_email.text().contains(username));
assert!(maildev_email
.to()
.iter()
.any(|t| t.address == email && t.name == username));
.any(|t| t.address() == email && t.name() == username));
u.set_path("/api/v1/messages");
let payload = MailpitDeleteEmail {
IDs: vec![mailpit_summary.id.clone()],
};
c.delete(u).json(&payload).send().await.unwrap();
mc.delete_email(maildev_email).await;
}
}

View file

@ -3,6 +3,8 @@ name = "db-migrations"
version = "0.1.0"
edition = "2021"
[workspace]
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]