From 8394e3a66e3248f66a8a4a071b145b1a34ff2894 Mon Sep 17 00:00:00 2001 From: Leo Date: Sat, 4 Apr 2020 14:29:19 +0800 Subject: [PATCH 1/3] Throw exception if variable is undeclared --- src/Execution/Request.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/Execution/Request.php b/src/Execution/Request.php index 5b3da1a0..88b7be72 100644 --- a/src/Execution/Request.php +++ b/src/Execution/Request.php @@ -66,6 +66,13 @@ public function __construct($data = [], $variables = []) if (!array_key_exists($ref->getName(), $variables)) { /** @var Variable $variable */ $variable = $ref->getVariable(); + /** + * If $variable is null, then it was not declared in the operation arguments + * @see https://graphql.org/learn/queries/#variables + */ + if (is_null($variable)) { + throw new InvalidRequestException(sprintf("Variable %s hasn't been declared", $ref->getName()), $ref->getLocation()); + } if ($variable->hasDefaultValue()) { $variables[$variable->getName()] = $variable->getDefaultValue()->getValue(); continue; From 4e9c094228c3253a970b098dc3206c9a75f9df1c Mon Sep 17 00:00:00 2001 From: Leo Date: Sun, 12 Apr 2020 15:46:05 +0800 Subject: [PATCH 2/3] Added test --- tests/Issues/Issue238/Issue238Test.php | 57 ++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 tests/Issues/Issue238/Issue238Test.php diff --git a/tests/Issues/Issue238/Issue238Test.php b/tests/Issues/Issue238/Issue238Test.php new file mode 100644 index 00000000..3cd96179 --- /dev/null +++ b/tests/Issues/Issue238/Issue238Test.php @@ -0,0 +1,57 @@ + new ObjectType([ + 'name' => 'RootQuery', + 'fields' => [ + 'currentUser' => [ + 'type' => new StringType(), + 'args' => [ + 'age' => [ + 'type' => new IntType(), + 'defaultValue' => 20, + ], + ], + 'resolve' => static function ($source, $args, ResolveInfo $info) { + return 'Alex age ' . $args['age']; + }, + ], + ], + ]), + ]); + + $processor = new Processor($schema); + + /** + * If using a variable in a query, it must be defined in the operation + * $properQuery = 'query GetUserAge($age:Int) { currentUser(age:$age) }'; + * When not declaring the variable in the operation, it must return a nice error message + * (instead of throwing a RuntimeException) + */ + $unproperQuery = '{ currentUser(age:$age) }'; + $response = $processor->processPayload($unproperQuery)->getResponseData(); + if ($this->assertArrayHasKey( + 'errors', + $response + )) { + $this->assertArraySubset( + ['message' => 'Variable age hasn\'t been declared'], + $response['errors'] + ); + } + } +} From 070b53705940d3005dd2626b4ac4970bd7ddf473 Mon Sep 17 00:00:00 2001 From: Leo Date: Sun, 12 Apr 2020 16:34:25 +0800 Subject: [PATCH 3/3] Fixed namespace --- tests/Issues/Issue238/Issue238Test.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Issues/Issue238/Issue238Test.php b/tests/Issues/Issue238/Issue238Test.php index 3cd96179..934d1e37 100644 --- a/tests/Issues/Issue238/Issue238Test.php +++ b/tests/Issues/Issue238/Issue238Test.php @@ -1,6 +1,6 @@