thruster_app/
testing_async.rs1use bytes::{BytesMut, BufMut};
2use std::collections::HashMap;
3
4use crate::app::App;
5
6use thruster_core::context::Context;
7use thruster_core::response::{Response, StatusMessage};
8use thruster_core::request::decode;
9use thruster_core::request::Request;
10
11pub async fn request<T: Context<Response = Response> + Send>(app: &App<Request, T>, method: &str, route: &str, headers: &[(&str, &str)], body: &str) -> TestResponse {
12 let headers_mapped: Vec<String> = headers
13 .iter()
14 .map(|val| format!("{}: {}", val.0, val.1))
15 .collect();
16 let headers = headers_mapped
17 .join("\n");
18 let body = format!("{} {} HTTP/1.1\nHost: localhost:8080\n{}\n\n{}", method, route, headers, body);
19
20 let mut bytes = BytesMut::with_capacity(body.len());
21 bytes.put(body.as_bytes());
22
23
24 let request = decode(&mut bytes).unwrap().unwrap();
25 let matched_route = app.resolve_from_method_and_path("GET", route);
26 let response = app.resolve(request, matched_route).await.unwrap();
27
28 TestResponse::new(response)
29}
30
31
32pub async fn get<T: Context<Response = Response> + Send>(app: &App<Request, T>, route: &str) -> TestResponse {
33 let body = format!("GET {} HTTP/1.1\nHost: localhost:8080\n\n", route);
34
35 let mut bytes = BytesMut::with_capacity(body.len());
36 bytes.put(body.as_bytes());
37
38
39 let request = decode(&mut bytes).unwrap().unwrap();
40 let matched_route = app.resolve_from_method_and_path("GET", route);
41 let response = app.resolve(request, matched_route).await.unwrap();
42
43 TestResponse::new(response)
44}
45
46pub async fn delete<T: Context<Response = Response> + Send>(app: &App<Request, T>, route: &str) -> TestResponse {
47 let body = format!("DELETE {} HTTP/1.1\nHost: localhost:8080\n\n", route);
48
49 let mut bytes = BytesMut::with_capacity(body.len());
50 bytes.put(body.as_bytes());
51
52
53 let request = decode(&mut bytes).unwrap().unwrap();
54 let matched_route = app.resolve_from_method_and_path("DELETE", route);
55 let response = app.resolve(request, matched_route).await.unwrap();
56
57
58 TestResponse::new(response)
59}
60
61pub async fn post<T: Context<Response = Response> + Send>(app: &App<Request, T>, route: &str, content: &str) -> TestResponse {
62 let body = format!("POST {} HTTP/1.1\nHost: localhost:8080\nContent-Length: {}\n\n{}", route, content.len(), content);
63
64 let mut bytes = BytesMut::with_capacity(body.len());
65 bytes.put(body.as_bytes());
66
67
68 let request = decode(&mut bytes).unwrap().unwrap();
69 let matched_route = app.resolve_from_method_and_path("POST", route);
70 let response = app.resolve(request, matched_route).await.unwrap();
71
72
73 TestResponse::new(response)
74}
75
76pub async fn put<T: Context<Response = Response> + Send>(app: &App<Request, T>, route: &str, content: &str) -> TestResponse {
77 let body = format!("PUT {} HTTP/1.1\nHost: localhost:8080\nContent-Length: {}\n\n{}", route, content.len(), content);
78
79 let mut bytes = BytesMut::with_capacity(body.len());
80 bytes.put(body.as_bytes());
81
82
83 let request = decode(&mut bytes).unwrap().unwrap();
84 let matched_route = app.resolve_from_method_and_path("PUT", route);
85 let response = app.resolve(request, matched_route).await.unwrap();
86
87
88 TestResponse::new(response)
89}
90
91pub async fn update<T: Context<Response = Response> + Send>(app: &App<Request, T>, route: &str, content: &str) -> TestResponse {
92 let body = format!("UPDATE {} HTTP/1.1\nHost: localhost:8080\nContent-Length: {}\n\n{}", route, content.len(), content);
93
94 let mut bytes = BytesMut::with_capacity(body.len());
95 bytes.put(body.as_bytes());
96
97
98 let request = decode(&mut bytes).unwrap().unwrap();
99 let matched_route = app.resolve_from_method_and_path("UPDATE", route);
100 let response = app.resolve(request, matched_route).await.unwrap();
101
102
103 TestResponse::new(response)
104}
105
106#[derive(Debug)]
107pub struct TestResponse {
108 pub body: String,
109 pub headers: HashMap<String, String>,
110 pub status: (String, u32)
111}
112
113impl TestResponse {
114 fn new(response: Response) -> TestResponse {
115 let mut headers = HashMap::new();
116 let header_string = String::from_utf8(response.header_raw.to_vec()).unwrap();
117
118 for header_pair in header_string.split("\r\n") {
119 if !header_pair.is_empty() {
120 let mut split = header_pair.split(':');
121 let key = split.next().unwrap().trim().to_owned();
122 let value = split.next().unwrap().trim().to_owned();
123
124 headers.insert(key, value);
125 }
126 }
127
128 TestResponse {
129 body: String::from_utf8(response.response).unwrap(),
130 headers,
131 status: match response.status_message {
132 StatusMessage::Ok => ("Ok".to_owned(), 200),
133 StatusMessage::Custom(code, message) => (message, code)
134 }
135 }
136 }
137}