From 7f7edbe159b219e92543168249b6bb77d40954bc Mon Sep 17 00:00:00 2001 From: amit Date: Fri, 19 Apr 2024 18:59:59 +0530 Subject: [PATCH] fix: null handling in the resolvers --- src/blueprint/blueprint.rs | 8 +++++ src/blueprint/into_schema.rs | 14 ++++++--- src/http/response.rs | 9 +++++- tests/execution/test-null-in-array.md | 30 +++++++++++++++++++ tests/execution/test-null-in-object.md | 30 +++++++++++++++++++ ...on_spec__test-null-in-array.md_client.snap | 28 +++++++++++++++++ ...on_spec__test-null-in-array.md_merged.snap | 16 ++++++++++ ...on_spec__test-null-in-array.md_test_0.snap | 15 ++++++++++ ...n_spec__test-null-in-object.md_client.snap | 28 +++++++++++++++++ ...n_spec__test-null-in-object.md_merged.snap | 16 ++++++++++ ...n_spec__test-null-in-object.md_test_0.snap | 18 +++++++++++ 11 files changed, 207 insertions(+), 5 deletions(-) create mode 100644 tests/execution/test-null-in-array.md create mode 100644 tests/execution/test-null-in-object.md create mode 100644 tests/snapshots/execution_spec__test-null-in-array.md_client.snap create mode 100644 tests/snapshots/execution_spec__test-null-in-array.md_merged.snap create mode 100644 tests/snapshots/execution_spec__test-null-in-array.md_test_0.snap create mode 100644 tests/snapshots/execution_spec__test-null-in-object.md_client.snap create mode 100644 tests/snapshots/execution_spec__test-null-in-object.md_merged.snap create mode 100644 tests/snapshots/execution_spec__test-null-in-object.md_test_0.snap diff --git a/src/blueprint/blueprint.rs b/src/blueprint/blueprint.rs index 5cd109d411..676838411c 100644 --- a/src/blueprint/blueprint.rs +++ b/src/blueprint/blueprint.rs @@ -53,6 +53,14 @@ impl Type { Type::ListType { non_null, .. } => *non_null, } } + + /// checks if the type is a list + pub fn is_list(&self) -> bool { + match self { + Type::NamedType { .. } => false, + Type::ListType { .. } => true, + } + } } #[derive(Clone, Debug)] diff --git a/src/blueprint/into_schema.rs b/src/blueprint/into_schema.rs index b35d310129..83f646924b 100644 --- a/src/blueprint/into_schema.rs +++ b/src/blueprint/into_schema.rs @@ -41,6 +41,7 @@ fn to_type(def: &Definition) -> dynamic::Type { let field = field.clone(); let type_ref = to_type_ref(&field.of_type); let field_name = &field.name.clone(); + let is_list = field.of_type.is_list(); let mut dyn_schema_field = dynamic::Field::new( field_name, type_ref.clone(), @@ -70,12 +71,17 @@ fn to_type(def: &Definition) -> dynamic::Type { let const_value = expr.eval(ctx, &Concurrent::Sequential).await?; - let p = match const_value { - ConstValue::List(a) => FieldValue::list(a), - a => FieldValue::from(a), + ConstValue::List(a) => Some(FieldValue::list(a)), + a => { + if a == ConstValue::Null && is_list { + FieldValue::NONE + } else { + FieldValue::try_from(a).ok() + } + }, }; - Ok(Some(p)) + Ok(p) } .instrument(span) .inspect_err(|err| tracing::error!(?err)), diff --git a/src/http/response.rs b/src/http/response.rs index 97e75e20b4..e4dcf41ad8 100644 --- a/src/http/response.rs +++ b/src/http/response.rs @@ -34,7 +34,14 @@ impl Response { } } - pub fn to_json(self) -> Result> { + pub fn to_json(self) -> Result> { + if self.body.is_empty() { + return Ok(Response { + status: self.status, + headers: self.headers, + body: Default::default(), + }); + } let body = serde_json::from_slice::(&self.body)?; Ok(Response { status: self.status, headers: self.headers, body }) } diff --git a/tests/execution/test-null-in-array.md b/tests/execution/test-null-in-array.md new file mode 100644 index 0000000000..1ec038ebe2 --- /dev/null +++ b/tests/execution/test-null-in-array.md @@ -0,0 +1,30 @@ +# Empty Array Response + +```graphql @server +schema @server { + query: Query +} + +type Query { + hi(id: ID!): [Company] @http(baseURL: "http://localhost:3000", path: "/hi") +} +type Company { + name: String + id: ID +} +``` + +```yml @mock +- request: + method: GET + url: http://localhost:3000/hi + response: + status: 200 +``` + +```yml @test +- method: POST + url: http://localhost:8080/graphql + body: + query: "query { hi (id: 1) { name id } }" +``` diff --git a/tests/execution/test-null-in-object.md b/tests/execution/test-null-in-object.md new file mode 100644 index 0000000000..a356b1f3be --- /dev/null +++ b/tests/execution/test-null-in-object.md @@ -0,0 +1,30 @@ +# Empty Object Response + +```graphql @server +schema @server { + query: Query +} + +type Query { + hi(id: ID!): Company @http(baseURL: "http://localhost:3000", path: "/hi") +} +type Company { + name: String + id: ID +} +``` + +```yml @mock +- request: + method: GET + url: http://localhost:3000/hi + response: + status: 200 +``` + +```yml @test +- method: POST + url: http://localhost:8080/graphql + body: + query: "query { hi (id: 1) { name id } }" +``` diff --git a/tests/snapshots/execution_spec__test-null-in-array.md_client.snap b/tests/snapshots/execution_spec__test-null-in-array.md_client.snap new file mode 100644 index 0000000000..285311d5cb --- /dev/null +++ b/tests/snapshots/execution_spec__test-null-in-array.md_client.snap @@ -0,0 +1,28 @@ +--- +source: tests/execution_spec.rs +expression: client +--- +type Company { + id: ID + name: String +} + +scalar Date + +scalar Email + +scalar Empty + +scalar JSON + +scalar PhoneNumber + +type Query { + hi(id: ID!): [Company] +} + +scalar Url + +schema { + query: Query +} diff --git a/tests/snapshots/execution_spec__test-null-in-array.md_merged.snap b/tests/snapshots/execution_spec__test-null-in-array.md_merged.snap new file mode 100644 index 0000000000..36cf068b16 --- /dev/null +++ b/tests/snapshots/execution_spec__test-null-in-array.md_merged.snap @@ -0,0 +1,16 @@ +--- +source: tests/execution_spec.rs +expression: merged +--- +schema @server @upstream { + query: Query +} + +type Company { + id: ID + name: String +} + +type Query { + hi(id: ID!): [Company] @http(baseURL: "http://localhost:3000", path: "/hi") +} diff --git a/tests/snapshots/execution_spec__test-null-in-array.md_test_0.snap b/tests/snapshots/execution_spec__test-null-in-array.md_test_0.snap new file mode 100644 index 0000000000..611acae330 --- /dev/null +++ b/tests/snapshots/execution_spec__test-null-in-array.md_test_0.snap @@ -0,0 +1,15 @@ +--- +source: tests/execution_spec.rs +expression: response +--- +{ + "status": 200, + "headers": { + "content-type": "application/json" + }, + "body": { + "data": { + "hi": null + } + } +} diff --git a/tests/snapshots/execution_spec__test-null-in-object.md_client.snap b/tests/snapshots/execution_spec__test-null-in-object.md_client.snap new file mode 100644 index 0000000000..3cf48f41f5 --- /dev/null +++ b/tests/snapshots/execution_spec__test-null-in-object.md_client.snap @@ -0,0 +1,28 @@ +--- +source: tests/execution_spec.rs +expression: client +--- +type Company { + id: ID + name: String +} + +scalar Date + +scalar Email + +scalar Empty + +scalar JSON + +scalar PhoneNumber + +type Query { + hi(id: ID!): Company +} + +scalar Url + +schema { + query: Query +} diff --git a/tests/snapshots/execution_spec__test-null-in-object.md_merged.snap b/tests/snapshots/execution_spec__test-null-in-object.md_merged.snap new file mode 100644 index 0000000000..877f21dbc2 --- /dev/null +++ b/tests/snapshots/execution_spec__test-null-in-object.md_merged.snap @@ -0,0 +1,16 @@ +--- +source: tests/execution_spec.rs +expression: merged +--- +schema @server @upstream { + query: Query +} + +type Company { + id: ID + name: String +} + +type Query { + hi(id: ID!): Company @http(baseURL: "http://localhost:3000", path: "/hi") +} diff --git a/tests/snapshots/execution_spec__test-null-in-object.md_test_0.snap b/tests/snapshots/execution_spec__test-null-in-object.md_test_0.snap new file mode 100644 index 0000000000..e2041de63e --- /dev/null +++ b/tests/snapshots/execution_spec__test-null-in-object.md_test_0.snap @@ -0,0 +1,18 @@ +--- +source: tests/execution_spec.rs +expression: response +--- +{ + "status": 200, + "headers": { + "content-type": "application/json" + }, + "body": { + "data": { + "hi": { + "name": null, + "id": null + } + } + } +}