pub const DOMAIN: &str = "testing.lettermint.co";
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Scenario {
Ok,
SoftBounce,
HardBounce,
SpamComplaint,
Dsn,
}
impl Scenario {
#[must_use]
pub fn local_part(&self) -> &'static str {
match self {
Self::Ok => "ok",
Self::SoftBounce => "softbounce",
Self::HardBounce => "hardbounce",
Self::SpamComplaint => "spamcomplaint",
Self::Dsn => "dsn",
}
}
#[must_use]
pub fn email(&self) -> String {
custom(self.local_part())
}
#[must_use]
pub fn random(&self) -> String {
use std::sync::atomic::{AtomicU64, Ordering};
use std::time::{SystemTime, UNIX_EPOCH};
static COUNTER: AtomicU64 = AtomicU64::new(0);
let ts = SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap_or_default()
.as_nanos();
let seq = COUNTER.fetch_add(1, Ordering::Relaxed);
let pid = std::process::id();
custom(&format!("{}+{ts}-{pid}-{seq}", self.local_part()))
}
}
#[must_use]
pub fn custom(local_part: &str) -> String {
format!("{local_part}@{DOMAIN}")
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn scenario_emails() {
assert_eq!(Scenario::Ok.email(), "ok@testing.lettermint.co");
assert_eq!(
Scenario::SoftBounce.email(),
"softbounce@testing.lettermint.co"
);
assert_eq!(
Scenario::HardBounce.email(),
"hardbounce@testing.lettermint.co"
);
assert_eq!(
Scenario::SpamComplaint.email(),
"spamcomplaint@testing.lettermint.co"
);
assert_eq!(Scenario::Dsn.email(), "dsn@testing.lettermint.co");
}
#[test]
fn custom_builds_address() {
assert_eq!(custom("hello"), "hello@testing.lettermint.co");
assert_eq!(custom("ok+tag"), "ok+tag@testing.lettermint.co");
}
#[test]
fn random_is_unique() {
let a = Scenario::Ok.random();
let b = Scenario::Ok.random();
assert_ne!(a, b);
assert!(a.starts_with("ok+"));
assert!(a.ends_with(&format!("@{DOMAIN}")));
}
#[test]
fn random_respects_scenario() {
let addr = Scenario::HardBounce.random();
assert!(addr.starts_with("hardbounce+"));
assert!(addr.ends_with(&format!("@{DOMAIN}")));
}
}