trillium_testing/
server_connector.rs1use crate::TestTransport;
2use std::sync::Arc;
3use url::Url;
4
5#[derive(Debug)]
7pub struct ServerConnector<H> {
8 handler: Arc<H>,
9}
10
11impl<H> ServerConnector<H>
12where
13 H: trillium::Handler,
14{
15 pub fn new(handler: H) -> Self {
17 Self {
18 handler: Arc::new(handler),
19 }
20 }
21
22 pub async fn connect(&self, secure: bool) -> TestTransport {
24 let (client_transport, server_transport) = TestTransport::new();
25
26 let handler = Arc::clone(&self.handler);
27
28 crate::spawn(async move {
29 trillium_http::Conn::map(server_transport, Default::default(), |mut conn| {
30 let handler = Arc::clone(&handler);
31 async move {
32 conn.set_secure(secure);
33 let conn = handler.run(conn.into()).await;
34 let conn = handler.before_send(conn).await;
35 conn.into_inner()
36 }
37 })
38 .await
39 .unwrap();
40 });
41
42 client_transport
43 }
44}
45
46#[trillium_server_common::async_trait]
47impl<H: trillium::Handler> trillium_server_common::Connector for ServerConnector<H> {
48 type Transport = TestTransport;
49 async fn connect(&self, url: &Url) -> std::io::Result<Self::Transport> {
50 Ok(self.connect(url.scheme() == "https").await)
51 }
52
53 fn spawn<Fut: std::future::Future<Output = ()> + Send + 'static>(&self, fut: Fut) {
54 crate::spawn(fut);
55 }
56}
57
58pub fn connector(handler: impl trillium::Handler) -> impl trillium_server_common::Connector {
60 ServerConnector::new(handler)
61}
62
63#[cfg(test)]
64mod test {
65 use crate::server_connector::ServerConnector;
66 use trillium_client::Client;
67
68 #[test]
69 fn test() {
70 crate::block_on(async {
71 let client = Client::new(ServerConnector::new("test"));
72 let mut conn = client.get("https://example.com/test").await.unwrap();
73 assert_eq!(conn.response_body().read_string().await.unwrap(), "test");
74 });
75 }
76
77 #[test]
78 fn test_no_dns() {
79 crate::block_on(async {
80 let client = Client::new(ServerConnector::new("test"));
81 let mut conn = client
82 .get("https://not.a.real.tld.example/test")
83 .await
84 .unwrap();
85 assert_eq!(conn.response_body().read_string().await.unwrap(), "test");
86 });
87 }
88
89 #[test]
90 fn test_post() {
91 crate::block_on(async {
92 let client = Client::new(ServerConnector::new(
93 |mut conn: trillium::Conn| async move {
94 let body = conn.request_body_string().await.unwrap();
95 let response = format!(
96 "{} {}://{}{} with body \"{}\"",
97 conn.method(),
98 if conn.is_secure() { "https" } else { "http" },
99 conn.inner().host().unwrap_or_default(),
100 conn.path(),
101 body
102 );
103
104 conn.ok(response)
105 },
106 ));
107
108 let body = client
109 .post("https://example.com/test")
110 .with_body("some body")
111 .await
112 .unwrap()
113 .response_body()
114 .read_string()
115 .await
116 .unwrap();
117
118 assert_eq!(
119 body,
120 "POST https://example.com/test with body \"some body\""
121 );
122 });
123 }
124}