Skip to content

Commit

Permalink
Fix serializing of JSON default values
Browse files Browse the repository at this point in the history
  • Loading branch information
urkle committed Jun 30, 2022
1 parent 175d869 commit ea53d6c
Show file tree
Hide file tree
Showing 2 changed files with 135 additions and 2 deletions.
4 changes: 2 additions & 2 deletions src/types/json.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ impl<T: DeserializeOwned + Serialize + Send + Sync> InputType for Json<T> {
}

fn to_value(&self) -> Value {
to_value(&self.0).unwrap_or_default()
Value::String(serde_json::to_string(&self.0).unwrap_or_default())
}

fn as_raw_value(&self) -> Option<&Self::RawValueType> {
Expand Down Expand Up @@ -120,7 +120,7 @@ impl InputType for serde_json::Value {
}

fn to_value(&self) -> Value {
to_value(&self).unwrap_or_default()
Value::String(self.to_string())
}

fn as_raw_value(&self) -> Option<&Self::RawValueType> {
Expand Down
133 changes: 133 additions & 0 deletions tests/introspection.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use async_graphql::*;
use chrono::{NaiveDateTime, NaiveDate};
use futures_util::stream::{self, Stream};

#[derive(Clone, Debug)]
Expand Down Expand Up @@ -1378,3 +1379,135 @@ pub async fn test_introspection_only() {
let res = schema.execute(query).await.into_result().unwrap().data;
assert_eq!(res, res_json);
}

#[tokio::test]
pub async fn test_introspection_default() {
#[derive(serde::Serialize, serde::Deserialize, Default)]
pub struct MyStruct {
a: i32,
b: i32,
}

#[derive(InputObject)]
pub struct DefaultInput {
#[graphql(default)]
pub str: String,
#[graphql(default_with = "NaiveDate::from_ymd(2016, 7, 8).and_hms(9, 10, 11)")]
pub date: NaiveDateTime,
// a required json with no default
pub json: serde_json::Value,
// basic default (JSON null)
#[graphql(default)]
pub json_def: serde_json::Value,
// complex default (JSON object)
#[graphql(default_with = "serde_json::Value::Object(Default::default())")]
pub json_def_obj: serde_json::Value,
#[graphql(default)]
pub json_def_struct: Json<MyStruct>,
}

struct LocalMutation;

#[Object]
#[allow(unreachable_code)]
impl LocalMutation {
async fn simple_mutation(&self, _input: DefaultInput) -> SimpleObject {
unimplemented!()
}
}

let schema = Schema::build(Query, LocalMutation, EmptySubscription)
.introspection_only()
.finish();

// Test whether introspection works.
let query = r#"
{
__type(name: "DefaultInput") {
name
kind
inputFields {
name
defaultValue
type { kind ofType { kind name } }
}
}
}
"#;
let res_json = value!({
"__type": {
"name": "DefaultInput",
"kind": "INPUT_OBJECT",
"inputFields": [
{
"name": "str",
"defaultValue": "\"\"",
"type": {
"kind": "NON_NULL",
"ofType": {
"kind": "SCALAR",
"name": "String"
},
},
},
{
"name": "date",
"defaultValue": "\"2016-07-08T09:10:11\"",
"type": {
"kind": "NON_NULL",
"ofType": {
"kind": "SCALAR",
"name": "NaiveDateTime"
},
},
},
{
"name": "json",
"defaultValue": null,
"type": {
"kind": "NON_NULL",
"ofType": {
"kind": "SCALAR",
"name": "JSON"
},
},
},
{
"name": "jsonDef",
"defaultValue": "\"null\"",
"type": {
"kind": "NON_NULL",
"ofType": {
"kind": "SCALAR",
"name": "JSON"
},
},
},
{
"name": "jsonDefObj",
"defaultValue": "\"{}\"",
"type": {
"kind": "NON_NULL",
"ofType": {
"kind": "SCALAR",
"name": "JSON"
},
},
},
{
"name": "jsonDefStruct",
"defaultValue": "\"{\\\"a\\\":0,\\\"b\\\":0}\"",
"type": {
"kind": "NON_NULL",
"ofType": {
"kind": "SCALAR",
"name": "JSON"
},
},
},
]
}
});
let res = schema.execute(query).await.into_result().unwrap().data;
assert_eq!(res, res_json);
}

0 comments on commit ea53d6c

Please sign in to comment.