diff --git a/CHANGELOG.md b/CHANGELOG.md index 7c23ea4..2a4802b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ This project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased](https://github.com/orca-services/cakephp-data-validation-testing) ### Added +- Add validation trait method for numeric range ### Changed diff --git a/docs/Usage.md b/docs/Usage.md index 3558e43..cb79994 100644 --- a/docs/Usage.md +++ b/docs/Usage.md @@ -80,6 +80,7 @@ Each helper builds an entity, runs the validator, and asserts the expected error - `testDataValidationMaxLength($table, $fieldName, $maxLength)` - `testDataValidationMinLength($table, $fieldName, $minLength, $expected)` - `testDataValidationLengthBetween($table, $fieldName, $minLength, $maxLength)` +- `testDataValidationRange($table, $fieldName, $lowerBound, $upperBound)` ### Generic helpers diff --git a/src/Traits/DataValidationTestTrait.php b/src/Traits/DataValidationTestTrait.php index 8f128c2..3b469ab 100644 --- a/src/Traits/DataValidationTestTrait.php +++ b/src/Traits/DataValidationTestTrait.php @@ -352,16 +352,24 @@ protected function testDataValidationContains( $errors = $entity->getError($fieldName); foreach ($expected as $rule => $message) { - static::assertArrayHasKey($rule, $errors, sprintf( - 'Field `%s` does not have expected validation error `%s`.', - $fieldName, + static::assertArrayHasKey( $rule, - )); - static::assertSame($message, $errors[$rule], sprintf( - 'Validation error message for field `%s` and rule `%s` does not match expected.', - $fieldName, - $rule, - )); + $errors, + sprintf( + '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, + ), + ); } } @@ -792,6 +800,62 @@ protected function testDataValidationLengthBetween( $this->testDataValidation($table, $fieldName, $dataset, $expected, $options); } + /** + * Validate the range data validation of a field for a given table + * + * @param Table $table The table to test. + * @param string $fieldName The field to check the range. + * @param float|int $lowerBound The lower bound to check with. + * @param float|int $upperBound The upper bound to check with. + * @param array|null $expected The expected data validation errors. + * @param ?array $options Additional options for newEntity. + * @return void + * @see \Cake\Validation\Validator::range() + */ + protected function testDataValidationRange( + Table $table, + string $fieldName, + int|float $lowerBound, + int|float $upperBound, + ?array $expected = null, + ?array $options = [], + ): void { + // Too low + $tooLowFloat = $lowerBound - 0.1; + $tooLowInt = $lowerBound - 1; + + // Too high + $tooHighFloat = $upperBound + 0.1; + $tooHighInt = $upperBound + 1; + + $list = [ + $tooLowFloat, + $tooLowInt, + $tooHighFloat, + $tooHighInt, + ]; + + $expected ??= [ + 'range' => sprintf( + 'The provided value must be between `%s` and `%s`, inclusively', + $lowerBound, + $upperBound, + ), + ]; + $this->testDataValidationInList($table, $list, $fieldName, $expected, $options); + + // Valid + $list = [ + (float)$lowerBound, + (int)$lowerBound, + (float)$upperBound, + (int)$upperBound, + ]; + + $expected = []; + $this->testDataValidationInList($table, $list, $fieldName, $expected, $options); + } + /** * Validate that a given field is validated as a natural number (positive integers only) * diff --git a/tests/TestApp/Model/Table/ValidationTestTable.php b/tests/TestApp/Model/Table/ValidationTestTable.php index 49e18dd..4941b6b 100644 --- a/tests/TestApp/Model/Table/ValidationTestTable.php +++ b/tests/TestApp/Model/Table/ValidationTestTable.php @@ -65,7 +65,8 @@ public function validationDefault(Validator $validator): Validator ->allowEmptyString('parent_id') ->integer('parent_id') ->email('email_field') - ->uuid('uuid_field'); + ->uuid('uuid_field') + ->range('range_field', [-30.0, 30.0]); return $validator; } diff --git a/tests/TestCase/Traits/DataValidationTestTraitTest.php b/tests/TestCase/Traits/DataValidationTestTraitTest.php index e415bef..b2fd9c8 100644 --- a/tests/TestCase/Traits/DataValidationTestTraitTest.php +++ b/tests/TestCase/Traits/DataValidationTestTraitTest.php @@ -431,6 +431,29 @@ public function testTestDataValidationLengthBetween(): void $this->testDataValidationLengthBetween($this->table, $field, $minLength, $maxLength); } + /** + * Test that testDataValidationRange passes when the field is between the lower and upper bound. + * + * @return void + * @covers ::testDataValidationRange + */ + public function testTestDataValidationRange(): void + { + // Ensure data validation of the field works as expected first + $lowerBound = -30.0; + $upperBound = 30.0; + $field = 'range_field'; + $expectedErrors = ['range' => 'The provided value must be between `-30` and `30`, inclusively']; + + $dataSet = [$field => $lowerBound - 1]; + $this->testDataValidation($this->table, $field, $dataSet, $expectedErrors); + + $dataSet = [$field => $upperBound + 1]; + $this->testDataValidation($this->table, $field, $dataSet, $expectedErrors); + + $this->testDataValidationRange($this->table, $field, $lowerBound, $upperBound); + } + /** * Test that testDataValidationNaturalNumber passes when the field is a natural number. * diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 8dfa39f..223cea7 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -82,7 +82,8 @@ natural_number_field INTEGER, unique_field VARCHAR(255) UNIQUE, email_field VARCHAR(255), - uuid VARCHAR(36) + uuid VARCHAR(36), + range_field INT ) ');