1 #![deny(warnings)]
2 
3 use bytes::Buf;
4 use futures::TryStreamExt;
5 use warp::Filter;
6 
7 #[tokio::test]
matches()8 async fn matches() {
9     let _ = pretty_env_logger::try_init();
10 
11     let concat = warp::body::bytes();
12 
13     let req = warp::test::request().path("/nothing-matches-me");
14 
15     assert!(req.matches(&concat).await);
16 
17     let p = warp::path("body");
18     let req = warp::test::request().path("/body");
19 
20     let and = p.and(concat);
21 
22     assert!(req.matches(&and).await);
23 }
24 
25 #[tokio::test]
server_error_if_taking_body_multiple_times()26 async fn server_error_if_taking_body_multiple_times() {
27     let _ = pretty_env_logger::try_init();
28 
29     let concat = warp::body::bytes();
30     let double = concat.and(concat).map(|_, _| warp::reply());
31 
32     let res = warp::test::request().reply(&double).await;
33 
34     assert_eq!(res.status(), 500);
35     assert_eq!(res.body(), "Request body consumed multiple times");
36 }
37 
38 #[tokio::test]
content_length_limit()39 async fn content_length_limit() {
40     let _ = pretty_env_logger::try_init();
41 
42     let limit = warp::body::content_length_limit(30).map(warp::reply);
43 
44     let res = warp::test::request().reply(&limit).await;
45     assert_eq!(res.status(), 411, "missing content-length returns 411");
46 
47     let res = warp::test::request()
48         .header("content-length", "999")
49         .reply(&limit)
50         .await;
51     assert_eq!(res.status(), 413, "over limit returns 413");
52 
53     let res = warp::test::request()
54         .header("content-length", "2")
55         .reply(&limit)
56         .await;
57     assert_eq!(res.status(), 200, "under limit succeeds");
58 }
59 
60 #[tokio::test]
json()61 async fn json() {
62     let _ = pretty_env_logger::try_init();
63 
64     let json = warp::body::json::<Vec<i32>>();
65 
66     let req = warp::test::request().body("[1, 2, 3]");
67 
68     let vec = req.filter(&json).await.unwrap();
69     assert_eq!(vec, &[1, 2, 3]);
70 
71     let req = warp::test::request()
72         .header("content-type", "application/json")
73         .body("[3, 2, 1]");
74 
75     let vec = req.filter(&json).await.unwrap();
76     assert_eq!(vec, &[3, 2, 1], "matches content-type");
77 }
78 
79 #[tokio::test]
json_rejects_bad_content_type()80 async fn json_rejects_bad_content_type() {
81     let _ = pretty_env_logger::try_init();
82 
83     let json = warp::body::json::<Vec<i32>>().map(|_| warp::reply());
84 
85     let req = warp::test::request()
86         .header("content-type", "text/xml")
87         .body("[3, 2, 1]");
88 
89     let res = req.reply(&json).await;
90     assert_eq!(
91         res.status(),
92         415,
93         "bad content-type should be 415 Unsupported Media Type"
94     );
95 }
96 
97 #[tokio::test]
json_invalid()98 async fn json_invalid() {
99     let _ = pretty_env_logger::try_init();
100 
101     let json = warp::body::json::<Vec<i32>>().map(|vec| warp::reply::json(&vec));
102 
103     let res = warp::test::request().body("lol#wat").reply(&json).await;
104     assert_eq!(res.status(), 400);
105     let prefix = b"Request body deserialize error: ";
106     assert_eq!(&res.body()[..prefix.len()], prefix);
107 }
108 
109 #[test]
json_size_of()110 fn json_size_of() {
111     let json = warp::body::json::<Vec<i32>>();
112     assert_eq!(std::mem::size_of_val(&json), 0);
113 }
114 
115 #[tokio::test]
form()116 async fn form() {
117     let _ = pretty_env_logger::try_init();
118 
119     let form = warp::body::form::<Vec<(String, String)>>();
120 
121     let req = warp::test::request().body("foo=bar&baz=quux");
122 
123     let vec = req.filter(&form).await.unwrap();
124     let expected = vec![
125         ("foo".to_owned(), "bar".to_owned()),
126         ("baz".to_owned(), "quux".to_owned()),
127     ];
128     assert_eq!(vec, expected);
129 }
130 
131 #[tokio::test]
form_rejects_bad_content_type()132 async fn form_rejects_bad_content_type() {
133     let _ = pretty_env_logger::try_init();
134 
135     let form = warp::body::form::<Vec<(String, String)>>().map(|_| warp::reply());
136 
137     let req = warp::test::request()
138         .header("content-type", "application/x-www-form-urlencoded")
139         .body("foo=bar");
140 
141     let res = req.reply(&form).await;
142     assert_eq!(res.status(), 200);
143 
144     let req = warp::test::request()
145         .header("content-type", "text/xml")
146         .body("foo=bar");
147     let res = req.reply(&form).await;
148     assert_eq!(
149         res.status(),
150         415,
151         "bad content-type should be 415 Unsupported Media Type"
152     );
153 }
154 
155 #[tokio::test]
form_allows_charset()156 async fn form_allows_charset() {
157     let _ = pretty_env_logger::try_init();
158 
159     let form = warp::body::form::<Vec<(String, String)>>();
160 
161     let req = warp::test::request()
162         .header(
163             "content-type",
164             "application/x-www-form-urlencoded; charset=utf-8",
165         )
166         .body("foo=bar");
167 
168     let vec = req.filter(&form).await.unwrap();
169     let expected = vec![("foo".to_owned(), "bar".to_owned())];
170     assert_eq!(vec, expected);
171 }
172 
173 #[tokio::test]
form_invalid()174 async fn form_invalid() {
175     let _ = pretty_env_logger::try_init();
176 
177     let form = warp::body::form::<Vec<i32>>().map(|vec| warp::reply::json(&vec));
178 
179     let res = warp::test::request().body("nope").reply(&form).await;
180     assert_eq!(res.status(), 400);
181     let prefix = b"Request body deserialize error: ";
182     assert_eq!(&res.body()[..prefix.len()], prefix);
183 }
184 
185 #[tokio::test]
stream()186 async fn stream() {
187     let _ = pretty_env_logger::try_init();
188 
189     let stream = warp::body::stream();
190 
191     let body = warp::test::request()
192         .body("foo=bar")
193         .filter(&stream)
194         .await
195         .expect("filter() stream");
196 
197     let bufs: Result<Vec<_>, warp::Error> = body.try_collect().await;
198     let bufs = bufs.unwrap();
199 
200     assert_eq!(bufs.len(), 1);
201     assert_eq!(bufs[0].chunk(), b"foo=bar");
202 }
203