From be4325a3dd9becdf9b8fca316776a33e8ed2c2d0 Mon Sep 17 00:00:00 2001 From: Joe Saunderson Date: Wed, 1 May 2024 14:18:15 +0100 Subject: [PATCH 1/5] Update InputValidator.php --- src/Validator/InputValidator.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/Validator/InputValidator.php b/src/Validator/InputValidator.php index 013fd45bc..05bc4740a 100644 --- a/src/Validator/InputValidator.php +++ b/src/Validator/InputValidator.php @@ -138,6 +138,12 @@ private function buildValidationTree(ValidationNode $rootObject, iterable $field foreach ($fields as $name => $arg) { $property = $arg['name'] ?? $name; + + if (!array_key_exists($property, $inputData)) { + // This field was not provided in the inputData. Do not attempt to validate it. + continue; + } + $config = static::normalizeConfig($arg['validation'] ?? []); if (isset($config['cascade']) && isset($inputData[$property])) { From 12d612bc31bb22ff31bf807604b15b1edbc3cbba Mon Sep 17 00:00:00 2001 From: Joe Saunderson Date: Wed, 1 May 2024 14:26:42 +0100 Subject: [PATCH 2/5] Update InputValidator.php --- src/Validator/InputValidator.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Validator/InputValidator.php b/src/Validator/InputValidator.php index 05bc4740a..a2cd4faac 100644 --- a/src/Validator/InputValidator.php +++ b/src/Validator/InputValidator.php @@ -182,6 +182,7 @@ private function buildValidationTree(ValidationNode $rootObject, iterable $field $this->cachedMetadata[$fqcn] = $this->defaultValidator->getMetadataFor($fqcn); } + // Get metadata from the property and it's getters $propertyMetadata = $this->cachedMetadata[$fqcn]->getPropertyMetadata($classProperty); From e6862724b2c3d513e6fe1b40514a7ed0698d9ebe Mon Sep 17 00:00:00 2001 From: Joe Saunderson Date: Wed, 1 May 2024 14:27:04 +0100 Subject: [PATCH 3/5] Update InputValidator.php --- src/Validator/InputValidator.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Validator/InputValidator.php b/src/Validator/InputValidator.php index a2cd4faac..2be294cb3 100644 --- a/src/Validator/InputValidator.php +++ b/src/Validator/InputValidator.php @@ -144,6 +144,7 @@ private function buildValidationTree(ValidationNode $rootObject, iterable $field continue; } + $config = static::normalizeConfig($arg['validation'] ?? []); if (isset($config['cascade']) && isset($inputData[$property])) { @@ -182,7 +183,6 @@ private function buildValidationTree(ValidationNode $rootObject, iterable $field $this->cachedMetadata[$fqcn] = $this->defaultValidator->getMetadataFor($fqcn); } - // Get metadata from the property and it's getters $propertyMetadata = $this->cachedMetadata[$fqcn]->getPropertyMetadata($classProperty); From e6d2f8c0627329e0ee682eab999de59b8c221f07 Mon Sep 17 00:00:00 2001 From: Joe Saunderson Date: Wed, 1 May 2024 14:29:53 +0100 Subject: [PATCH 4/5] Update InputValidator.php --- src/Validator/InputValidator.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/Validator/InputValidator.php b/src/Validator/InputValidator.php index 2be294cb3..18846c393 100644 --- a/src/Validator/InputValidator.php +++ b/src/Validator/InputValidator.php @@ -138,14 +138,12 @@ private function buildValidationTree(ValidationNode $rootObject, iterable $field foreach ($fields as $name => $arg) { $property = $arg['name'] ?? $name; + $config = static::normalizeConfig($arg['validation'] ?? []); if (!array_key_exists($property, $inputData)) { // This field was not provided in the inputData. Do not attempt to validate it. continue; } - - - $config = static::normalizeConfig($arg['validation'] ?? []); if (isset($config['cascade']) && isset($inputData[$property])) { $groups = $config['cascade']; From c20063eecc6b1bbaa3f83db080533ac2a078025c Mon Sep 17 00:00:00 2001 From: Joe Saunderson Date: Fri, 10 May 2024 13:06:59 +0100 Subject: [PATCH 5/5] Add a test to assert that only the passed fields from an input object are validated --- .../config/validator/mapping/Mutation.types.yml | 8 ++++++++ .../config/validator/mapping/Person.types.yml | 14 ++++++++++++++ .../Functional/Validator/InputValidatorTest.php | 16 ++++++++++++++++ 3 files changed, 38 insertions(+) create mode 100644 tests/Functional/App/config/validator/mapping/Person.types.yml diff --git a/tests/Functional/App/config/validator/mapping/Mutation.types.yml b/tests/Functional/App/config/validator/mapping/Mutation.types.yml index ede5d948b..e320f09ac 100644 --- a/tests/Functional/App/config/validator/mapping/Mutation.types.yml +++ b/tests/Functional/App/config/validator/mapping/Mutation.types.yml @@ -138,3 +138,11 @@ Mutation: validation: cascade: groups: ['group2'] + + onlyPassedFieldsValidation: + type: Boolean + resolve: '@=m("mutation_mock", args)' + args: + person: + validation: cascade + type: Person! diff --git a/tests/Functional/App/config/validator/mapping/Person.types.yml b/tests/Functional/App/config/validator/mapping/Person.types.yml new file mode 100644 index 000000000..bb8e29642 --- /dev/null +++ b/tests/Functional/App/config/validator/mapping/Person.types.yml @@ -0,0 +1,14 @@ +Person: + type: input-object + config: + fields: + firstName: + type: String + validation: + - NotBlank: ~ + - NotNull: ~ + surname: + type: String + validation: + - NotBlank: ~ + - NotNull: ~ diff --git a/tests/Functional/Validator/InputValidatorTest.php b/tests/Functional/Validator/InputValidatorTest.php index 4bd76823c..f454ab057 100644 --- a/tests/Functional/Validator/InputValidatorTest.php +++ b/tests/Functional/Validator/InputValidatorTest.php @@ -87,6 +87,22 @@ public function testLinkedConstraintsValidationPasses(): void $this->assertTrue($result['data']['linkedConstraintsValidation']); } + public function testOnlyPassedFieldsValidated(): void + { + $query = ' + mutation { + onlyPassedFieldsValidation( + person: { firstName: "Joe" } + ) + } + '; + + $result = $this->executeGraphQLRequest($query); + + $this->assertTrue(empty($result['errors'])); + $this->assertTrue($result['data']['onlyPassedFieldsValidation']); + } + public function testLinkedConstraintsValidationFails(): void { $query = '