84c106a33e9758f4e9f94dec487f9e4b3af0b4ae
[Packages/TYPO3.CMS.git] / typo3 / sysext / extbase / Tests / Unit / Validation / Validator / GenericObjectValidatorTest.php
1 <?php
2 namespace TYPO3\CMS\Extbase\Tests\Unit\Validation\Validator;
3
4 /* *
5 * This script belongs to the Extbase framework. *
6 * *
7 * It is free software; you can redistribute it and/or modify it under *
8 * the terms of the GNU Lesser General Public License as published by the *
9 * Free Software Foundation, either version 3 of the License, or (at your *
10 * option) any later version. *
11 * *
12 * This script is distributed in the hope that it will be useful, but *
13 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- *
14 * TABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser *
15 * General Public License for more details. *
16 * *
17 * You should have received a copy of the GNU Lesser General Public *
18 * License along with the script. *
19 * If not, see http://www.gnu.org/licenses/lgpl.html *
20 * *
21 * The TYPO3 project - inspiring people to share! *
22 * */
23
24 /**
25 * Testcase for the Generic Object Validator
26 *
27 * @license http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public License, version 3 or later
28 */
29 class GenericObjectValidatorTest extends \TYPO3\CMS\Extbase\Tests\Unit\Validation\Validator\AbstractValidatorTestcase
30 {
31 /**
32 * @var string
33 */
34 protected $validatorClassName = \TYPO3\CMS\Extbase\Validation\Validator\GenericObjectValidator::class;
35
36 protected function setUp()
37 {
38 parent::setUp();
39 }
40
41 /**
42 * @test
43 */
44 public function validatorShouldReturnErrorsIfTheValueIsNoObjectAndNotNull()
45 {
46 $this->assertTrue($this->validator->validate('foo')->hasErrors());
47 }
48
49 /**
50 * @test
51 */
52 public function validatorShouldReturnNoErrorsIfTheValueIsNull()
53 {
54 $this->assertFalse($this->validator->validate(null)->hasErrors());
55 }
56
57 /**
58 * @return array
59 */
60 public function dataProviderForValidator()
61 {
62 $error1 = new \TYPO3\CMS\Extbase\Error\Error('error1', 1);
63 $error2 = new \TYPO3\CMS\Extbase\Error\Error('error2', 2);
64 $emptyResult1 = new \TYPO3\CMS\Extbase\Error\Result();
65 $emptyResult2 = new \TYPO3\CMS\Extbase\Error\Result();
66 $resultWithError1 = new \TYPO3\CMS\Extbase\Error\Result();
67 $resultWithError1->addError($error1);
68 $resultWithError2 = new \TYPO3\CMS\Extbase\Error\Result();
69 $resultWithError2->addError($error2);
70 $classNameForObjectWithPrivateProperties = $this->getUniqueId('B');
71 eval('class ' . $classNameForObjectWithPrivateProperties . '{ protected $foo = \'foovalue\'; protected $bar = \'barvalue\'; }');
72 $objectWithPrivateProperties = new $classNameForObjectWithPrivateProperties();
73 return [
74 // If no errors happened, this is shown
75 [$objectWithPrivateProperties, $emptyResult1, $emptyResult2, []],
76 // If errors on two properties happened, they are merged together.
77 [$objectWithPrivateProperties, $resultWithError1, $resultWithError2, ['foo' => [$error1], 'bar' => [$error2]]]
78 ];
79 }
80
81 /**
82 * @test
83 * @dataProvider dataProviderForValidator
84 * @param mixed $mockObject
85 * @param mixed $validationResultForFoo
86 * @param mixed $validationResultForBar
87 * @param mixed $errors
88 */
89 public function validateChecksAllPropertiesForWhichAPropertyValidatorExists($mockObject, $validationResultForFoo, $validationResultForBar, $errors)
90 {
91 $validatorForFoo = $this->getMockBuilder(\TYPO3\CMS\Extbase\Validation\Validator\ValidatorInterface::class)
92 ->setMethods(['validate', 'getOptions'])
93 ->getMock();
94 $validatorForFoo->expects($this->once())->method('validate')->with('foovalue')->will($this->returnValue($validationResultForFoo));
95 $validatorForBar = $this->getMockBuilder(\TYPO3\CMS\Extbase\Validation\Validator\ValidatorInterface::class)
96 ->setMethods(['validate', 'getOptions'])
97 ->getMock();
98 $validatorForBar->expects($this->once())->method('validate')->with('barvalue')->will($this->returnValue($validationResultForBar));
99 $this->validator->addPropertyValidator('foo', $validatorForFoo);
100 $this->validator->addPropertyValidator('bar', $validatorForBar);
101 $this->assertEquals($errors, $this->validator->validate($mockObject)->getFlattenedErrors());
102 }
103
104 /**
105 * @test
106 */
107 public function validateCanHandleRecursiveTargetsWithoutEndlessLooping()
108 {
109 $classNameA = $this->getUniqueId('B');
110 eval('class ' . $classNameA . '{ public $b; }');
111 $classNameB = $this->getUniqueId('B');
112 eval('class ' . $classNameB . '{ public $a; }');
113 $A = new $classNameA();
114 $B = new $classNameB();
115 $A->b = $B;
116 $B->a = $A;
117
118 $aValidator = new \TYPO3\CMS\Extbase\Validation\Validator\GenericObjectValidator([]);
119 $bValidator = new \TYPO3\CMS\Extbase\Validation\Validator\GenericObjectValidator([]);
120
121 $aValidator->addPropertyValidator('b', $bValidator);
122 $bValidator->addPropertyValidator('a', $aValidator);
123 $this->assertFalse($aValidator->validate($A)->hasErrors());
124 }
125
126 /**
127 * @test
128 */
129 public function validateDetectsFailuresInRecursiveTargetsI()
130 {
131 $classNameA = $this->getUniqueId('A');
132 eval('class ' . $classNameA . '{ public $b; }');
133 $classNameB = $this->getUniqueId('B');
134 eval('class ' . $classNameB . '{ public $a; public $uuid = 0xF; }');
135 $A = new $classNameA();
136 $B = new $classNameB();
137 $A->b = $B;
138 $B->a = $A;
139 $aValidator = $this->getValidator();
140 $bValidator = $this->getValidator();
141
142 $aValidator->addPropertyValidator('b', $bValidator);
143 $bValidator->addPropertyValidator('a', $aValidator);
144 $error = new \TYPO3\CMS\Extbase\Error\Error('error1', 123);
145 $result = new \TYPO3\CMS\Extbase\Error\Result();
146 $result->addError($error);
147 $mockUuidValidator = $this->getMockBuilder(\TYPO3\CMS\Extbase\Validation\Validator\ValidatorInterface::class)
148 ->setMethods(['validate', 'getOptions'])
149 ->getMock();
150 $mockUuidValidator->expects($this->any())->method('validate')->with(15)->will($this->returnValue($result));
151 $bValidator->addPropertyValidator('uuid', $mockUuidValidator);
152 $this->assertSame(['b.uuid' => [$error]], $aValidator->validate($A)->getFlattenedErrors());
153 }
154
155 /**
156 * @test
157 */
158 public function validateDetectsFailuresInRecursiveTargetsII()
159 {
160 $classNameA = $this->getUniqueId('A');
161 eval('class ' . $classNameA . '{ public $b; public $uuid = 0xF; }');
162 $classNameB = $this->getUniqueId('B');
163 eval('class ' . $classNameB . '{ public $a; public $uuid = 0xF; }');
164 $A = new $classNameA();
165 $B = new $classNameB();
166 $A->b = $B;
167 $B->a = $A;
168 $aValidator = $this->getValidator();
169 $bValidator = $this->getValidator();
170
171 $aValidator->addPropertyValidator('b', $bValidator);
172 $bValidator->addPropertyValidator('a', $aValidator);
173 $error1 = new \TYPO3\CMS\Extbase\Error\Error('error1', 123);
174 $result1 = new \TYPO3\CMS\Extbase\Error\Result();
175 $result1->addError($error1);
176 $mockUuidValidator = $this->getMockBuilder(\TYPO3\CMS\Extbase\Validation\Validator\ValidatorInterface::class)
177 ->setMethods(['validate', 'getOptions'])
178 ->getMock();
179 $mockUuidValidator->expects($this->any())->method('validate')->with(15)->will($this->returnValue($result1));
180 $aValidator->addPropertyValidator('uuid', $mockUuidValidator);
181 $bValidator->addPropertyValidator('uuid', $mockUuidValidator);
182 $this->assertSame(['b.uuid' => [$error1], 'uuid' => [$error1]], $aValidator->validate($A)->getFlattenedErrors());
183 }
184 }