Commit
Author: Kevin Schoon [me@kevinschoon.com]
Hash: f28739c6b03677b2019c0e48751a982052b65a2b
Timestamp: Sat, 04 Jan 2025 23:16:47 +0000 (2 weeks ago)

+49 -1 +/-1 browse
add an async test using the lettre client on a free port
1diff --git a/maitred/src/server.rs b/maitred/src/server.rs
2index 47acf14..e6b6192 100644
3--- a/maitred/src/server.rs
4+++ b/maitred/src/server.rs
5 @@ -304,7 +304,9 @@ impl Server {
6 .plain_auth
7 .as_ref()
8 .expect("authentication not available");
9- match cb.call(plain_auth.authenticate(&authcid, &authzid, &password).await) {
10+ match cb
11+ .call(plain_auth.authenticate(&authcid, &authzid, &password).await)
12+ {
13 crate::session::Action::Send(response) => {
14 conn.send(response).await?;
15 }
16 @@ -561,13 +563,19 @@ impl Server {
17 #[cfg(test)]
18 mod test {
19
20+ use crate::DeliveryFunc;
21+
22 use super::*;
23
24 use std::io;
25 use std::net::{Ipv4Addr, SocketAddrV4};
26 use std::pin::Pin;
27 use std::task::{Context, Poll};
28+
29+ use lettre::{AsyncSmtpTransport, AsyncTransport, Message as LettreMessage, Tokio1Executor};
30+ use port_check::free_local_ipv4_port;
31 use tokio::io::{AsyncRead, AsyncWrite};
32+ use tokio::sync::mpsc::channel;
33
34 /// Fake TCP stream for testing purposes with "framed" line oriented
35 /// requests to feed to the session processor.
36 @@ -688,4 +696,44 @@ mod test {
37 assert!(server.address("0.0.0.0:0").listen().await.is_err());
38 });
39 }
40+
41+ #[tokio::test]
42+ async fn server_lettre_client() {
43+ let test_port = free_local_ipv4_port().unwrap();
44+ let (tx, mut rx) = channel::<bool>(1);
45+ tokio::task::spawn(async move {
46+ let mut server = Server::default()
47+ .address(&format!("127.0.0.1:{}", test_port))
48+ .with_delivery(DeliveryFunc(move |envelope: &Envelope| {
49+ let tx_clone = tx.clone();
50+ let matches = envelope
51+ .body
52+ .body_text(0)
53+ .is_some_and(|body| body.contains("Hello World!"));
54+ async move {
55+ tx_clone.send(matches).await.unwrap();
56+ Ok(())
57+ }
58+ }));
59+ server.listen().await.unwrap();
60+ });
61+ let transport: AsyncSmtpTransport<Tokio1Executor> =
62+ AsyncSmtpTransport::<Tokio1Executor>::builder_dangerous("127.0.0.1")
63+ .port(test_port)
64+ .build();
65+ let message = LettreMessage::builder()
66+ .to("hello@example.org".parse().unwrap())
67+ .from("fuu@example.org".parse().unwrap())
68+ .cc("bar@example.org".parse().unwrap())
69+ .body(String::from("Hello World!\n"))
70+ .unwrap();
71+ // FIXME: Need synchronization in the server to tell us when it's
72+ // accepting connections.
73+ tokio::time::sleep(Duration::from_millis(500)).await;
74+ // BUG: Either the client doesn't respect batching or the server doesn't
75+ // implement it correctly (probably the latter).
76+ // assert!(transport.test_connection().await.is_ok_and(|ready| ready));
77+ transport.send(message).await.unwrap();
78+ assert!(rx.recv().await.is_some_and(|matches| matches));
79+ }
80 }