1use hyper;
3use hyper::buffer::BufReader;
4use hyper::net::NetworkStream;
5
6use iron;
7use iron::prelude::*;
8use iron::{Handler, headers, Headers, method, Url};
9
10use std::io::Cursor;
11
12use super::mock_stream::MockStream;
13
14pub fn get<H: Handler>(path: &str, headers: Headers, handler: &H) -> IronResult<Response> {
16 request(method::Get, path, "", headers, handler)
17}
18
19pub fn post<H: Handler>(path: &str, headers: Headers, body: &str, handler: &H) -> IronResult<Response> {
21 request(method::Post, path, body, headers, handler)
22}
23
24pub fn patch<H: Handler>(path: &str, headers: Headers, body: &str, handler: &H) -> IronResult<Response> {
26 request(method::Patch, path, body, headers, handler)
27}
28
29pub fn put<H: Handler>(path: &str, headers: Headers, body: &str, handler: &H) -> IronResult<Response> {
31 request(method::Put, path, body, headers, handler)
32}
33
34pub fn delete<H: Handler>(path: &str, headers: Headers, handler: &H) -> IronResult<Response> {
36 request(method::Delete, path, "", headers, handler)
37}
38
39pub fn options<H: Handler>(path: &str, headers: Headers, handler: &H) -> IronResult<Response> {
41 request(method::Options, path, "", headers, handler)
42}
43
44pub fn head<H: Handler>(path: &str, headers: Headers, handler: &H) -> IronResult<Response> {
46 request(method::Head, path, "", headers, handler)
47}
48
49pub fn request<H: Handler>(method: method::Method,
52 path: &str,
53 body: &str,
54 headers: Headers,
55 handler: &H) -> IronResult<Response> {
56 let url = Url::parse(path).unwrap();
57 let mut buffer = String::new();
61 buffer.push_str(&format!("{} {} HTTP/1.1\r\n", &method, url));
62 buffer.push_str(&format!("Content-Length: {}\r\n", body.len() as u64));
63 for header in headers.iter() {
64 buffer.push_str(&format!("{}: {}\r\n", header.name(), header.value_string()));
65 }
66 if !headers.has::<headers::UserAgent>() {
67 buffer.push_str(&format!("User-Agent: iron-test\r\n"));
68 }
69 buffer.push_str("\r\n");
70 buffer.push_str(body);
71
72 let addr = "127.0.0.1:3000".parse().unwrap();
73 let protocol = match url.scheme() {
74 "http" => iron::Protocol::http(),
75 "https" => iron::Protocol::https(),
76 _ => panic!("unknown protocol {}", url.scheme()),
77 };
78
79 let mut stream = MockStream::new(Cursor::new(buffer.as_bytes().to_vec()));
80 let mut buf_reader = BufReader::new(&mut stream as &mut NetworkStream);
81 let http_request = hyper::server::Request::new(&mut buf_reader, addr).unwrap();
82 let mut req = Request::from_http(http_request, addr, &protocol).unwrap();
83
84 handler.handle(&mut req)
85}
86
87#[cfg(test)]
88mod test {
89 extern crate router;
90 extern crate urlencoded;
91
92 use iron::headers::Headers;
93 use iron::mime::Mime;
94 use iron::prelude::*;
95 use iron::{Handler, headers, status};
96
97 use response::{extract_body_to_bytes, extract_body_to_string};
98
99 use self::urlencoded::UrlEncodedBody;
100
101 use super::*;
102
103 struct HelloWorldHandler;
104
105 impl Handler for HelloWorldHandler {
106 fn handle(&self, _: &mut Request) -> IronResult<Response> {
107 Ok(Response::with((status::Ok, "Hello, world!")))
108 }
109 }
110
111 struct RouterHandler;
112
113 impl Handler for RouterHandler {
114 fn handle(&self, req: &mut Request) -> IronResult<Response> {
115 let params = req.extensions
116 .get::<router::Router>()
117 .expect("Expected to get a Router from the request extensions.");
118 let id = params.find("id").unwrap();
119
120 Ok(Response::with((status::Ok, id)))
121 }
122 }
123
124 struct PostHandler;
125
126 impl Handler for PostHandler {
127 fn handle(&self, req: &mut Request) -> IronResult<Response> {
128 let body = req.get_ref::<UrlEncodedBody>()
129 .expect("Expected to extract a UrlEncodedBody from the request");
130 let first_name = body.get("first_name").unwrap()[0].to_owned();
131 let last_name = body.get("last_name").unwrap()[0].to_owned();
132
133 Ok(Response::with((status::Ok, first_name + " " + &last_name)))
134 }
135 }
136
137 struct UpdateHandler;
138
139 impl Handler for UpdateHandler {
140 fn handle(&self, req: &mut Request) -> IronResult<Response> {
141 let id = {
142 let params = req.extensions
143 .get::<router::Router>()
144 .expect("Expected to get a Router from request extensions.");
145 params.find("id").unwrap().parse::<String>().unwrap()
146 };
147
148 let body = req.get_ref::<UrlEncodedBody>()
149 .expect("Expected to extract a UrlEncodedBody from the request");
150 let first_name = body.get("first_name").unwrap()[0].to_owned();
151 let last_name = body.get("last_name").unwrap()[0].to_owned();
152
153 Ok(Response::with((status::Ok, [first_name, last_name, id].join(" "))))
154 }
155 }
156
157 struct OptionsHandler;
158
159 impl Handler for OptionsHandler {
160 fn handle(&self, _: &mut Request) -> IronResult<Response> {
161 Ok(Response::with((status::Ok, "ALLOW: GET,POST")))
162 }
163 }
164
165 struct HeadHandler;
166
167 impl Handler for HeadHandler {
168 fn handle(&self, _: &mut Request) -> IronResult<Response> {
169 Ok(Response::with(status::Ok))
170 }
171 }
172
173 struct UserAgentHandler;
174
175 impl Handler for UserAgentHandler {
176 fn handle(&self, req: &mut Request) -> IronResult<Response> {
177 let user_agent = req.headers.get::<headers::UserAgent>().unwrap();
178 Ok(Response::with((status::Ok, user_agent.to_string())))
179 }
180 }
181
182 #[test]
183 fn test_get() {
184 let response = get("http://localhost:3000", Headers::new(), &HelloWorldHandler);
185 let result = extract_body_to_bytes(response.unwrap());
186
187 assert_eq!(result, b"Hello, world!");
188 }
189
190 #[test]
191 fn test_post() {
192 let mut headers = Headers::new();
193 let mime: Mime = "application/x-www-form-urlencoded".parse().unwrap();
194 headers.set(headers::ContentType(mime));
195 let response = post("http://localhost:3000/users",
196 headers,
197 "first_name=Example&last_name=User",
198 &PostHandler);
199 let result = extract_body_to_bytes(response.unwrap());
200
201 assert_eq!(result, b"Example User");
202 }
203
204 #[test]
205 fn test_patch() {
206 let mut router = router::Router::new();
207 router.patch("/users/:id", UpdateHandler, "update");
208
209 let mut headers = Headers::new();
210 let mime: Mime = "application/x-www-form-urlencoded".parse().unwrap();
211 headers.set(headers::ContentType(mime));
212 let response = patch("http://localhost:3000/users/1",
213 headers,
214 "first_name=Example&last_name=User",
215 &router);
216 let result = extract_body_to_bytes(response.unwrap());
217
218 assert_eq!(result, b"Example User 1");
219 }
220
221 #[test]
222 fn test_put() {
223 let mut router = router::Router::new();
224 router.put("/users/:id", UpdateHandler, "update");
225
226 let mut headers = Headers::new();
227 let mime: Mime = "application/x-www-form-urlencoded".parse().unwrap();
228 headers.set(headers::ContentType(mime));
229 let response = put("http://localhost:3000/users/2",
230 headers,
231 "first_name=Example&last_name=User",
232 &router);
233 let result = extract_body_to_bytes(response.unwrap());
234
235 assert_eq!(result, b"Example User 2");
236 }
237
238 #[test]
239 fn test_delete() {
240 let mut router = router::Router::new();
241 router.delete("/:id", RouterHandler, "update");
242
243 let response = delete("http://localhost:3000/1", Headers::new(), &router);
244 let result = extract_body_to_bytes(response.unwrap());
245
246 assert_eq!(result, b"1");
247 }
248
249
250 #[test]
251 fn test_options() {
252 let response = options("http://localhost:3000/users/options", Headers::new(), &OptionsHandler);
253 let result = extract_body_to_bytes(response.unwrap());
254
255 assert_eq!(result, b"ALLOW: GET,POST");
256 }
257
258 #[test]
259 fn test_head() {
260 let response = head("http://localhost:3000/users", Headers::new(), &HeadHandler);
261 let result = extract_body_to_bytes(response.unwrap());
262
263 assert_eq!(result, b"");
264 }
265
266 #[test]
267 fn test_user_agent_not_provided() {
268 let headers = Headers::new();
269 let response = get("http://localhost:3000/", headers, &UserAgentHandler);
270 let result = extract_body_to_string(response.unwrap());
271
272 assert_eq!(result, "iron-test");
273 }
274
275 #[test]
276 fn test_user_agent_provided() {
277 let mut headers = Headers::new();
278 headers.set(headers::UserAgent("CustomAgent/1.0".to_owned()));
279 let response = get("http://localhost:3000/", headers, &UserAgentHandler);
280 let result = extract_body_to_string(response.unwrap());
281
282 assert_eq!(result, "CustomAgent/1.0");
283 }
284
285 #[test]
286 fn test_percent_decoded_url() {
287 let response = head("http://localhost:3000/some path with spaces", Headers::new(), &HeadHandler);
288 let result = extract_body_to_bytes(response.unwrap());
289
290 assert_eq!(result, b"");
291 }
292}