Allow vars to be missing when def is nullable

Allow variables to be missing when the associated variable definition is
nullable (in which case we use `null` as the default).

This fixes queries like

```graphql
query Test($var: Int) {
    test(var: $var)
}
```

```json
{}
```

which appear to be allowed according to the GraphQL spec.
This commit is contained in:
Bryan Burgers 2020-06-11 10:00:47 -05:00
parent 385bd16d24
commit e21f2e6316
2 changed files with 73 additions and 0 deletions

View File

@ -424,6 +424,16 @@ impl<'a, T> ContextBase<'a, T> {
} else if let Some(default) = &def.default_value {
return Ok(default.clone_inner());
}
match def.var_type.deref() {
&async_graphql_parser::query::Type::Named(_)
| &async_graphql_parser::query::Type::List(_) => {
// Nullable types can default to null when not given.
return Ok(Value::Null);
}
&async_graphql_parser::query::Type::NonNull(_) => {
// Strict types can not.
}
}
}
Err(QueryError::VarNotDefined {
var_name: name.to_string(),

View File

@ -71,6 +71,69 @@ pub async fn test_variable_default_value() {
);
}
#[async_std::test]
pub async fn test_variable_no_value() {
struct QueryRoot;
#[Object]
impl QueryRoot {
pub async fn int_val(&self, value: Option<i32>) -> i32 {
value.unwrap_or(10)
}
}
let schema = Schema::new(QueryRoot, EmptyMutation, EmptySubscription);
let query = QueryBuilder::new(
r#"
query QueryWithVariables($intVal: Int) {
intVal(value: $intVal)
}
"#,
)
.variables(Variables::parse_from_json(serde_json::json!({})).unwrap());
let resp = query.execute(&schema).await.unwrap();
assert_eq!(
resp.data,
serde_json::json!({
"intVal": 10,
})
);
}
#[async_std::test]
pub async fn test_variable_null() {
struct QueryRoot;
#[Object]
impl QueryRoot {
pub async fn int_val(&self, value: Option<i32>) -> i32 {
value.unwrap_or(10)
}
}
let schema = Schema::new(QueryRoot, EmptyMutation, EmptySubscription);
let query = QueryBuilder::new(
r#"
query QueryWithVariables($intVal: Int) {
intVal(value: $intVal)
}
"#,
)
.variables(
Variables::parse_from_json(serde_json::json!({
"intVal": null,
}))
.unwrap(),
);
let resp = query.execute(&schema).await.unwrap();
assert_eq!(
resp.data,
serde_json::json!({
"intVal": 10,
})
);
}
#[async_std::test]
pub async fn test_variable_in_input_object() {
#[InputObject]