[TASK] Upgrade to phpunit 5.2
[Packages/TYPO3.CMS.git] / typo3 / sysext / extbase / Tests / Unit / Property / TypeConverter / PersistentObjectConverterTest.php
1 <?php
2 namespace TYPO3\CMS\Extbase\Tests\Unit\Property\TypeConverter;
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 use TYPO3\CMS\Core\Tests\UnitTestCase;
24 use TYPO3\CMS\Extbase\Property\TypeConverter\PersistentObjectConverter;
25 use TYPO3\CMS\Extbase\Tests\Unit\Property\TypeConverter\Fixtures\PersistentObjectEntityFixture;
26 use TYPO3\CMS\Extbase\Tests\Unit\Property\TypeConverter\Fixtures\PersistentObjectFixture;
27 use TYPO3\CMS\Extbase\Tests\Unit\Property\TypeConverter\Fixtures\PersistentObjectValueObjectFixture;
28
29 /**
30 * Test case
31 */
32 class PersistentObjectConverterTest extends UnitTestCase
33 {
34 /**
35 * @var \TYPO3\CMS\Extbase\Property\TypeConverterInterface|\PHPUnit_Framework_MockObject_MockObject
36 */
37 protected $converter;
38
39 /**
40 * @var \TYPO3\CMS\Extbase\Reflection\ReflectionService|\PHPUnit_Framework_MockObject_MockObject
41 */
42 protected $mockReflectionService;
43
44 /**
45 * @var \TYPO3\CMS\Extbase\Persistence\PersistenceManagerInterface|\PHPUnit_Framework_MockObject_MockObject
46 */
47 protected $mockPersistenceManager;
48
49 /**
50 * @var \TYPO3\CMS\Extbase\Object\ObjectManagerInterface|\PHPUnit_Framework_MockObject_MockObject
51 */
52 protected $mockObjectManager;
53
54 /**
55 * @var \TYPO3\CMS\Extbase\Object\Container\Container|\PHPUnit_Framework_MockObject_MockObject
56 */
57 protected $mockContainer;
58
59 /**
60 * @throws \InvalidArgumentException
61 * @throws \PHPUnit_Framework_Exception
62 * @throws \RuntimeException
63 */
64 protected function setUp()
65 {
66 $this->converter = new PersistentObjectConverter();
67 $this->mockReflectionService = $this->getMock(\TYPO3\CMS\Extbase\Reflection\ReflectionService::class);
68 $this->inject($this->converter, 'reflectionService', $this->mockReflectionService);
69
70 $this->mockPersistenceManager = $this->getMock(\TYPO3\CMS\Extbase\Persistence\PersistenceManagerInterface::class);
71 $this->inject($this->converter, 'persistenceManager', $this->mockPersistenceManager);
72
73 $this->mockObjectManager = $this->getMock(\TYPO3\CMS\Extbase\Object\ObjectManagerInterface::class, array());
74 $this->mockObjectManager->expects($this->any())
75 ->method('get')
76 ->will($this->returnCallback(function ($className, ...$arguments) {
77 $reflectionClass = new \ReflectionClass($className);
78 if (empty($arguments)) {
79 return $reflectionClass->newInstance();
80 } else {
81 return $reflectionClass->newInstanceArgs($arguments);
82 }
83 }));
84 $this->inject($this->converter, 'objectManager', $this->mockObjectManager);
85
86 $this->mockContainer = $this->getMock(\TYPO3\CMS\Extbase\Object\Container\Container::class);
87 $this->inject($this->converter, 'objectContainer', $this->mockContainer);
88 }
89
90 /**
91 * @test
92 */
93 public function checkMetadata()
94 {
95 $this->assertEquals(array('integer', 'string', 'array'), $this->converter->getSupportedSourceTypes(), 'Source types do not match');
96 $this->assertEquals('object', $this->converter->getSupportedTargetType(), 'Target type does not match');
97 $this->assertEquals(1, $this->converter->getPriority(), 'Priority does not match');
98 }
99
100 /**
101 * @return array
102 */
103 public function dataProviderForCanConvert()
104 {
105 return array(
106 array(true, false, true),
107 // is entity => can convert
108 array(false, true, true),
109 // is valueobject => can convert
110 array(false, false, false),
111 // is no entity and no value object => can not convert
112 );
113 }
114
115 /**
116 * @test
117 * @dataProvider dataProviderForCanConvert
118 */
119 public function canConvertFromReturnsTrueIfClassIsTaggedWithEntityOrValueObject($isEntity, $isValueObject, $expected)
120 {
121 $className = PersistentObjectFixture::class;
122
123 if ($isEntity) {
124 $className = PersistentObjectEntityFixture::class;
125 } elseif ($isValueObject) {
126 $className = PersistentObjectValueObjectFixture::class;
127 }
128 $this->assertEquals($expected, $this->converter->canConvertFrom('myInputData', $className));
129 }
130
131 /**
132 * @test
133 */
134 public function getSourceChildPropertiesToBeConvertedReturnsAllPropertiesExceptTheIdentityProperty()
135 {
136 $source = array(
137 'k1' => 'v1',
138 '__identity' => 'someIdentity',
139 'k2' => 'v2'
140 );
141 $expected = array(
142 'k1' => 'v1',
143 'k2' => 'v2'
144 );
145 $this->assertEquals($expected, $this->converter->getSourceChildPropertiesToBeConverted($source));
146 }
147
148 /**
149 * @test
150 */
151 public function getTypeOfChildPropertyShouldUseReflectionServiceToDetermineType()
152 {
153 $mockSchema = $this->getMockBuilder(\TYPO3\CMS\Extbase\Reflection\ClassSchema::class)->disableOriginalConstructor()->getMock();
154 $this->mockReflectionService->expects($this->any())->method('getClassSchema')->with('TheTargetType')->will($this->returnValue($mockSchema));
155
156 $this->mockContainer->expects($this->any())->method('getImplementationClassName')->will($this->returnValue('TheTargetType'));
157 $mockSchema->expects($this->any())->method('hasProperty')->with('thePropertyName')->will($this->returnValue(true));
158 $mockSchema->expects($this->any())->method('getProperty')->with('thePropertyName')->will($this->returnValue(array(
159 'type' => 'TheTypeOfSubObject',
160 'elementType' => null
161 )));
162 $configuration = $this->buildConfiguration(array());
163 $this->assertEquals('TheTypeOfSubObject', $this->converter->getTypeOfChildProperty('TheTargetType', 'thePropertyName', $configuration));
164 }
165
166 /**
167 * @test
168 */
169 public function getTypeOfChildPropertyShouldUseConfiguredTypeIfItWasSet()
170 {
171 $this->mockReflectionService->expects($this->never())->method('getClassSchema');
172 $this->mockContainer->expects($this->any())->method('getImplementationClassName')->will($this->returnValue('foo'));
173
174 $configuration = $this->buildConfiguration(array());
175 $configuration->forProperty('thePropertyName')->setTypeConverterOption(\TYPO3\CMS\Extbase\Property\TypeConverter\PersistentObjectConverter::class, PersistentObjectConverter::CONFIGURATION_TARGET_TYPE, 'Foo\Bar');
176 $this->assertEquals('Foo\Bar', $this->converter->getTypeOfChildProperty('foo', 'thePropertyName', $configuration));
177 }
178
179 /**
180 * @test
181 */
182 public function convertFromShouldFetchObjectFromPersistenceIfUuidStringIsGiven()
183 {
184 $identifier = '17';
185 $object = new \stdClass();
186
187 $this->mockPersistenceManager->expects($this->any())->method('getObjectByIdentifier')->with($identifier)->will($this->returnValue($object));
188 $this->assertSame($object, $this->converter->convertFrom($identifier, 'MySpecialType'));
189 }
190
191 /**
192 * @test
193 */
194 public function convertFromShouldFetchObjectFromPersistenceIfuidStringIsGiven()
195 {
196 $identifier = '17';
197 $object = new \stdClass();
198
199 $this->mockPersistenceManager->expects($this->any())->method('getObjectByIdentifier')->with($identifier)->will($this->returnValue($object));
200 $this->assertSame($object, $this->converter->convertFrom($identifier, 'MySpecialType'));
201 }
202
203 /**
204 * @test
205 */
206 public function convertFromShouldFetchObjectFromPersistenceIfOnlyIdentityArrayGiven()
207 {
208 $identifier = '12345';
209 $object = new \stdClass();
210
211 $source = array(
212 '__identity' => $identifier
213 );
214 $this->mockPersistenceManager->expects($this->any())->method('getObjectByIdentifier')->with($identifier)->will($this->returnValue($object));
215 $this->assertSame($object, $this->converter->convertFrom($source, 'MySpecialType'));
216 }
217
218 /**
219 * @test
220 * @expectedException \TYPO3\CMS\Extbase\Property\Exception\InvalidPropertyMappingConfigurationException
221 */
222 public function convertFromShouldThrowExceptionIfObjectNeedsToBeModifiedButConfigurationIsNotSet()
223 {
224 $identifier = '12345';
225 $object = new \stdClass();
226 $object->someProperty = 'asdf';
227
228 $source = array(
229 '__identity' => $identifier,
230 'foo' => 'bar'
231 );
232 $this->mockPersistenceManager->expects($this->any())->method('getObjectByIdentifier')->with($identifier)->will($this->returnValue($object));
233 $this->converter->convertFrom($source, 'MySpecialType');
234 }
235
236 /**
237 * @param array $typeConverterOptions
238 * @return \TYPO3\CMS\Extbase\Property\PropertyMappingConfiguration
239 */
240 protected function buildConfiguration($typeConverterOptions)
241 {
242 $configuration = new \TYPO3\CMS\Extbase\Property\PropertyMappingConfiguration();
243 $configuration->setTypeConverterOptions(\TYPO3\CMS\Extbase\Property\TypeConverter\PersistentObjectConverter::class, $typeConverterOptions);
244 return $configuration;
245 }
246
247 /**
248 * @param int $numberOfResults
249 * @param Matcher $howOftenIsGetFirstCalled
250 * @return \stdClass
251 */
252 public function setupMockQuery($numberOfResults, $howOftenIsGetFirstCalled)
253 {
254 $mockClassSchema = $this->getMock(\TYPO3\CMS\Extbase\Reflection\ClassSchema::class, array(), array('Dummy'));
255 $mockClassSchema->expects($this->any())->method('getIdentityProperties')->will($this->returnValue(array('key1' => 'someType')));
256 $this->mockReflectionService->expects($this->any())->method('getClassSchema')->with('SomeType')->will($this->returnValue($mockClassSchema));
257
258 $mockConstraint = $this->getMockBuilder(\TYPO3\CMS\Extbase\Persistence\Generic\Qom\Comparison::class)->disableOriginalConstructor()->getMock();
259
260 $mockObject = new \stdClass();
261 $mockQuery = $this->getMock(\TYPO3\CMS\Extbase\Persistence\QueryInterface::class);
262 $mockQueryResult = $this->getMock(\TYPO3\CMS\Extbase\Persistence\QueryResultInterface::class);
263 $mockQueryResult->expects($this->any())->method('count')->will($this->returnValue($numberOfResults));
264 $mockQueryResult->expects($howOftenIsGetFirstCalled)->method('getFirst')->will($this->returnValue($mockObject));
265 $mockQuery->expects($this->any())->method('equals')->with('key1', 'value1')->will($this->returnValue($mockConstraint));
266 $mockQuery->expects($this->any())->method('matching')->with($mockConstraint)->will($this->returnValue($mockQuery));
267 $mockQuery->expects($this->any())->method('execute')->will($this->returnValue($mockQueryResult));
268
269 $this->mockPersistenceManager->expects($this->any())->method('createQueryForType')->with('SomeType')->will($this->returnValue($mockQuery));
270
271 return $mockObject;
272 }
273
274 /**
275 * @test
276 * @expectedException \TYPO3\CMS\Extbase\Property\Exception\TargetNotFoundException
277 */
278 public function convertFromShouldReturnExceptionIfNoMatchingObjectWasFound()
279 {
280 $this->setupMockQuery(0, $this->never());
281 $this->mockReflectionService->expects($this->never())->method('getClassSchema');
282
283 $source = array(
284 '__identity' => 123
285 );
286 $actual = $this->converter->convertFrom($source, 'SomeType');
287 $this->assertNull($actual);
288 }
289
290 /**
291 * @test
292 * @expectedException \TYPO3\CMS\Extbase\Property\Exception\DuplicateObjectException
293 */
294 public function convertFromShouldThrowExceptionIfMoreThanOneObjectWasFound()
295 {
296 $this->setupMockQuery(2, $this->never());
297
298 $source = array(
299 '__identity' => 666
300 );
301 $this->mockPersistenceManager->expects($this->any())->method('getObjectByIdentifier')->with(666)->will($this->throwException(new \TYPO3\CMS\Extbase\Property\Exception\DuplicateObjectException));
302 $this->converter->convertFrom($source, 'SomeType');
303 }
304
305 /**
306 * @test
307 * @expectedException \TYPO3\CMS\Extbase\Property\Exception\InvalidPropertyMappingConfigurationException
308 */
309 public function convertFromShouldThrowExceptionIfObjectNeedsToBeCreatedButConfigurationIsNotSet()
310 {
311 $source = array(
312 'foo' => 'bar'
313 );
314 $this->converter->convertFrom($source, 'MySpecialType');
315 }
316
317 /**
318 * @test
319 */
320 public function convertFromShouldCreateObject()
321 {
322 $source = array(
323 'propertyX' => 'bar'
324 );
325 $convertedChildProperties = array(
326 'property1' => 'bar'
327 );
328 $expectedObject = new \TYPO3\CMS\Extbase\Tests\Fixture\ClassWithSetters();
329 $expectedObject->property1 = 'bar';
330
331 $this->mockReflectionService->expects($this->any())->method('getMethodParameters')->with(\TYPO3\CMS\Extbase\Tests\Fixture\ClassWithSetters::class, '__construct')->will($this->throwException(new \ReflectionException()));
332 $configuration = $this->buildConfiguration(array(PersistentObjectConverter::CONFIGURATION_CREATION_ALLOWED => true));
333 $result = $this->converter->convertFrom($source, \TYPO3\CMS\Extbase\Tests\Fixture\ClassWithSetters::class, $convertedChildProperties, $configuration);
334 $this->assertEquals($expectedObject, $result);
335 }
336
337 /**
338 * @test
339 * @expectedException \TYPO3\CMS\Extbase\Property\Exception\InvalidTargetException
340 */
341 public function convertFromShouldThrowExceptionIfPropertyOnTargetObjectCouldNotBeSet()
342 {
343 $source = array(
344 'propertyX' => 'bar'
345 );
346 $object = new \TYPO3\CMS\Extbase\Tests\Fixture\ClassWithSetters();
347 $convertedChildProperties = array(
348 'propertyNotExisting' => 'bar'
349 );
350 $this->mockObjectManager->expects($this->any())->method('get')->with(\TYPO3\CMS\Extbase\Tests\Fixture\ClassWithSetters::class)->will($this->returnValue($object));
351 $this->mockReflectionService->expects($this->any())->method('getMethodParameters')->with(\TYPO3\CMS\Extbase\Tests\Fixture\ClassWithSetters::class, '__construct')->will($this->returnValue(array()));
352 $configuration = $this->buildConfiguration(array(PersistentObjectConverter::CONFIGURATION_CREATION_ALLOWED => true));
353 $result = $this->converter->convertFrom($source, \TYPO3\CMS\Extbase\Tests\Fixture\ClassWithSetters::class, $convertedChildProperties, $configuration);
354 $this->assertSame($object, $result);
355 }
356
357 /**
358 * @test
359 */
360 public function convertFromShouldCreateObjectWhenThereAreConstructorParameters()
361 {
362 $source = array(
363 'propertyX' => 'bar'
364 );
365 $convertedChildProperties = array(
366 'property1' => 'param1',
367 'property2' => 'bar'
368 );
369 $expectedObject = new \TYPO3\CMS\Extbase\Tests\Fixture\ClassWithSettersAndConstructor('param1');
370 $expectedObject->setProperty2('bar');
371
372 $this->mockReflectionService
373 ->expects($this->any())
374 ->method('getMethodParameters')
375 ->with(\TYPO3\CMS\Extbase\Tests\Fixture\ClassWithSettersAndConstructor::class, '__construct')
376 ->will($this->returnValue(array(
377 'property1' => array('optional' => false)
378 )));
379 $this->mockReflectionService
380 ->expects($this->any())
381 ->method('hasMethod')
382 ->with(\TYPO3\CMS\Extbase\Tests\Fixture\ClassWithSettersAndConstructor::class, '__construct')
383 ->will($this->returnValue(true));
384 $this->mockContainer->expects($this->any())->method('getImplementationClassName')->will($this->returnValue(\TYPO3\CMS\Extbase\Tests\Fixture\ClassWithSettersAndConstructor::class));
385 $configuration = $this->buildConfiguration(array(PersistentObjectConverter::CONFIGURATION_CREATION_ALLOWED => true));
386 $result = $this->converter->convertFrom($source, \TYPO3\CMS\Extbase\Tests\Fixture\ClassWithSettersAndConstructor::class, $convertedChildProperties, $configuration);
387 $this->assertEquals($expectedObject, $result);
388 $this->assertEquals('bar', $expectedObject->getProperty2());
389 }
390
391 /**
392 * @test
393 */
394 public function convertFromShouldCreateObjectWhenThereAreOptionalConstructorParameters()
395 {
396 $source = array(
397 'propertyX' => 'bar'
398 );
399 $expectedObject = new \TYPO3\CMS\Extbase\Tests\Fixture\ClassWithSettersAndConstructor('thisIsTheDefaultValue');
400
401 $this->mockReflectionService->expects($this->any())->method('getMethodParameters')->with(\TYPO3\CMS\Extbase\Tests\Fixture\ClassWithSettersAndConstructor::class, '__construct')->will($this->returnValue(array(
402 'property1' => array('optional' => true, 'defaultValue' => 'thisIsTheDefaultValue')
403 )));
404 $this->mockReflectionService
405 ->expects($this->any())
406 ->method('hasMethod')
407 ->with(\TYPO3\CMS\Extbase\Tests\Fixture\ClassWithSettersAndConstructor::class, '__construct')
408 ->will($this->returnValue(true));
409 $this->mockContainer->expects($this->any())->method('getImplementationClassName')->will($this->returnValue(\TYPO3\CMS\Extbase\Tests\Fixture\ClassWithSettersAndConstructor::class));
410 $configuration = $this->buildConfiguration(array(PersistentObjectConverter::CONFIGURATION_CREATION_ALLOWED => true));
411 $result = $this->converter->convertFrom($source, \TYPO3\CMS\Extbase\Tests\Fixture\ClassWithSettersAndConstructor::class, array(), $configuration);
412 $this->assertEquals($expectedObject, $result);
413 }
414
415 /**
416 * @test
417 * @expectedException \TYPO3\CMS\Extbase\Property\Exception\InvalidTargetException
418 */
419 public function convertFromShouldThrowExceptionIfRequiredConstructorParameterWasNotFound()
420 {
421 $source = array(
422 'propertyX' => 'bar'
423 );
424 $object = new \TYPO3\CMS\Extbase\Tests\Fixture\ClassWithSettersAndConstructor('param1');
425 $convertedChildProperties = array(
426 'property2' => 'bar'
427 );
428
429 $this->mockReflectionService->expects($this->any())->method('getMethodParameters')->with(\TYPO3\CMS\Extbase\Tests\Fixture\ClassWithSettersAndConstructor::class, '__construct')->will($this->returnValue(array(
430 'property1' => array('optional' => false)
431 )));
432 $this->mockReflectionService
433 ->expects($this->any())
434 ->method('hasMethod')
435 ->with(\TYPO3\CMS\Extbase\Tests\Fixture\ClassWithSettersAndConstructor::class, '__construct')
436 ->will($this->returnValue(true));
437 $this->mockContainer->expects($this->any())->method('getImplementationClassName')->will($this->returnValue(\TYPO3\CMS\Extbase\Tests\Fixture\ClassWithSettersAndConstructor::class));
438 $configuration = $this->buildConfiguration(array(PersistentObjectConverter::CONFIGURATION_CREATION_ALLOWED => true));
439 $result = $this->converter->convertFrom($source, \TYPO3\CMS\Extbase\Tests\Fixture\ClassWithSettersAndConstructor::class, $convertedChildProperties, $configuration);
440 $this->assertSame($object, $result);
441 }
442
443 /**
444 * @test
445 */
446 public function convertFromShouldReturnNullForEmptyString()
447 {
448 $source = '';
449 $result = $this->converter->convertFrom($source, \TYPO3\CMS\Extbase\Tests\Fixture\ClassWithSettersAndConstructor::class);
450 $this->assertNull($result);
451 }
452 }