e45c7e529b 2026-07-31 1: use smtp2tg::mail::MailServer;
e45c7e529b 2026-07-31 2:
e45c7e529b 2026-07-31 3: use stacked_errors::{
e45c7e529b 2026-07-31 4: Result,
e45c7e529b 2026-07-31 5: StackableErr,
e45c7e529b 2026-07-31 6: };
e45c7e529b 2026-07-31 7:
e45c7e529b 2026-07-31 8: use tgbot::types::ChatPeerId;
e45c7e529b 2026-07-31 9: /// Builds a `MailServer` purely from an in-memory TOML source, no
e45c7e529b 2026-07-31 10: /// network access is performed while constructing it.
e45c7e529b 2026-07-31 11: fn build_server () -> Result<MailServer> {
e45c7e529b 2026-07-31 12: let settings = config::Config::builder()
e45c7e529b 2026-07-31 13: .add_source(config::File::from_str(r#"
e45c7e529b 2026-07-31 14: api_key = "test-api-key"
e45c7e529b 2026-07-31 15: api_gateway = "https://api.telegram.org"
e45c7e529b 2026-07-31 16: default = 0
e45c7e529b 2026-07-31 17: fields = ["date", "from", "subject"]
e45c7e529b 2026-07-31 18: domains = ["example.com"]
e45c7e529b 2026-07-31 19:
e45c7e529b 2026-07-31 20: [recipients]
e45c7e529b 2026-07-31 21: "someone@example.com" = 1
e45c7e529b 2026-07-31 22: "root" = -1
e45c7e529b 2026-07-31 23: "#, config::FileFormat::Toml))
e45c7e529b 2026-07-31 24: .build()
e45c7e529b 2026-07-31 25: .stack()?;
e45c7e529b 2026-07-31 26: MailServer::new(settings)
e45c7e529b 2026-07-31 27: }
e45c7e529b 2026-07-31 28:
e45c7e529b 2026-07-31 29: #[test]
158c9cffc6 2026-08-01 30: fn get_id_properly_resolves_addresses () -> Result<()> {
b9af445709 2026-07-31 31: let server = build_server()?;
b9af445709 2026-07-31 32: let cases = [
b9af445709 2026-07-31 33: ("someone@example.com", 1),
b9af445709 2026-07-31 34: ("someone", 0),
b9af445709 2026-07-31 35: ("root", -1),
b9af445709 2026-07-31 36: ("unknown@example.com", 0),
158c9cffc6 2026-08-01 37: ("SOMEONE@example.com", 1), // uppercase local part
158c9cffc6 2026-08-01 38: ("someone@EXAMPLE.COM", 1), // uppercase domain
158c9cffc6 2026-08-01 39: ("some.one@example.com", 1), // functionally equivalent to skipping '.'
158c9cffc6 2026-08-01 40: ("some-one-2", 0), // Hyphens
b9af445709 2026-07-31 41: ];
b9af445709 2026-07-31 42: for (email, id) in cases {
b9af445709 2026-07-31 43: assert_eq!(*server.get_id(email)?, ChatPeerId::from(id), "email [{email}] expected to return id [{id}]");
f748e99b70 2026-08-01 44: }
f748e99b70 2026-08-01 45: let cases = [
f748e99b70 2026-08-01 46: "someone@otherdomain.net",
158c9cffc6 2026-08-01 47: "@example.com", // empty local part
158c9cffc6 2026-08-01 48: "some@one@example.com", // more than one '@'
158c9cffc6 2026-08-01 49: "someone@example.com.evil",
158c9cffc6 2026-08-01 50: "someone@example.org",
f748e99b70 2026-08-01 51: ];
f748e99b70 2026-08-01 52: for email in cases {
158c9cffc6 2026-08-01 53: let err = server.get_id(email).err()
158c9cffc6 2026-08-01 54: .ok_or_else(|| format!("email [{email}] expected to fail")).stack()?;
158c9cffc6 2026-08-01 55: assert!(err.to_string().contains("Doesn't look like address from one of our domains."));
b9af445709 2026-07-31 56: }
e45c7e529b 2026-07-31 57: Ok(())
e45c7e529b 2026-07-31 58: }