use apollo_router::_private::create_test_service_factory_from_yaml;
use tower::ServiceExt;
#[tokio::test]
async fn test_supergraph_validation_errors_are_passed_on() {
create_test_service_factory_from_yaml(
include_str!("../../src/testdata/invalid_supergraph.graphql"),
"supergraph:\n introspection: true\n",
)
.await;
}
#[tokio::test]
async fn test_request_extensions_is_null() {
let request =
serde_json::json!({"query": "{__typename}", "extensions": serde_json::Value::Null});
let request = apollo_router::services::router::Request::fake_builder()
.body(request.to_string())
.method(hyper::Method::POST)
.header("content-type", "application/json")
.build()
.unwrap();
let response = apollo_router::TestHarness::builder()
.schema(include_str!("../fixtures/supergraph.graphql"))
.build_router()
.await
.unwrap()
.oneshot(request)
.await
.unwrap()
.next_response()
.await
.unwrap()
.unwrap();
assert_eq!(
String::from_utf8_lossy(&response),
r#"{"data":{"__typename":"Query"}}"#
);
}
#[tokio::test]
async fn test_syntax_error() {
let request = serde_json::json!({"query": "{__typename"});
let request = apollo_router::services::router::Request::fake_builder()
.body(request.to_string())
.method(hyper::Method::POST)
.header("content-type", "application/json")
.build()
.unwrap();
let response = apollo_router::TestHarness::builder()
.schema(include_str!("../fixtures/supergraph.graphql"))
.build_router()
.await
.unwrap()
.oneshot(request)
.await
.unwrap()
.next_response()
.await
.unwrap()
.unwrap();
let v: serde_json::Value = serde_json::from_slice(&response).unwrap();
insta::assert_json_snapshot!(v, @r###"
{
"errors": [
{
"message": "parsing error: syntax error: expected R_CURLY, got EOF",
"locations": [
{
"line": 1,
"column": 12
}
],
"extensions": {
"code": "PARSING_ERROR"
}
}
]
}
"###);
}
#[tokio::test]
async fn test_validation_error() {
let request = serde_json::json!({"query": "{...a} fragment unused on Query { me { id } } fragment a on Query{me {id} topProducts(first: 5.5) {id}}"});
let request = apollo_router::services::router::Request::fake_builder()
.body(request.to_string())
.method(hyper::Method::POST)
.header("content-type", "application/json")
.build()
.unwrap();
let response = apollo_router::TestHarness::builder()
.schema(include_str!("../fixtures/supergraph.graphql"))
.build_router()
.await
.unwrap()
.oneshot(request)
.await
.unwrap()
.next_response()
.await
.unwrap()
.unwrap();
let v: serde_json::Value = serde_json::from_slice(&response).unwrap();
insta::assert_json_snapshot!(v, @r###"
{
"errors": [
{
"message": "Fragment \"unused\" is never used.",
"locations": [
{
"line": 1,
"column": 8
}
],
"extensions": {
"code": "GRAPHQL_VALIDATION_FAILED"
}
},
{
"message": "Field \"topProducts\" of type \"Query\" must have a selection of subfields. Did you mean \"topProducts { ... }\"?",
"locations": [
{
"line": 1,
"column": 75
}
],
"extensions": {
"code": "GRAPHQL_VALIDATION_FAILED"
}
},
{
"message": "Int cannot represent value: 5.5",
"locations": [
{
"line": 1,
"column": 94
}
],
"extensions": {
"code": "GRAPHQL_VALIDATION_FAILED"
}
},
{
"message": "Cannot query field \"id\" on type \"Product\".",
"locations": [
{
"line": 1,
"column": 100
}
],
"extensions": {
"code": "GRAPHQL_VALIDATION_FAILED"
}
}
]
}
"###);
}
#[tokio::test]
async fn test_lots_of_validation_errors() {
let query = format!(
"{{ __typename {} }}",
"@a".repeat(4_000), );
let request = serde_json::json!({ "query": query });
let request = apollo_router::services::router::Request::fake_builder()
.body(request.to_string())
.method(hyper::Method::POST)
.header("content-type", "application/json")
.build()
.unwrap();
let response = apollo_router::TestHarness::builder()
.schema(include_str!("../fixtures/supergraph.graphql"))
.build_router()
.await
.unwrap()
.oneshot(request)
.await
.unwrap()
.next_response()
.await
.unwrap()
.unwrap();
let v: serde_json::Value = serde_json::from_slice(&response).unwrap();
let errors = v["errors"].as_array().unwrap();
assert!(!errors.is_empty(), "should have errors");
assert_eq!(
errors.first().unwrap()["extensions"]["code"],
serde_json::Value::from("GRAPHQL_VALIDATION_FAILED")
);
assert!(errors.len() <= 100, "should return limited error count");
}