thruster_app/
testing_async.rs

1use 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}