From a2fc50270250352e56fd850beed6f3011d67d899 Mon Sep 17 00:00:00 2001 From: Oleg Babin Date: Sun, 11 Jul 2021 13:55:58 +0300 Subject: [PATCH] throw if it's impossible to coerce boolean value Graphql spec states: > Input Coercion When expected as an input type, only boolean input values are accepted. All other input values must raise a request error indicating an incorrect type. (https://spec.graphql.org/draft/#sec-Boolean) So we can't coerce string, numeric and enum values. And here we faced main issue - because graphql parser considered "False" and "True" as enum values (correct boolean values is "true" and "false"). And if user passed "False" value to boolean argument it silently converted to true. This patch check that passed node type is boolean and raises if it's not so. Closes #14 --- graphql/types.lua | 3 +++ test/unit/graphql_test.lua | 29 +++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/graphql/types.lua b/graphql/types.lua index 0700ecd..a9299ad 100644 --- a/graphql/types.lua +++ b/graphql/types.lua @@ -382,6 +382,9 @@ types.boolean = types.scalar({ description = "The `Boolean` scalar type represents `true` or `false`.", serialize = coerceBoolean, parseLiteral = function(node) + if node.kind ~= 'boolean' then + error(('Could not coerce value "%s" with type "%s" to type boolean'):format(node.value, node.kind)) + end return coerceBoolean(node.value) end, isValueOfTheType = isBoolean, diff --git a/test/unit/graphql_test.lua b/test/unit/graphql_test.lua index ebcf960..1e10a9a 100644 --- a/test/unit/graphql_test.lua +++ b/test/unit/graphql_test.lua @@ -1028,3 +1028,32 @@ function g.test_types_for_different_schemas() t.assert_error_msg_contains('Field "string_2" is not defined on type "Object"', validate, schema_1, parse([[query { object_list { long_1 string_2 } }]])) end + +function g.test_boolean_coerce() + local query = types.object({ + name = 'Query', + fields = { + test_boolean = { + kind = types.boolean.nonNull, + arguments = { + value = types.boolean, + non_null_value = types.boolean.nonNull, + } + }, + } + }) + + local test_schema = schema.create({query = query}) + + validate(test_schema, parse([[ { test_boolean(value: true, non_null_value: true) } ]])) + validate(test_schema, parse([[ { test_boolean(value: false, non_null_value: false) } ]])) + validate(test_schema, parse([[ { test_boolean(value: null, non_null_value: true) } ]])) + + -- Errors + t.assert_error_msg_contains('Could not coerce value "True" with type "enum" to type boolean', + validate, test_schema, parse([[ { test_boolean(value: True) } ]])) + t.assert_error_msg_contains('Could not coerce value "123" with type "int" to type boolean', + validate, test_schema, parse([[ { test_boolean(value: 123) } ]])) + t.assert_error_msg_contains('Could not coerce value "value" with type "string" to type boolean', + validate, test_schema, parse([[ { test_boolean(value: "value") } ]])) +end