156 lines
4.5 KiB
Rust
156 lines
4.5 KiB
Rust
|
use futures::executor;
|
||
|
use juniper::{
|
||
|
http::tests::{run_http_test_suite, HttpIntegration, TestResponse},
|
||
|
tests::fixtures::starwars::schema::{Database, Query},
|
||
|
EmptyMutation, EmptySubscription, RootNode,
|
||
|
};
|
||
|
use juniper_rocket::{GraphQLRequest, GraphQLResponse};
|
||
|
use rocket::{
|
||
|
get,
|
||
|
http::ContentType,
|
||
|
local::asynchronous::{Client, LocalResponse},
|
||
|
post, routes, Build, Rocket, State,
|
||
|
};
|
||
|
|
||
|
type Schema = RootNode<'static, Query, EmptyMutation<Database>, EmptySubscription<Database>>;
|
||
|
|
||
|
fn bootstrap_rocket() -> Rocket<Build> {
|
||
|
Rocket::build().manage(Database::new()).manage(Schema::new(
|
||
|
Query,
|
||
|
EmptyMutation::<Database>::new(),
|
||
|
EmptySubscription::<Database>::new(),
|
||
|
))
|
||
|
}
|
||
|
|
||
|
fn make_rocket() -> Rocket<Build> {
|
||
|
#[get("/?<request..>")]
|
||
|
async fn get_handler(
|
||
|
context: &State<Database>,
|
||
|
request: GraphQLRequest,
|
||
|
schema: &State<Schema>,
|
||
|
) -> GraphQLResponse {
|
||
|
request.execute(schema, context).await
|
||
|
}
|
||
|
|
||
|
#[post("/", data = "<request>")]
|
||
|
async fn post_handler(
|
||
|
context: &State<Database>,
|
||
|
request: GraphQLRequest,
|
||
|
schema: &State<Schema>,
|
||
|
) -> GraphQLResponse {
|
||
|
request.execute(schema, context).await
|
||
|
}
|
||
|
|
||
|
bootstrap_rocket().mount("/", routes![post_handler, get_handler])
|
||
|
}
|
||
|
|
||
|
fn make_sync_rocket() -> Rocket<Build> {
|
||
|
#[get("/?<request..>")]
|
||
|
fn get_handler_sync(
|
||
|
context: &State<Database>,
|
||
|
request: GraphQLRequest,
|
||
|
schema: &State<Schema>,
|
||
|
) -> GraphQLResponse {
|
||
|
request.execute_sync(schema, context)
|
||
|
}
|
||
|
|
||
|
#[post("/", data = "<request>")]
|
||
|
fn post_handler_sync(
|
||
|
context: &State<Database>,
|
||
|
request: GraphQLRequest,
|
||
|
schema: &State<Schema>,
|
||
|
) -> GraphQLResponse {
|
||
|
request.execute_sync(schema, context)
|
||
|
}
|
||
|
|
||
|
bootstrap_rocket().mount("/", routes![post_handler_sync, get_handler_sync])
|
||
|
}
|
||
|
|
||
|
struct TestRocketIntegration {
|
||
|
client: Client,
|
||
|
}
|
||
|
|
||
|
async fn into_test_response(response: LocalResponse<'_>) -> TestResponse {
|
||
|
let status_code = response.status().code as i32;
|
||
|
let content_type = response
|
||
|
.content_type()
|
||
|
.expect("no `Content-Type` header from handler")
|
||
|
.to_string();
|
||
|
let body = response
|
||
|
.into_string()
|
||
|
.await
|
||
|
.expect("no body returned from GraphQL handler");
|
||
|
|
||
|
TestResponse {
|
||
|
status_code,
|
||
|
content_type,
|
||
|
body: Some(body),
|
||
|
}
|
||
|
}
|
||
|
|
||
|
impl HttpIntegration for TestRocketIntegration {
|
||
|
fn get(&self, url: &str) -> TestResponse {
|
||
|
let req = self.client.get(url);
|
||
|
let resp = executor::block_on(req.dispatch());
|
||
|
executor::block_on(into_test_response(resp))
|
||
|
}
|
||
|
|
||
|
fn post_json(&self, url: &str, body: &str) -> TestResponse {
|
||
|
let req = self.client.post(url).header(ContentType::JSON).body(body);
|
||
|
let resp = executor::block_on(req.dispatch());
|
||
|
executor::block_on(into_test_response(resp))
|
||
|
}
|
||
|
|
||
|
fn post_graphql(&self, url: &str, body: &str) -> TestResponse {
|
||
|
let req = self
|
||
|
.client
|
||
|
.post(url)
|
||
|
.header(ContentType::new("application", "graphql"))
|
||
|
.body(body);
|
||
|
let resp = executor::block_on(req.dispatch());
|
||
|
executor::block_on(into_test_response(resp))
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#[rocket::async_test]
|
||
|
async fn test_rocket_integration() {
|
||
|
let rocket = make_rocket();
|
||
|
let client = Client::untracked(rocket).await.expect("valid rocket");
|
||
|
|
||
|
run_http_test_suite(&TestRocketIntegration { client });
|
||
|
}
|
||
|
|
||
|
#[rocket::async_test]
|
||
|
async fn test_sync_rocket_integration() {
|
||
|
let rocket = make_sync_rocket();
|
||
|
let client = Client::untracked(rocket).await.expect("valid rocket");
|
||
|
|
||
|
run_http_test_suite(&TestRocketIntegration { client });
|
||
|
}
|
||
|
|
||
|
#[rocket::async_test]
|
||
|
async fn test_operation_names() {
|
||
|
#[post("/", data = "<request>")]
|
||
|
async fn post_graphql_assert_operation_name_handler(
|
||
|
context: &State<Database>,
|
||
|
request: GraphQLRequest,
|
||
|
schema: &State<Schema>,
|
||
|
) -> GraphQLResponse {
|
||
|
assert_eq!(request.operation_names(), vec![Some("TestQuery")]);
|
||
|
request.execute(schema, context).await
|
||
|
}
|
||
|
|
||
|
let rocket = bootstrap_rocket().mount("/", routes![post_graphql_assert_operation_name_handler]);
|
||
|
let client = Client::untracked(rocket).await.expect("valid rocket");
|
||
|
|
||
|
let resp = client
|
||
|
.post("/")
|
||
|
.header(ContentType::JSON)
|
||
|
.body(r#"{"query": "query TestQuery {hero{name}}", "operationName": "TestQuery"}"#)
|
||
|
.dispatch()
|
||
|
.await;
|
||
|
let resp = into_test_response(resp).await;
|
||
|
|
||
|
assert_eq!(resp.status_code, 200, "response: {resp:#?}");
|
||
|
}
|