Skip to content

Commit 565f14c

Browse files
committed
Factor out HTTP integration tests to http module
1 parent 5f69b1d commit 565f14c

File tree

2 files changed

+161
-127
lines changed

2 files changed

+161
-127
lines changed

src/http.rs

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,3 +90,120 @@ impl<'a> ser::Serialize for GraphQLResponse<'a> {
9090
}
9191
}
9292
}
93+
94+
#[cfg(test)]
95+
pub mod tests {
96+
use serde_json::Value as Json;
97+
use serde_json;
98+
99+
pub struct TestResponse {
100+
pub status_code: i32,
101+
pub body: Option<String>,
102+
pub content_type: String,
103+
}
104+
105+
pub trait HTTPIntegration {
106+
fn get(&self, url: &str) -> TestResponse;
107+
fn post(&self, url: &str, body: &str) -> TestResponse;
108+
}
109+
110+
pub fn run_http_test_suite<T: HTTPIntegration>(integration: &T) {
111+
println!("Running HTTP Test suite for integration");
112+
113+
println!(" - test_simple_get");
114+
test_simple_get(integration);
115+
116+
println!(" - test_encoded_get");
117+
test_encoded_get(integration);
118+
119+
println!(" - test_get_with_variables");
120+
test_get_with_variables(integration);
121+
122+
println!(" - test_simple_post");
123+
test_simple_post(integration);
124+
}
125+
126+
fn unwrap_json_response(response: &TestResponse) -> Json {
127+
serde_json::from_str::<Json>(
128+
response.body.as_ref().expect("No data returned from request")
129+
).expect("Could not parse JSON object")
130+
}
131+
132+
fn test_simple_get<T: HTTPIntegration>(integration: &T) {
133+
let response = integration.get("/?query={hero{name}}");
134+
135+
assert_eq!(response.status_code, 200);
136+
assert_eq!(response.content_type.as_str(), "application/json");
137+
138+
assert_eq!(
139+
unwrap_json_response(&response),
140+
serde_json::from_str::<Json>(r#"{"data": {"hero": {"name": "R2-D2"}}}"#)
141+
.expect("Invalid JSON constant in test"));
142+
}
143+
144+
fn test_encoded_get<T: HTTPIntegration>(integration: &T) {
145+
let response = integration.get(
146+
"/?query=query%20{%20%20%20human(id:%20\"1000\")%20{%20%20%20%20%20id,%20%20%20%20%20name,%20%20%20%20%20appearsIn,%20%20%20%20%20homePlanet%20%20%20}%20}");
147+
148+
assert_eq!(response.status_code, 200);
149+
assert_eq!(response.content_type.as_str(), "application/json");
150+
151+
assert_eq!(
152+
unwrap_json_response(&response),
153+
serde_json::from_str::<Json>(r#"{
154+
"data": {
155+
"human": {
156+
"appearsIn": [
157+
"NEW_HOPE",
158+
"EMPIRE",
159+
"JEDI"
160+
],
161+
"homePlanet": "Tatooine",
162+
"name": "Luke Skywalker",
163+
"id": "1000"
164+
}
165+
}
166+
}"#)
167+
.expect("Invalid JSON constant in test"));
168+
}
169+
170+
fn test_get_with_variables<T: HTTPIntegration>(integration: &T) {
171+
let response = integration.get(
172+
"/?query=query($id:%20String!)%20{%20%20%20human(id:%20$id)%20{%20%20%20%20%20id,%20%20%20%20%20name,%20%20%20%20%20appearsIn,%20%20%20%20%20homePlanet%20%20%20}%20}&variables={%20%20%20\"id\":%20%20\"1000\"%20}");
173+
174+
assert_eq!(response.status_code, 200);
175+
assert_eq!(response.content_type, "application/json");
176+
177+
assert_eq!(
178+
unwrap_json_response(&response),
179+
serde_json::from_str::<Json>(r#"{
180+
"data": {
181+
"human": {
182+
"appearsIn": [
183+
"NEW_HOPE",
184+
"EMPIRE",
185+
"JEDI"
186+
],
187+
"homePlanet": "Tatooine",
188+
"name": "Luke Skywalker",
189+
"id": "1000"
190+
}
191+
}
192+
}"#)
193+
.expect("Invalid JSON constant in test"));
194+
}
195+
196+
fn test_simple_post<T: HTTPIntegration>(integration: &T) {
197+
let response = integration.post(
198+
"/",
199+
r#"{"query": "{hero{name}}"}"#);
200+
201+
assert_eq!(response.status_code, 200);
202+
assert_eq!(response.content_type, "application/json");
203+
204+
assert_eq!(
205+
unwrap_json_response(&response),
206+
serde_json::from_str::<Json>(r#"{"data": {"hero": {"name": "R2-D2"}}}"#)
207+
.expect("Invalid JSON constant in test"));
208+
}
209+
}

src/integrations/iron_handlers.rs

Lines changed: 44 additions & 127 deletions
Original file line numberDiff line numberDiff line change
@@ -215,153 +215,70 @@ impl From<GraphQLIronError> for IronError {
215215

216216
#[cfg(test)]
217217
mod tests {
218-
use serde_json::Value as Json;
219-
use serde_json;
220218
use iron::prelude::*;
221-
use iron::status;
222-
use iron::headers;
223219
use iron_test::{request, response};
224220
use iron::{Handler, Headers};
225221

226222
use ::tests::model::Database;
223+
use ::http::tests as http_tests;
227224
use types::scalars::EmptyMutation;
228225

229226
use super::GraphQLHandler;
230227

231-
fn context_factory(_: &mut Request) -> Database {
232-
Database::new()
233-
}
234-
235-
fn make_handler() -> Box<Handler> {
236-
Box::new(GraphQLHandler::new(
237-
context_factory,
238-
Database::new(),
239-
EmptyMutation::<Database>::new(),
240-
))
241-
}
228+
struct TestIronIntegration;
242229

243-
fn unwrap_json_response(resp: Response) -> Json {
244-
let result = response::extract_body_to_string(resp);
230+
impl http_tests::HTTPIntegration for TestIronIntegration
231+
{
232+
fn get(&self, url: &str) -> http_tests::TestResponse {
233+
make_test_response(request::get(
234+
&("http://localhost:3000".to_owned() + url),
235+
Headers::new(),
236+
&make_handler(),
237+
))
238+
}
245239

246-
serde_json::from_str::<Json>(&result).expect("Could not parse JSON object")
240+
fn post(&self, url: &str, body: &str) -> http_tests::TestResponse {
241+
make_test_response(request::post(
242+
&("http://localhost:3000".to_owned() + url),
243+
Headers::new(),
244+
body,
245+
&make_handler(),
246+
))
247+
}
247248
}
248249

249250
#[test]
250-
fn test_simple_get() {
251-
let response = request::get(
252-
"http://localhost:3000/?query={hero{name}}",
253-
Headers::new(),
254-
&make_handler())
255-
.expect("Unexpected IronError");
256-
257-
assert_eq!(response.status, Some(status::Ok));
258-
assert_eq!(response.headers.get::<headers::ContentType>(),
259-
Some(&headers::ContentType::json()));
260-
261-
let json = unwrap_json_response(response);
262-
263-
assert_eq!(
264-
json,
265-
serde_json::from_str::<Json>(r#"{"data": {"hero": {"name": "R2-D2"}}}"#)
266-
.expect("Invalid JSON constant in test"));
267-
}
251+
fn test_iron_integration() {
252+
let integration = TestIronIntegration;
268253

269-
#[test]
270-
fn test_encoded_get() {
271-
let response = request::get(
272-
"http://localhost:3000/?query=query%20{%20%20%20human(id:%20\"1000\")%20{%20%20%20%20%20id,%20%20%20%20%20name,%20%20%20%20%20appearsIn,%20%20%20%20%20homePlanet%20%20%20}%20}",
273-
Headers::new(),
274-
&make_handler())
275-
.expect("Unexpected IronError");
276-
277-
assert_eq!(response.status, Some(status::Ok));
278-
assert_eq!(response.headers.get::<headers::ContentType>(),
279-
Some(&headers::ContentType::json()));
280-
281-
let json = unwrap_json_response(response);
282-
283-
assert_eq!(
284-
json,
285-
serde_json::from_str::<Json>(r#"{
286-
"data": {
287-
"human": {
288-
"appearsIn": [
289-
"NEW_HOPE",
290-
"EMPIRE",
291-
"JEDI"
292-
],
293-
"homePlanet": "Tatooine",
294-
"name": "Luke Skywalker",
295-
"id": "1000"
296-
}
297-
}
298-
}"#)
299-
.expect("Invalid JSON constant in test"));
254+
http_tests::run_http_test_suite(&integration);
300255
}
301256

302-
#[test]
303-
fn test_get_with_variables() {
304-
let response = request::get(
305-
"http://localhost:3000/?query=query($id:%20String!)%20{%20%20%20human(id:%20$id)%20{%20%20%20%20%20id,%20%20%20%20%20name,%20%20%20%20%20appearsIn,%20%20%20%20%20homePlanet%20%20%20}%20}&variables={%20%20%20\"id\":%20%20\"1000\"%20}",
306-
Headers::new(),
307-
&make_handler())
308-
.expect("Unexpected IronError");
309-
310-
assert_eq!(response.status, Some(status::Ok));
311-
assert_eq!(response.headers.get::<headers::ContentType>(),
312-
Some(&headers::ContentType::json()));
313-
314-
let json = unwrap_json_response(response);
315-
316-
assert_eq!(
317-
json,
318-
serde_json::from_str::<Json>(r#"{
319-
"data": {
320-
"human": {
321-
"appearsIn": [
322-
"NEW_HOPE",
323-
"EMPIRE",
324-
"JEDI"
325-
],
326-
"homePlanet": "Tatooine",
327-
"name": "Luke Skywalker",
328-
"id": "1000"
329-
}
330-
}
331-
}"#)
332-
.expect("Invalid JSON constant in test"));
257+
fn context_factory(_: &mut Request) -> Database {
258+
Database::new()
333259
}
334260

335-
336-
#[test]
337-
fn test_simple_post() {
338-
let response = request::post(
339-
"http://localhost:3000/",
340-
Headers::new(),
341-
r#"{"query": "{hero{name}}"}"#,
342-
&make_handler())
343-
.expect("Unexpected IronError");
344-
345-
assert_eq!(response.status, Some(status::Ok));
346-
assert_eq!(response.headers.get::<headers::ContentType>(),
347-
Some(&headers::ContentType::json()));
348-
349-
let json = unwrap_json_response(response);
350-
351-
assert_eq!(
352-
json,
353-
serde_json::from_str::<Json>(r#"{"data": {"hero": {"name": "R2-D2"}}}"#)
354-
.expect("Invalid JSON constant in test"));
261+
fn make_test_response(response: IronResult<Response>) -> http_tests::TestResponse {
262+
let response = response.expect("Error response from GraphQL handler");
263+
let status_code = response.status.expect("No status code returned from handler").to_u16() as i32;
264+
let content_type = String::from_utf8(
265+
response.headers.get_raw("content-type")
266+
.expect("No content type header from handler")[0].clone())
267+
.expect("Content-type header invalid UTF-8");
268+
let body = response::extract_body_to_string(response);
269+
270+
http_tests::TestResponse {
271+
status_code: status_code,
272+
body: Some(body),
273+
content_type: content_type,
274+
}
355275
}
356276

357-
#[test]
358-
fn test_unsupported_method() {
359-
let response = request::options(
360-
"http://localhost:3000/?query={hero{name}}",
361-
Headers::new(),
362-
&make_handler())
363-
.expect("Unexpected IronError");
364-
365-
assert_eq!(response.status, Some(status::MethodNotAllowed));
277+
fn make_handler() -> Box<Handler> {
278+
Box::new(GraphQLHandler::new(
279+
context_factory,
280+
Database::new(),
281+
EmptyMutation::<Database>::new(),
282+
))
366283
}
367284
}

0 commit comments

Comments
 (0)