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, EmptySubscription>; fn bootstrap_rocket() -> Rocket { Rocket::build().manage(Database::new()).manage(Schema::new( Query, EmptyMutation::::new(), EmptySubscription::::new(), )) } fn make_rocket() -> Rocket { #[get("/?")] async fn get_handler( context: &State, request: GraphQLRequest, schema: &State, ) -> GraphQLResponse { request.execute(schema, context).await } #[post("/", data = "")] async fn post_handler( context: &State, request: GraphQLRequest, schema: &State, ) -> GraphQLResponse { request.execute(schema, context).await } bootstrap_rocket().mount("/", routes![post_handler, get_handler]) } fn make_sync_rocket() -> Rocket { #[get("/?")] fn get_handler_sync( context: &State, request: GraphQLRequest, schema: &State, ) -> GraphQLResponse { request.execute_sync(schema, context) } #[post("/", data = "")] fn post_handler_sync( context: &State, request: GraphQLRequest, schema: &State, ) -> 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 = "")] async fn post_graphql_assert_operation_name_handler( context: &State, request: GraphQLRequest, schema: &State, ) -> 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:#?}"); }