Factor out HTTP integration tests to http module
This commit is contained in:
parent
5f69b1d45e
commit
565f14ceef
2 changed files with 163 additions and 129 deletions
117
src/http.rs
117
src/http.rs
|
@ -90,3 +90,120 @@ impl<'a> ser::Serialize for GraphQLResponse<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
pub mod tests {
|
||||||
|
use serde_json::Value as Json;
|
||||||
|
use serde_json;
|
||||||
|
|
||||||
|
pub struct TestResponse {
|
||||||
|
pub status_code: i32,
|
||||||
|
pub body: Option<String>,
|
||||||
|
pub content_type: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait HTTPIntegration {
|
||||||
|
fn get(&self, url: &str) -> TestResponse;
|
||||||
|
fn post(&self, url: &str, body: &str) -> TestResponse;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn run_http_test_suite<T: HTTPIntegration>(integration: &T) {
|
||||||
|
println!("Running HTTP Test suite for integration");
|
||||||
|
|
||||||
|
println!(" - test_simple_get");
|
||||||
|
test_simple_get(integration);
|
||||||
|
|
||||||
|
println!(" - test_encoded_get");
|
||||||
|
test_encoded_get(integration);
|
||||||
|
|
||||||
|
println!(" - test_get_with_variables");
|
||||||
|
test_get_with_variables(integration);
|
||||||
|
|
||||||
|
println!(" - test_simple_post");
|
||||||
|
test_simple_post(integration);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn unwrap_json_response(response: &TestResponse) -> Json {
|
||||||
|
serde_json::from_str::<Json>(
|
||||||
|
response.body.as_ref().expect("No data returned from request")
|
||||||
|
).expect("Could not parse JSON object")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_simple_get<T: HTTPIntegration>(integration: &T) {
|
||||||
|
let response = integration.get("/?query={hero{name}}");
|
||||||
|
|
||||||
|
assert_eq!(response.status_code, 200);
|
||||||
|
assert_eq!(response.content_type.as_str(), "application/json");
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
unwrap_json_response(&response),
|
||||||
|
serde_json::from_str::<Json>(r#"{"data": {"hero": {"name": "R2-D2"}}}"#)
|
||||||
|
.expect("Invalid JSON constant in test"));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_encoded_get<T: HTTPIntegration>(integration: &T) {
|
||||||
|
let response = integration.get(
|
||||||
|
"/?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}");
|
||||||
|
|
||||||
|
assert_eq!(response.status_code, 200);
|
||||||
|
assert_eq!(response.content_type.as_str(), "application/json");
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
unwrap_json_response(&response),
|
||||||
|
serde_json::from_str::<Json>(r#"{
|
||||||
|
"data": {
|
||||||
|
"human": {
|
||||||
|
"appearsIn": [
|
||||||
|
"NEW_HOPE",
|
||||||
|
"EMPIRE",
|
||||||
|
"JEDI"
|
||||||
|
],
|
||||||
|
"homePlanet": "Tatooine",
|
||||||
|
"name": "Luke Skywalker",
|
||||||
|
"id": "1000"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}"#)
|
||||||
|
.expect("Invalid JSON constant in test"));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_get_with_variables<T: HTTPIntegration>(integration: &T) {
|
||||||
|
let response = integration.get(
|
||||||
|
"/?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}");
|
||||||
|
|
||||||
|
assert_eq!(response.status_code, 200);
|
||||||
|
assert_eq!(response.content_type, "application/json");
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
unwrap_json_response(&response),
|
||||||
|
serde_json::from_str::<Json>(r#"{
|
||||||
|
"data": {
|
||||||
|
"human": {
|
||||||
|
"appearsIn": [
|
||||||
|
"NEW_HOPE",
|
||||||
|
"EMPIRE",
|
||||||
|
"JEDI"
|
||||||
|
],
|
||||||
|
"homePlanet": "Tatooine",
|
||||||
|
"name": "Luke Skywalker",
|
||||||
|
"id": "1000"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}"#)
|
||||||
|
.expect("Invalid JSON constant in test"));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_simple_post<T: HTTPIntegration>(integration: &T) {
|
||||||
|
let response = integration.post(
|
||||||
|
"/",
|
||||||
|
r#"{"query": "{hero{name}}"}"#);
|
||||||
|
|
||||||
|
assert_eq!(response.status_code, 200);
|
||||||
|
assert_eq!(response.content_type, "application/json");
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
unwrap_json_response(&response),
|
||||||
|
serde_json::from_str::<Json>(r#"{"data": {"hero": {"name": "R2-D2"}}}"#)
|
||||||
|
.expect("Invalid JSON constant in test"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -215,23 +215,65 @@ impl From<GraphQLIronError> for IronError {
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use serde_json::Value as Json;
|
|
||||||
use serde_json;
|
|
||||||
use iron::prelude::*;
|
use iron::prelude::*;
|
||||||
use iron::status;
|
|
||||||
use iron::headers;
|
|
||||||
use iron_test::{request, response};
|
use iron_test::{request, response};
|
||||||
use iron::{Handler, Headers};
|
use iron::{Handler, Headers};
|
||||||
|
|
||||||
use ::tests::model::Database;
|
use ::tests::model::Database;
|
||||||
|
use ::http::tests as http_tests;
|
||||||
use types::scalars::EmptyMutation;
|
use types::scalars::EmptyMutation;
|
||||||
|
|
||||||
use super::GraphQLHandler;
|
use super::GraphQLHandler;
|
||||||
|
|
||||||
|
struct TestIronIntegration;
|
||||||
|
|
||||||
|
impl http_tests::HTTPIntegration for TestIronIntegration
|
||||||
|
{
|
||||||
|
fn get(&self, url: &str) -> http_tests::TestResponse {
|
||||||
|
make_test_response(request::get(
|
||||||
|
&("http://localhost:3000".to_owned() + url),
|
||||||
|
Headers::new(),
|
||||||
|
&make_handler(),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn post(&self, url: &str, body: &str) -> http_tests::TestResponse {
|
||||||
|
make_test_response(request::post(
|
||||||
|
&("http://localhost:3000".to_owned() + url),
|
||||||
|
Headers::new(),
|
||||||
|
body,
|
||||||
|
&make_handler(),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_iron_integration() {
|
||||||
|
let integration = TestIronIntegration;
|
||||||
|
|
||||||
|
http_tests::run_http_test_suite(&integration);
|
||||||
|
}
|
||||||
|
|
||||||
fn context_factory(_: &mut Request) -> Database {
|
fn context_factory(_: &mut Request) -> Database {
|
||||||
Database::new()
|
Database::new()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn make_test_response(response: IronResult<Response>) -> http_tests::TestResponse {
|
||||||
|
let response = response.expect("Error response from GraphQL handler");
|
||||||
|
let status_code = response.status.expect("No status code returned from handler").to_u16() as i32;
|
||||||
|
let content_type = String::from_utf8(
|
||||||
|
response.headers.get_raw("content-type")
|
||||||
|
.expect("No content type header from handler")[0].clone())
|
||||||
|
.expect("Content-type header invalid UTF-8");
|
||||||
|
let body = response::extract_body_to_string(response);
|
||||||
|
|
||||||
|
http_tests::TestResponse {
|
||||||
|
status_code: status_code,
|
||||||
|
body: Some(body),
|
||||||
|
content_type: content_type,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn make_handler() -> Box<Handler> {
|
fn make_handler() -> Box<Handler> {
|
||||||
Box::new(GraphQLHandler::new(
|
Box::new(GraphQLHandler::new(
|
||||||
context_factory,
|
context_factory,
|
||||||
|
@ -239,129 +281,4 @@ mod tests {
|
||||||
EmptyMutation::<Database>::new(),
|
EmptyMutation::<Database>::new(),
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn unwrap_json_response(resp: Response) -> Json {
|
|
||||||
let result = response::extract_body_to_string(resp);
|
|
||||||
|
|
||||||
serde_json::from_str::<Json>(&result).expect("Could not parse JSON object")
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_simple_get() {
|
|
||||||
let response = request::get(
|
|
||||||
"http://localhost:3000/?query={hero{name}}",
|
|
||||||
Headers::new(),
|
|
||||||
&make_handler())
|
|
||||||
.expect("Unexpected IronError");
|
|
||||||
|
|
||||||
assert_eq!(response.status, Some(status::Ok));
|
|
||||||
assert_eq!(response.headers.get::<headers::ContentType>(),
|
|
||||||
Some(&headers::ContentType::json()));
|
|
||||||
|
|
||||||
let json = unwrap_json_response(response);
|
|
||||||
|
|
||||||
assert_eq!(
|
|
||||||
json,
|
|
||||||
serde_json::from_str::<Json>(r#"{"data": {"hero": {"name": "R2-D2"}}}"#)
|
|
||||||
.expect("Invalid JSON constant in test"));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_encoded_get() {
|
|
||||||
let response = request::get(
|
|
||||||
"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}",
|
|
||||||
Headers::new(),
|
|
||||||
&make_handler())
|
|
||||||
.expect("Unexpected IronError");
|
|
||||||
|
|
||||||
assert_eq!(response.status, Some(status::Ok));
|
|
||||||
assert_eq!(response.headers.get::<headers::ContentType>(),
|
|
||||||
Some(&headers::ContentType::json()));
|
|
||||||
|
|
||||||
let json = unwrap_json_response(response);
|
|
||||||
|
|
||||||
assert_eq!(
|
|
||||||
json,
|
|
||||||
serde_json::from_str::<Json>(r#"{
|
|
||||||
"data": {
|
|
||||||
"human": {
|
|
||||||
"appearsIn": [
|
|
||||||
"NEW_HOPE",
|
|
||||||
"EMPIRE",
|
|
||||||
"JEDI"
|
|
||||||
],
|
|
||||||
"homePlanet": "Tatooine",
|
|
||||||
"name": "Luke Skywalker",
|
|
||||||
"id": "1000"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}"#)
|
|
||||||
.expect("Invalid JSON constant in test"));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_get_with_variables() {
|
|
||||||
let response = request::get(
|
|
||||||
"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}",
|
|
||||||
Headers::new(),
|
|
||||||
&make_handler())
|
|
||||||
.expect("Unexpected IronError");
|
|
||||||
|
|
||||||
assert_eq!(response.status, Some(status::Ok));
|
|
||||||
assert_eq!(response.headers.get::<headers::ContentType>(),
|
|
||||||
Some(&headers::ContentType::json()));
|
|
||||||
|
|
||||||
let json = unwrap_json_response(response);
|
|
||||||
|
|
||||||
assert_eq!(
|
|
||||||
json,
|
|
||||||
serde_json::from_str::<Json>(r#"{
|
|
||||||
"data": {
|
|
||||||
"human": {
|
|
||||||
"appearsIn": [
|
|
||||||
"NEW_HOPE",
|
|
||||||
"EMPIRE",
|
|
||||||
"JEDI"
|
|
||||||
],
|
|
||||||
"homePlanet": "Tatooine",
|
|
||||||
"name": "Luke Skywalker",
|
|
||||||
"id": "1000"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}"#)
|
|
||||||
.expect("Invalid JSON constant in test"));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_simple_post() {
|
|
||||||
let response = request::post(
|
|
||||||
"http://localhost:3000/",
|
|
||||||
Headers::new(),
|
|
||||||
r#"{"query": "{hero{name}}"}"#,
|
|
||||||
&make_handler())
|
|
||||||
.expect("Unexpected IronError");
|
|
||||||
|
|
||||||
assert_eq!(response.status, Some(status::Ok));
|
|
||||||
assert_eq!(response.headers.get::<headers::ContentType>(),
|
|
||||||
Some(&headers::ContentType::json()));
|
|
||||||
|
|
||||||
let json = unwrap_json_response(response);
|
|
||||||
|
|
||||||
assert_eq!(
|
|
||||||
json,
|
|
||||||
serde_json::from_str::<Json>(r#"{"data": {"hero": {"name": "R2-D2"}}}"#)
|
|
||||||
.expect("Invalid JSON constant in test"));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_unsupported_method() {
|
|
||||||
let response = request::options(
|
|
||||||
"http://localhost:3000/?query={hero{name}}",
|
|
||||||
Headers::new(),
|
|
||||||
&make_handler())
|
|
||||||
.expect("Unexpected IronError");
|
|
||||||
|
|
||||||
assert_eq!(response.status, Some(status::MethodNotAllowed));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue