From e43afa59f8bfc3d689275747d495f028ff77f5a5 Mon Sep 17 00:00:00 2001 From: Neluxx Date: Fri, 21 Aug 2026 08:09:39 +0200 Subject: [PATCH 01/10] Restrict testDataValidationScalar() to the scalar validation key --- CHANGELOG.md | 2 + src/Traits/DataValidationTestTrait.php | 38 ++++++++++++++++--- .../Traits/DataValidationTestTraitTest.php | 7 +--- 3 files changed, 37 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index deab1ed..f446d6b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,8 +6,10 @@ This project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased](https://github.com/orca-services/cakephp-data-validation-testing) ### Added +- `testDataValidationContains()` to assert that specific validation errors are present, ignoring others on the same field. ### Changed +- `testDataValidationScalar()` now checks only the `scalar` rule by default. ### Fixed diff --git a/src/Traits/DataValidationTestTrait.php b/src/Traits/DataValidationTestTrait.php index 51a51be..d36a695 100644 --- a/src/Traits/DataValidationTestTrait.php +++ b/src/Traits/DataValidationTestTrait.php @@ -328,6 +328,37 @@ protected function testDataValidation( static::assertEquals($expected, $errors); } + /** + * Validate that a field's data validation errors contain the expected rule => message pairs. + * + * @param Table $table The table to test. + * @param string $fieldName The field to check for data validation errors. + * @param array $dataSet The data set to test. + * @param array $expected The expected data validation errors (rule name => message) that must be present. + * @param array $options Additional options for newEntity. + * @return void + * @see \Cake\Validation\Validator::validate() + */ + protected function testDataValidationContains( + Table $table, + string $fieldName, + array $dataSet, + array $expected, + array $options = [], + ): void { + $entity = $table->newEntity($dataSet, $options); + $errors = $entity->getError($fieldName); + + foreach ($expected as $rule => $message) { + static::assertArrayHasKey($rule, $errors, sprintf( + 'Failed asserting that field `%s` has a `%s` validation error.', + $fieldName, + $rule, + )); + static::assertSame($message, $errors[$rule]); + } + } + /** * Validate that a given data set for a given table leads to the expected rule errors * @@ -475,11 +506,8 @@ protected function testDataValidationScalar( ): void { $dataset = [$fieldName => []]; - $expected ??= [ - 'scalar' => 'The provided value must be scalar', - 'maxLength' => 'The provided value must be at most `50` characters long', - ]; - $this->testDataValidation($table, $fieldName, $dataset, $expected, $options); + $expected ??= ['scalar' => 'The provided value must be scalar']; + $this->testDataValidationContains($table, $fieldName, $dataset, $expected, $options); } /** diff --git a/tests/TestCase/Traits/DataValidationTestTraitTest.php b/tests/TestCase/Traits/DataValidationTestTraitTest.php index 444e5b0..e415bef 100644 --- a/tests/TestCase/Traits/DataValidationTestTraitTest.php +++ b/tests/TestCase/Traits/DataValidationTestTraitTest.php @@ -280,12 +280,9 @@ public function testTestDataValidationScalar(): void { // Ensure data validation of the field works as expected first $field = 'scalar_field'; - $expectedErrors = [ - 'scalar' => 'The provided value must be scalar', - 'maxLength' => 'The provided value must be at most `50` characters long', - ]; + $expectedErrors = ['scalar' => 'The provided value must be scalar']; $dataSet = [$field => []]; - $this->testDataValidation($this->table, $field, $dataSet, $expectedErrors); + $this->testDataValidationContains($this->table, $field, $dataSet, $expectedErrors); $this->testDataValidationScalar($this->table, $field); } From 34feb559d71b781647d81ad6f1a0a87069f1b00d Mon Sep 17 00:00:00 2001 From: "marc.wuerth" Date: Fri, 21 Aug 2026 12:46:33 +0200 Subject: [PATCH 02/10] Add value explanation --- src/Traits/DataValidationTestTrait.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Traits/DataValidationTestTrait.php b/src/Traits/DataValidationTestTrait.php index d36a695..00072db 100644 --- a/src/Traits/DataValidationTestTrait.php +++ b/src/Traits/DataValidationTestTrait.php @@ -504,7 +504,7 @@ protected function testDataValidationScalar( ?array $expected = null, ?array $options = [], ): void { - $dataset = [$fieldName => []]; + $dataset = [$fieldName => []]; // A non-scalar value $expected ??= ['scalar' => 'The provided value must be scalar']; $this->testDataValidationContains($table, $fieldName, $dataset, $expected, $options); From 82a4dc560992c1f22d69305f43eba8d82fcd09d3 Mon Sep 17 00:00:00 2001 From: "marc.wuerth" Date: Fri, 21 Aug 2026 12:48:34 +0200 Subject: [PATCH 03/10] Use regular full array check if expected errors are set for scalar check --- src/Traits/DataValidationTestTrait.php | 8 +++++-- .../Traits/DataValidationTestTraitTest.php | 22 +++++++++++++++++++ 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/src/Traits/DataValidationTestTrait.php b/src/Traits/DataValidationTestTrait.php index 00072db..25d1b34 100644 --- a/src/Traits/DataValidationTestTrait.php +++ b/src/Traits/DataValidationTestTrait.php @@ -506,8 +506,12 @@ protected function testDataValidationScalar( ): void { $dataset = [$fieldName => []]; // A non-scalar value - $expected ??= ['scalar' => 'The provided value must be scalar']; - $this->testDataValidationContains($table, $fieldName, $dataset, $expected, $options); + if ($expected) { + $this->testDataValidation($table, $fieldName, $dataset, $expected, $options); + } else { + $expected = ['scalar' => 'The provided value must be scalar']; + $this->testDataValidationContains($table, $fieldName, $dataset, $expected, $options); + } } /** diff --git a/tests/TestCase/Traits/DataValidationTestTraitTest.php b/tests/TestCase/Traits/DataValidationTestTraitTest.php index e415bef..8267822 100644 --- a/tests/TestCase/Traits/DataValidationTestTraitTest.php +++ b/tests/TestCase/Traits/DataValidationTestTraitTest.php @@ -287,6 +287,28 @@ public function testTestDataValidationScalar(): void $this->testDataValidationScalar($this->table, $field); } + /** + * Test that testDataValidationScalar passes when the field is scalar witht the expected errors set + * + * @return void + * @covers ::testDataValidationScalar + */ + public function testTestDataValidationScalarExpectedSet(): void + { + // Ensure data validation of the field works as expected first + $field = 'scalar_field'; + $expectedErrors = ['scalar' => 'The provided value must be scalar']; + $dataSet = [$field => []]; + $this->testDataValidationContains($this->table, $field, $dataSet, $expectedErrors); + + $expected = [ + 'scalar' => 'The provided value must be scalar', + 'maxLength' => 'The provided value must be at most `50` characters long', + ]; + + $this->testDataValidationScalar($this->table, $field, $expected); + } + /** * Test that testDataValidationDecimal passes when the field is decimal. * From f792310031edd16633fc0c904d82e3e29a0ac7a8 Mon Sep 17 00:00:00 2001 From: "marc.wuerth" Date: Fri, 21 Aug 2026 12:56:56 +0200 Subject: [PATCH 04/10] Use testDataValidation method for pre-check Do not do the same check again --- .../TestCase/Traits/DataValidationTestTraitTest.php | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/tests/TestCase/Traits/DataValidationTestTraitTest.php b/tests/TestCase/Traits/DataValidationTestTraitTest.php index 8267822..d40bb41 100644 --- a/tests/TestCase/Traits/DataValidationTestTraitTest.php +++ b/tests/TestCase/Traits/DataValidationTestTraitTest.php @@ -280,9 +280,12 @@ public function testTestDataValidationScalar(): void { // Ensure data validation of the field works as expected first $field = 'scalar_field'; - $expectedErrors = ['scalar' => 'The provided value must be scalar']; + $expectedErrors = [ + 'scalar' => 'The provided value must be scalar', + 'maxLength' => 'The provided value must be at most `50` characters long', // Known undesired behavior + ]; $dataSet = [$field => []]; - $this->testDataValidationContains($this->table, $field, $dataSet, $expectedErrors); + $this->testDataValidation($this->table, $field, $dataSet, $expectedErrors); $this->testDataValidationScalar($this->table, $field); } @@ -295,12 +298,7 @@ public function testTestDataValidationScalar(): void */ public function testTestDataValidationScalarExpectedSet(): void { - // Ensure data validation of the field works as expected first $field = 'scalar_field'; - $expectedErrors = ['scalar' => 'The provided value must be scalar']; - $dataSet = [$field => []]; - $this->testDataValidationContains($this->table, $field, $dataSet, $expectedErrors); - $expected = [ 'scalar' => 'The provided value must be scalar', 'maxLength' => 'The provided value must be at most `50` characters long', From d3642df18e7ecb9aafebb97034669b601b0f218a Mon Sep 17 00:00:00 2001 From: "marc.wuerth" Date: Fri, 21 Aug 2026 12:57:40 +0200 Subject: [PATCH 05/10] Reword test cases --- tests/TestCase/Traits/DataValidationTestTraitTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/TestCase/Traits/DataValidationTestTraitTest.php b/tests/TestCase/Traits/DataValidationTestTraitTest.php index d40bb41..27b1b82 100644 --- a/tests/TestCase/Traits/DataValidationTestTraitTest.php +++ b/tests/TestCase/Traits/DataValidationTestTraitTest.php @@ -271,7 +271,7 @@ public function testTestDataValidationMinLength(): void } /** - * Test that testDataValidationScalar passes when the field is scalar. + * Tests the testDataValidationScalar method * * @return void * @covers ::testDataValidationScalar @@ -291,7 +291,7 @@ public function testTestDataValidationScalar(): void } /** - * Test that testDataValidationScalar passes when the field is scalar witht the expected errors set + * Tests the testDataValidationScalar method when the expected errors are set * * @return void * @covers ::testDataValidationScalar From 933d36336557e537d0eea0d5ba9141de631c183c Mon Sep 17 00:00:00 2001 From: "marc.wuerth" Date: Fri, 21 Aug 2026 13:23:34 +0200 Subject: [PATCH 06/10] Improve method description --- src/Traits/DataValidationTestTrait.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Traits/DataValidationTestTrait.php b/src/Traits/DataValidationTestTrait.php index 25d1b34..10b23a6 100644 --- a/src/Traits/DataValidationTestTrait.php +++ b/src/Traits/DataValidationTestTrait.php @@ -329,12 +329,14 @@ protected function testDataValidation( } /** - * Validate that a field's data validation errors contain the expected rule => message pairs. + * Validate that a field's data validation error array contains the expected "rule name" => "message" pair(s) + * + * Other validation errors will be ignored. * * @param Table $table The table to test. * @param string $fieldName The field to check for data validation errors. * @param array $dataSet The data set to test. - * @param array $expected The expected data validation errors (rule name => message) that must be present. + * @param array $expected The expected data validation errors ("rule name" => "message") that must be present. * @param array $options Additional options for newEntity. * @return void * @see \Cake\Validation\Validator::validate() From 7858387f378369bc99d05eae254e889e1b38afab Mon Sep 17 00:00:00 2001 From: "marc.wuerth" Date: Fri, 21 Aug 2026 13:34:45 +0200 Subject: [PATCH 07/10] Improve assertion messages --- src/Traits/DataValidationTestTrait.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/Traits/DataValidationTestTrait.php b/src/Traits/DataValidationTestTrait.php index 10b23a6..f40b59f 100644 --- a/src/Traits/DataValidationTestTrait.php +++ b/src/Traits/DataValidationTestTrait.php @@ -353,11 +353,15 @@ protected function testDataValidationContains( foreach ($expected as $rule => $message) { static::assertArrayHasKey($rule, $errors, sprintf( - 'Failed asserting that field `%s` has a `%s` validation error.', + 'Field `%s` does not have expected validation error `%s`.', + $fieldName, + $rule, + )); + static::assertSame($message, $errors[$rule], sprintf( + 'Validation error message for field `%s` and rule `%s` does not match expected.', $fieldName, $rule, )); - static::assertSame($message, $errors[$rule]); } } From 53d08d5405d99919e8d819707c05469da1006226 Mon Sep 17 00:00:00 2001 From: Neluxx Date: Mon, 24 Aug 2026 10:45:15 +0200 Subject: [PATCH 08/10] Revert "Reword test cases" This reverts commit d3642df18e7ecb9aafebb97034669b601b0f218a. --- tests/TestCase/Traits/DataValidationTestTraitTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/TestCase/Traits/DataValidationTestTraitTest.php b/tests/TestCase/Traits/DataValidationTestTraitTest.php index 27b1b82..d40bb41 100644 --- a/tests/TestCase/Traits/DataValidationTestTraitTest.php +++ b/tests/TestCase/Traits/DataValidationTestTraitTest.php @@ -271,7 +271,7 @@ public function testTestDataValidationMinLength(): void } /** - * Tests the testDataValidationScalar method + * Test that testDataValidationScalar passes when the field is scalar. * * @return void * @covers ::testDataValidationScalar @@ -291,7 +291,7 @@ public function testTestDataValidationScalar(): void } /** - * Tests the testDataValidationScalar method when the expected errors are set + * Test that testDataValidationScalar passes when the field is scalar witht the expected errors set * * @return void * @covers ::testDataValidationScalar From e8513f5bbb85154af14498cef1bcb55bf4271620 Mon Sep 17 00:00:00 2001 From: Neluxx Date: Mon, 24 Aug 2026 10:45:15 +0200 Subject: [PATCH 09/10] Revert "Use testDataValidation method for pre-check" This reverts commit f792310031edd16633fc0c904d82e3e29a0ac7a8. --- .../TestCase/Traits/DataValidationTestTraitTest.php | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/tests/TestCase/Traits/DataValidationTestTraitTest.php b/tests/TestCase/Traits/DataValidationTestTraitTest.php index d40bb41..8267822 100644 --- a/tests/TestCase/Traits/DataValidationTestTraitTest.php +++ b/tests/TestCase/Traits/DataValidationTestTraitTest.php @@ -280,12 +280,9 @@ public function testTestDataValidationScalar(): void { // Ensure data validation of the field works as expected first $field = 'scalar_field'; - $expectedErrors = [ - 'scalar' => 'The provided value must be scalar', - 'maxLength' => 'The provided value must be at most `50` characters long', // Known undesired behavior - ]; + $expectedErrors = ['scalar' => 'The provided value must be scalar']; $dataSet = [$field => []]; - $this->testDataValidation($this->table, $field, $dataSet, $expectedErrors); + $this->testDataValidationContains($this->table, $field, $dataSet, $expectedErrors); $this->testDataValidationScalar($this->table, $field); } @@ -298,7 +295,12 @@ public function testTestDataValidationScalar(): void */ public function testTestDataValidationScalarExpectedSet(): void { + // Ensure data validation of the field works as expected first $field = 'scalar_field'; + $expectedErrors = ['scalar' => 'The provided value must be scalar']; + $dataSet = [$field => []]; + $this->testDataValidationContains($this->table, $field, $dataSet, $expectedErrors); + $expected = [ 'scalar' => 'The provided value must be scalar', 'maxLength' => 'The provided value must be at most `50` characters long', From f1d7b6ac0e718e591f984fdf53bfd5afc9d3af73 Mon Sep 17 00:00:00 2001 From: Neluxx Date: Mon, 24 Aug 2026 10:45:15 +0200 Subject: [PATCH 10/10] Revert "Use regular full array check if expected errors are set for scalar check" This reverts commit 82a4dc560992c1f22d69305f43eba8d82fcd09d3. --- src/Traits/DataValidationTestTrait.php | 8 ++----- .../Traits/DataValidationTestTraitTest.php | 22 ------------------- 2 files changed, 2 insertions(+), 28 deletions(-) diff --git a/src/Traits/DataValidationTestTrait.php b/src/Traits/DataValidationTestTrait.php index f40b59f..8d991fd 100644 --- a/src/Traits/DataValidationTestTrait.php +++ b/src/Traits/DataValidationTestTrait.php @@ -512,12 +512,8 @@ protected function testDataValidationScalar( ): void { $dataset = [$fieldName => []]; // A non-scalar value - if ($expected) { - $this->testDataValidation($table, $fieldName, $dataset, $expected, $options); - } else { - $expected = ['scalar' => 'The provided value must be scalar']; - $this->testDataValidationContains($table, $fieldName, $dataset, $expected, $options); - } + $expected ??= ['scalar' => 'The provided value must be scalar']; + $this->testDataValidationContains($table, $fieldName, $dataset, $expected, $options); } /** diff --git a/tests/TestCase/Traits/DataValidationTestTraitTest.php b/tests/TestCase/Traits/DataValidationTestTraitTest.php index 8267822..e415bef 100644 --- a/tests/TestCase/Traits/DataValidationTestTraitTest.php +++ b/tests/TestCase/Traits/DataValidationTestTraitTest.php @@ -287,28 +287,6 @@ public function testTestDataValidationScalar(): void $this->testDataValidationScalar($this->table, $field); } - /** - * Test that testDataValidationScalar passes when the field is scalar witht the expected errors set - * - * @return void - * @covers ::testDataValidationScalar - */ - public function testTestDataValidationScalarExpectedSet(): void - { - // Ensure data validation of the field works as expected first - $field = 'scalar_field'; - $expectedErrors = ['scalar' => 'The provided value must be scalar']; - $dataSet = [$field => []]; - $this->testDataValidationContains($this->table, $field, $dataSet, $expectedErrors); - - $expected = [ - 'scalar' => 'The provided value must be scalar', - 'maxLength' => 'The provided value must be at most `50` characters long', - ]; - - $this->testDataValidationScalar($this->table, $field, $expected); - } - /** * Test that testDataValidationDecimal passes when the field is decimal. *