From d8a0931bfba4ca17418caae5173e0d1796e2b41c Mon Sep 17 00:00:00 2001 From: Mohd Hafizuddin M Marzuki Date: Mon, 27 Nov 2023 22:44:10 +0800 Subject: [PATCH] [10.x] Reset numeric rules after each attribute's validation (#49142) * Reset numeric rules after each attribute's validation * formatting --------- Co-authored-by: Taylor Otwell --- src/Illuminate/Validation/Validator.php | 9 + tests/Validation/ValidationValidatorTest.php | 182 ++++++++++++++++++- 2 files changed, 183 insertions(+), 8 deletions(-) diff --git a/src/Illuminate/Validation/Validator.php b/src/Illuminate/Validation/Validator.php index 7bcdc97b8212..3894e6e141ba 100755 --- a/src/Illuminate/Validation/Validator.php +++ b/src/Illuminate/Validation/Validator.php @@ -290,6 +290,13 @@ class Validator implements ValidatorContract */ protected $numericRules = ['Numeric', 'Integer', 'Decimal']; + /** + * The default numeric related validation rules. + * + * @var string[] + */ + protected $defaultNumericRules = ['Numeric', 'Integer', 'Decimal']; + /** * The current placeholder for dots in rule keys. * @@ -641,6 +648,8 @@ protected function validateAttribute($attribute, $rule) $method = "validate{$rule}"; + $this->numericRules = $this->defaultNumericRules; + if ($validatable && ! $this->$method($attribute, $value, $parameters, $this)) { $this->addFailure($attribute, $rule, $parameters); } diff --git a/tests/Validation/ValidationValidatorTest.php b/tests/Validation/ValidationValidatorTest.php index cc57af1f96d0..6ce65cc2b6d5 100755 --- a/tests/Validation/ValidationValidatorTest.php +++ b/tests/Validation/ValidationValidatorTest.php @@ -3955,6 +3955,166 @@ public function testValidationExistsIsNotCalledUnnecessarily() $this->assertTrue($v->passes()); } + public function testValidateGtMessagesAreCorrect() + { + $trans = $this->getIlluminateArrayTranslator(); + $trans->addLines([ + 'validation.gt.numeric' => 'The :attribute field must be greater than :value.', + 'validation.gt.string' => 'The :attribute field must be greater than :value characters.', + 'validation.gt.file' => 'The :attribute field must be greater than :value kilobytes.', + 'validation.gt.array' => 'The :attribute field must have more than :value items.', + ], 'en'); + + $file = $this->getMockBuilder(UploadedFile::class)->onlyMethods(['getSize', 'isValid'])->setConstructorArgs([__FILE__, false])->getMock(); + $file->expects($this->any())->method('getSize')->willReturn(8919); + $file->expects($this->any())->method('isValid')->willReturn(true); + $otherFile = $this->getMockBuilder(UploadedFile::class)->onlyMethods(['getSize', 'isValid'])->setConstructorArgs([__FILE__, false])->getMock(); + $otherFile->expects($this->any())->method('getSize')->willReturn(9216); + $otherFile->expects($this->any())->method('isValid')->willReturn(true); + + $v = new Validator($trans, [ + 'numeric' => 7, + 'string' => 'abcd', + 'file' => $file, + 'array' => [1, 2, 3], + 'other_numeric' => 10, + 'other_string' => 'abcde', + 'other_file' => $otherFile, + 'other_array' => [1, 2, 3, 4], + ], [ + 'numeric' => 'gt:other_numeric', + 'string' => 'gt:other_string', + 'file' => 'gt:other_file', + 'array' => 'array|gt:other_array', + ]); + + $this->assertFalse($v->passes()); + $this->assertEquals('The numeric field must be greater than 10.', $v->messages()->first('numeric')); + $this->assertEquals('The string field must be greater than 5 characters.', $v->messages()->first('string')); + $this->assertEquals('The file field must be greater than 9 kilobytes.', $v->messages()->first('file')); + $this->assertEquals('The array field must have more than 4 items.', $v->messages()->first('array')); + } + + public function testValidateGteMessagesAreCorrect() + { + $trans = $this->getIlluminateArrayTranslator(); + $trans->addLines([ + 'validation.gte.numeric' => 'The :attribute field must be greater than or equal to :value.', + 'validation.gte.string' => 'The :attribute field must be greater than or equal to :value characters.', + 'validation.gte.file' => 'The :attribute field must be greater than or equal to :value kilobytes.', + 'validation.gte.array' => 'The :attribute field must have :value items or more.', + ], 'en'); + + $file = $this->getMockBuilder(UploadedFile::class)->onlyMethods(['getSize', 'isValid'])->setConstructorArgs([__FILE__, false])->getMock(); + $file->expects($this->any())->method('getSize')->willReturn(8919); + $file->expects($this->any())->method('isValid')->willReturn(true); + $otherFile = $this->getMockBuilder(UploadedFile::class)->onlyMethods(['getSize', 'isValid'])->setConstructorArgs([__FILE__, false])->getMock(); + $otherFile->expects($this->any())->method('getSize')->willReturn(9216); + $otherFile->expects($this->any())->method('isValid')->willReturn(true); + + $v = new Validator($trans, [ + 'numeric' => 7, + 'string' => 'abcd', + 'file' => $file, + 'array' => [1, 2, 3], + 'other_numeric' => 10, + 'other_string' => 'abcde', + 'other_file' => $otherFile, + 'other_array' => [1, 2, 3, 4], + ], [ + 'numeric' => 'gte:other_numeric', + 'string' => 'gte:other_string', + 'file' => 'gte:other_file', + 'array' => 'array|gte:other_array', + ]); + + $this->assertFalse($v->passes()); + $this->assertEquals('The numeric field must be greater than or equal to 10.', $v->messages()->first('numeric')); + $this->assertEquals('The string field must be greater than or equal to 5 characters.', $v->messages()->first('string')); + $this->assertEquals('The file field must be greater than or equal to 9 kilobytes.', $v->messages()->first('file')); + $this->assertEquals('The array field must have 4 items or more.', $v->messages()->first('array')); + } + + public function testValidateLtMessagesAreCorrect() + { + $trans = $this->getIlluminateArrayTranslator(); + $trans->addLines([ + 'validation.lt.numeric' => 'The :attribute field must be less than :value.', + 'validation.lt.string' => 'The :attribute field must be less than :value characters.', + 'validation.lt.file' => 'The :attribute field must be less than :value kilobytes.', + 'validation.lt.array' => 'The :attribute field must have less than :value items.', + ], 'en'); + + $file = $this->getMockBuilder(UploadedFile::class)->onlyMethods(['getSize', 'isValid'])->setConstructorArgs([__FILE__, false])->getMock(); + $file->expects($this->any())->method('getSize')->willReturn(8919); + $file->expects($this->any())->method('isValid')->willReturn(true); + $otherFile = $this->getMockBuilder(UploadedFile::class)->onlyMethods(['getSize', 'isValid'])->setConstructorArgs([__FILE__, false])->getMock(); + $otherFile->expects($this->any())->method('getSize')->willReturn(8192); + $otherFile->expects($this->any())->method('isValid')->willReturn(true); + + $v = new Validator($trans, [ + 'numeric' => 7, + 'string' => 'abcd', + 'file' => $file, + 'array' => [1, 2, 3], + 'other_numeric' => 5, + 'other_string' => 'abc', + 'other_file' => $otherFile, + 'other_array' => [1, 2], + ], [ + 'numeric' => 'lt:other_numeric', + 'string' => 'lt:other_string', + 'file' => 'lt:other_file', + 'array' => 'array|lt:other_array', + ]); + + $this->assertFalse($v->passes()); + $this->assertEquals('The numeric field must be less than 5.', $v->messages()->first('numeric')); + $this->assertEquals('The string field must be less than 3 characters.', $v->messages()->first('string')); + $this->assertEquals('The file field must be less than 8 kilobytes.', $v->messages()->first('file')); + $this->assertEquals('The array field must have less than 2 items.', $v->messages()->first('array')); + } + + public function testValidateLteMessagesAreCorrect() + { + $trans = $this->getIlluminateArrayTranslator(); + $trans->addLines([ + 'validation.lte.numeric' => 'The :attribute field must be less than or equal to :value.', + 'validation.lte.string' => 'The :attribute field must be less than or equal to :value characters.', + 'validation.lte.file' => 'The :attribute field must be less than or equal to :value kilobytes.', + 'validation.lte.array' => 'The :attribute field must not have more than :value items.', + ], 'en'); + + $file = $this->getMockBuilder(UploadedFile::class)->onlyMethods(['getSize', 'isValid'])->setConstructorArgs([__FILE__, false])->getMock(); + $file->expects($this->any())->method('getSize')->willReturn(8919); + $file->expects($this->any())->method('isValid')->willReturn(true); + $otherFile = $this->getMockBuilder(UploadedFile::class)->onlyMethods(['getSize', 'isValid'])->setConstructorArgs([__FILE__, false])->getMock(); + $otherFile->expects($this->any())->method('getSize')->willReturn(8192); + $otherFile->expects($this->any())->method('isValid')->willReturn(true); + + $v = new Validator($trans, [ + 'numeric' => 7, + 'string' => 'abcd', + 'file' => $file, + 'array' => [1, 2, 3], + 'other_numeric' => 5, + 'other_string' => 'abc', + 'other_file' => $otherFile, + 'other_array' => [1, 2], + ], [ + 'numeric' => 'lte:other_numeric', + 'string' => 'lte:other_string', + 'file' => 'lte:other_file', + 'array' => 'array|lte:other_array', + ]); + + $this->assertFalse($v->passes()); + $this->assertEquals('The numeric field must be less than or equal to 5.', $v->messages()->first('numeric')); + $this->assertEquals('The string field must be less than or equal to 3 characters.', $v->messages()->first('string')); + $this->assertEquals('The file field must be less than or equal to 8 kilobytes.', $v->messages()->first('file')); + $this->assertEquals('The array field must not have more than 2 items.', $v->messages()->first('array')); + } + public function testValidateIp() { $trans = $this->getIlluminateArrayTranslator(); @@ -8917,6 +9077,9 @@ public function testItTrimsSpaceFromParameters() 'foo' => '4', ' foo' => ' 5', ' foo ' => ' 6 ', + 'foo_str' => 'abcd', + ' foo_str' => ' abcd', + ' foo_str ' => ' abcd ', ], [ 'min' => 'numeric|min: 20', 'min_str' => 'min: 5', @@ -8925,16 +9088,16 @@ public function testItTrimsSpaceFromParameters() 'between_str' => "between:\t 5, 6\n", 'gt' => 'numeric|gt: 4', 'gt_field' => 'numeric|gt:foo', - 'gt_str' => 'gt:foo', + 'gt_str' => 'gt:foo_str', 'lt' => 'numeric|lt: 6', 'lt_field' => 'numeric|lt: foo ', - 'lt_str' => 'lt: foo ', + 'lt_str' => 'lt: foo_str ', 'gte' => 'numeric|gte: 5', 'gte_field' => 'numeric|gte: foo', - 'gte_str' => 'gte: foo', + 'gte_str' => 'gte: foo_str', 'lte' => 'numeric|lte: 5', 'lte_field' => 'numeric|lte: foo', - 'lte_str' => 'lte: foo', + 'lte_str' => 'lte: foo_str', 'max' => 'numeric|max: 20', 'max_str' => 'max: 5', 'size' => 'numeric|size: 20', @@ -8967,6 +9130,9 @@ public function testItTrimsSpaceFromParameters() 'foo' => '4', ' foo' => ' 5', ' foo ' => ' 6 ', + 'foo_str' => 'abcd', + ' foo_str' => ' abcd', + ' foo_str ' => ' abcd ', ], [ 'min' => 'numeric|min: 21', 'min_str' => 'min: 6', @@ -8975,16 +9141,16 @@ public function testItTrimsSpaceFromParameters() 'between_str' => "between:\t 6, 7\n", 'gt' => 'numeric|gt: 5', 'gt_field' => 'numeric|gt: foo ', - 'gt_str' => 'gt: foo', + 'gt_str' => 'gt: foo_str', 'lt' => 'numeric|lt: 5', 'lt_field' => 'numeric|lt: foo', - 'lt_str' => 'lt: foo', + 'lt_str' => 'lt: foo_str', 'gte' => 'numeric|gte: 6', 'gte_field' => 'numeric|gte: foo ', - 'gte_str' => 'gte: foo ', + 'gte_str' => 'gte: foo_str ', 'lte' => 'numeric|lte: 4', 'lte_field' => 'numeric|lte:foo', - 'lte_str' => 'lte:foo', + 'lte_str' => 'lte:foo_str', 'max' => 'numeric|max: 19', 'max_str' => 'max: 4', 'size' => 'numeric|size: 19',