diff --git a/src/Type/SchemaValidationContext.php b/src/Type/SchemaValidationContext.php index 4e5cc2745..289c1f0e1 100644 --- a/src/Type/SchemaValidationContext.php +++ b/src/Type/SchemaValidationContext.php @@ -508,25 +508,21 @@ private function validateFields(Type $type): void } // Ensure argument definition directives are valid - if (! isset($arg->astNode, $arg->astNode->directives)) { - continue; + if (isset($arg->astNode, $arg->astNode->directives)) { + $this->validateDirectivesAtLocation( + $arg->astNode->directives, + DirectiveLocation::ARGUMENT_DEFINITION + ); } - - $this->validateDirectivesAtLocation( - $arg->astNode->directives, - DirectiveLocation::ARGUMENT_DEFINITION - ); } // Ensure any directives are valid - if (! isset($field->astNode, $field->astNode->directives)) { - continue; + if (isset($field->astNode, $field->astNode->directives)) { + $this->validateDirectivesAtLocation( + $field->astNode->directives, + DirectiveLocation::FIELD_DEFINITION + ); } - - $this->validateDirectivesAtLocation( - $field->astNode->directives, - DirectiveLocation::FIELD_DEFINITION - ); } } diff --git a/src/Utils/ASTDefinitionBuilder.php b/src/Utils/ASTDefinitionBuilder.php index a4b840ff8..4ba708531 100644 --- a/src/Utils/ASTDefinitionBuilder.php +++ b/src/Utils/ASTDefinitionBuilder.php @@ -163,6 +163,8 @@ function (InputValueDefinitionNode $value): array { 'astNode' => $value, ]; if (isset($value->defaultValue)) { + // Might result in the defaultValue being Utils::undefined() if the type does not match. + // Again, we do not throw immediately but rather defer this check to schema validation. $config['defaultValue'] = AST::valueFromAST($value->defaultValue, $type); } diff --git a/src/Validator/DocumentValidator.php b/src/Validator/DocumentValidator.php index 9c5434b14..f59b89a1e 100644 --- a/src/Validator/DocumentValidator.php +++ b/src/Validator/DocumentValidator.php @@ -193,6 +193,7 @@ public static function securityRules() public static function sdlRules() { if (self::$sdlRules === null) { + // TODO add rule DefaultValuesMatchArgumentType self::$sdlRules = [ LoneSchemaDefinition::class => new LoneSchemaDefinition(), KnownDirectives::class => new KnownDirectives(), diff --git a/tests/Type/ValidationTest.php b/tests/Type/ValidationTest.php index cbf457095..198a7c33c 100644 --- a/tests/Type/ValidationTest.php +++ b/tests/Type/ValidationTest.php @@ -1264,6 +1264,32 @@ public function invalidEnumValueName(): array ]; } + public function testRejectsFieldArgumentsWithIncorrectDefaultType(): void + { + $schema = BuildSchema::build(' + type Query { + foo( + int: Int = "not an int" + string: String = 42 + ): ID + } + '); + + $this->assertMatchesValidationMessage( + $schema->validate(), + [ + [ + 'message' => 'Expected foo.int to have a default value of type Int, got "not an int".', + 'locations' => [['line' => 7, 'column' => 16], ['line' => 11, 'column' => 16]], + ], + [ + 'message' => 'Expected foo.string to have a default value of type String, got 42.', + 'locations' => [['line' => 7, 'column' => 16], ['line' => 11, 'column' => 16]], + ], + ] + ); + } + /** * @see it('rejects an Enum type with incorrectly named values') *