[TASK] Replace ObjectManager create with get
[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 /**
24 * Testcase for the String to String converter
25 *
26 * @license http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public License, version 3 or later
27 * @covers \TYPO3\CMS\Extbase\Property\TypeConverter\PersistentObjectConverter<extended>
28 */
29 class PersistentObjectConverterTest extends \TYPO3\CMS\Extbase\Tests\Unit\BaseTestCase {
30
31 /**
32 * @var \TYPO3\CMS\Extbase\Property\TypeConverterInterface
33 */
34 protected $converter;
35
36 protected $mockReflectionService;
37
38 protected $mockPersistenceManager;
39
40 protected $mockObjectManager;
41
42 public function setUp() {
43 $this->converter = new \TYPO3\CMS\Extbase\Property\TypeConverter\PersistentObjectConverter();
44 $this->mockReflectionService = $this->getMock('TYPO3\\CMS\\Extbase\\Reflection\\ReflectionService');
45 $this->converter->injectReflectionService($this->mockReflectionService);
46 $this->mockPersistenceManager = $this->getMock('TYPO3\\CMS\\Extbase\\Persistence\\PersistenceManagerInterface');
47 $this->converter->injectPersistenceManager($this->mockPersistenceManager);
48 $this->mockObjectManager = $this->getMock('TYPO3\\CMS\\Extbase\\Object\\ObjectManagerInterface');
49 $this->converter->injectObjectManager($this->mockObjectManager);
50 }
51
52 /**
53 * @test
54 * @author Sebastian Kurfürst <sebastian@typo3.org>
55 */
56 public function checkMetadata() {
57 $this->assertEquals(array('string', 'array'), $this->converter->getSupportedSourceTypes(), 'Source types do not match');
58 $this->assertEquals('object', $this->converter->getSupportedTargetType(), 'Target type does not match');
59 $this->assertEquals(1, $this->converter->getPriority(), 'Priority does not match');
60 }
61
62 /**
63 * @return array
64 */
65 public function dataProviderForCanConvert() {
66 return array(
67 array(TRUE, FALSE, TRUE),
68 // is entity => can convert
69 array(FALSE, TRUE, TRUE),
70 // is valueobject => can convert
71 array(FALSE, FALSE, FALSE)
72 );
73 }
74
75 /**
76 * @test
77 * @dataProvider dataProviderForCanConvert
78 * @author Sebastian Kurfürst <sebastian@typo3.org>
79 * @param boolean $isEntity
80 * @param boolean $isValueObject
81 * @param mixed $expected
82 */
83 public function canConvertFromReturnsTrueIfClassIsTaggedWithEntityOrValueObject($isEntity, $isValueObject, $expected) {
84 $className = uniqid('Test_Class');
85 if ($isEntity) {
86 eval("class {$className} extends Tx_Extbase_DomainObject_AbstractEntity {}");
87 } elseif ($isValueObject) {
88 eval("class {$className} extends Tx_Extbase_DomainObject_AbstractValueObject {}");
89 } else {
90 eval("class {$className} {}");
91 }
92 $this->assertEquals($expected, $this->converter->canConvertFrom('myInputData', $className));
93 }
94
95 /**
96 * test
97 *
98 * @author Sebastian Kurfürst <sebastian@typo3.org>
99 */
100 public function getPropertyNamesReturnsEmptyArray() {
101 $this->assertEquals(array(), $this->converter->getPropertyNames('myString'));
102 }
103
104 /**
105 * @test
106 * @author Sebastian Kurfürst <sebastian@typo3.org>
107 */
108 public function getSourceChildPropertiesToBeConvertedReturnsAllPropertiesExceptTheIdentityProperty() {
109 $source = array(
110 'k1' => 'v1',
111 '__identity' => 'someIdentity',
112 'k2' => 'v2'
113 );
114 $expected = array(
115 'k1' => 'v1',
116 'k2' => 'v2'
117 );
118 $this->assertEquals($expected, $this->converter->getSourceChildPropertiesToBeConverted($source));
119 }
120
121 /**
122 * @test
123 * @author Sebastian Kurfürst <sebastian@typo3.org>
124 */
125 public function getTypeOfChildPropertyShouldUseReflectionServiceToDetermineType() {
126 $mockSchema = $this->getMockBuilder('TYPO3\\CMS\\Extbase\\Reflection\\ClassSchema')->disableOriginalConstructor()->getMock();
127 $this->mockReflectionService->expects($this->any())->method('getClassSchema')->with('TheTargetType')->will($this->returnValue($mockSchema));
128 $mockSchema->expects($this->any())->method('hasProperty')->with('thePropertyName')->will($this->returnValue(TRUE));
129 $mockSchema->expects($this->any())->method('getProperty')->with('thePropertyName')->will($this->returnValue(array(
130 'type' => 'TheTypeOfSubObject',
131 'elementType' => NULL
132 )));
133 $configuration = $this->buildConfiguration(array());
134 $this->assertEquals('TheTypeOfSubObject', $this->converter->getTypeOfChildProperty('TheTargetType', 'thePropertyName', $configuration));
135 }
136
137 /**
138 * @test
139 * @author Sebastian Kurfürst <sebastian@typo3.org>
140 */
141 public function getTypeOfChildPropertyShouldUseConfiguredTypeIfItWasSet() {
142 $this->mockReflectionService->expects($this->never())->method('getClassSchema');
143 $configuration = $this->buildConfiguration(array());
144 $configuration->forProperty('thePropertyName')->setTypeConverterOption('TYPO3\\CMS\\Extbase\\Property\\TypeConverter\\PersistentObjectConverter', \TYPO3\CMS\Extbase\Property\TypeConverter\PersistentObjectConverter::CONFIGURATION_TARGET_TYPE, 'Foo\\Bar');
145 $this->assertEquals('Foo\\Bar', $this->converter->getTypeOfChildProperty('foo', 'thePropertyName', $configuration));
146 }
147
148 /**
149 * @test
150 * @author Sebastian Kurfürst <sebastian@typo3.org>
151 */
152 public function convertFromShouldFetchObjectFromPersistenceIfuidStringIsGiven() {
153 $identifier = '17';
154 $object = new \stdClass();
155 $this->mockPersistenceManager->expects($this->once())->method('getObjectByIdentifier')->with($identifier)->will($this->returnValue($object));
156 $this->assertSame($object, $this->converter->convertFrom($identifier, 'MySpecialType'));
157 }
158
159 /**
160 * @test
161 * @author Sebastian Kurfürst <sebastian@typo3.org>
162 */
163 public function convertFromShouldFetchObjectFromPersistenceIfOnlyIdentityArrayGiven() {
164 $identifier = '12345';
165 $object = new \stdClass();
166 $source = array(
167 '__identity' => $identifier
168 );
169 $this->mockPersistenceManager->expects($this->once())->method('getObjectByIdentifier')->with($identifier)->will($this->returnValue($object));
170 $this->assertSame($object, $this->converter->convertFrom($source, 'MySpecialType'));
171 }
172
173 /**
174 * @test
175 * @author Sebastian Kurfürst <sebastian@typo3.org>
176 * @expectedException \TYPO3\CMS\Extbase\Property\Exception\InvalidPropertyMappingConfigurationException
177 */
178 public function convertFromShouldThrowExceptionIfObjectNeedsToBeModifiedButConfigurationIsNotSet() {
179 $identifier = '12345';
180 $object = new \stdClass();
181 $object->someProperty = 'asdf';
182 $source = array(
183 '__identity' => $identifier,
184 'foo' => 'bar'
185 );
186 $this->mockPersistenceManager->expects($this->once())->method('getObjectByIdentifier')->with($identifier)->will($this->returnValue($object));
187 $this->converter->convertFrom($source, 'MySpecialType');
188 }
189
190 /**
191 * @param array $typeConverterOptions
192 * @return \TYPO3\CMS\Extbase\Property\PropertyMappingConfiguration
193 */
194 protected function buildConfiguration($typeConverterOptions) {
195 $configuration = new \TYPO3\CMS\Extbase\Property\PropertyMappingConfiguration();
196 $configuration->setTypeConverterOptions('TYPO3\\CMS\\Extbase\\Property\\TypeConverter\\PersistentObjectConverter', $typeConverterOptions);
197 return $configuration;
198 }
199
200 /**
201 * @test
202 * @author Sebastian Kurfürst <sebastian@typo3.org>
203 */
204 public function convertFromShouldCloneTheFetchedObjectIfObjectNeedsToBeModified() {
205 $identifier = '12345';
206 $object = new \TYPO3\CMS\Extbase\Tests\Fixture\ClassWithSetters();
207 $object->someProperty = 'asdf';
208 $source = array(
209 '__identity' => $identifier,
210 'foo' => 'bar'
211 );
212 $convertedChildProperties = array(
213 'property1' => 'someConvertedValue'
214 );
215 $this->mockPersistenceManager->expects($this->once())->method('getObjectByIdentifier')->with($identifier)->will($this->returnValue($object));
216 $configuration = $this->buildConfiguration(array(\TYPO3\CMS\Extbase\Property\TypeConverter\PersistentObjectConverter::CONFIGURATION_MODIFICATION_ALLOWED => TRUE));
217 $actual = $this->converter->convertFrom($source, 'MySpecialType', $convertedChildProperties, $configuration);
218 $this->assertNotSame($object, $actual, 'The object has not been cloned.');
219 $this->assertEquals('asdf', $actual->someProperty, 'The object somehow lost its current state.');
220 $this->assertEquals('someConvertedValue', $actual->property1, 'The sub properties have not been set.');
221 }
222
223 /**
224 * @param integer $numberOfResults
225 * @param Matcher $howOftenIsGetFirstCalled
226 * @return \stdClass
227 * @author Bastian Waidelich <bastian@typo3.org>
228 * @author Sebastian Kurfürst <sebastian@typo3.org>
229 */
230 public function setupMockQuery($numberOfResults, $howOftenIsGetFirstCalled) {
231 $mockClassSchema = $this->getMock('TYPO3\\CMS\\Extbase\\Reflection\\ClassSchema', array(), array('Dummy'));
232 $mockClassSchema->expects($this->once())->method('getIdentityProperties')->will($this->returnValue(array('key1' => 'someType')));
233 $this->mockReflectionService->expects($this->once())->method('getClassSchema')->with('SomeType')->will($this->returnValue($mockClassSchema));
234 $mockConstraint = $this->getMockBuilder('Tx_Extbase_Persistence_Generic_Qom_Comparison')->disableOriginalConstructor()->getMock();
235 $mockObject = new \stdClass();
236 $mockQuery = $this->getMock('TYPO3\\CMS\\Extbase\\Persistence\\QueryInterface');
237 $mockQueryResult = $this->getMock('TYPO3\\CMS\\Extbase\\Persistence\\QueryResultInterface');
238 $mockQueryResult->expects($this->once())->method('count')->will($this->returnValue($numberOfResults));
239 $mockQueryResult->expects($howOftenIsGetFirstCalled)->method('getFirst')->will($this->returnValue($mockObject));
240 $mockQuery->expects($this->once())->method('equals')->with('key1', 'value1')->will($this->returnValue($mockConstraint));
241 $mockQuery->expects($this->once())->method('matching')->with($mockConstraint)->will($this->returnValue($mockQuery));
242 $mockQuery->expects($this->once())->method('execute')->will($this->returnValue($mockQueryResult));
243 $this->mockPersistenceManager->expects($this->once())->method('createQueryForType')->with('SomeType')->will($this->returnValue($mockQuery));
244 return $mockObject;
245 }
246
247 /**
248 * @test
249 * @author Sebastian Kurfürst <sebastian@typo3.org>
250 * @expectedException \TYPO3\CMS\Extbase\Property\Exception\InvalidPropertyMappingConfigurationException
251 */
252 public function convertFromShouldThrowExceptionIfObjectNeedsToBeCreatedButConfigurationIsNotSet() {
253 $source = array(
254 'foo' => 'bar'
255 );
256 $this->converter->convertFrom($source, 'MySpecialType');
257 }
258
259 /**
260 * @test
261 * @author Sebastian Kurfürst <sebastian@typo3.org>
262 */
263 public function convertFromShouldCreateObject() {
264 $source = array(
265 'propertyX' => 'bar'
266 );
267 $object = new \TYPO3\CMS\Extbase\Tests\Fixture\ClassWithSetters();
268 $convertedChildProperties = array(
269 'property1' => 'bar'
270 );
271 $this->mockObjectManager->expects($this->once())->method('get')->with('TYPO3\\CMS\\Extbase\\Tests\\Fixture\\ClassWithSetters')->will($this->returnValue($object));
272 $this->mockReflectionService->expects($this->once())->method('getMethodParameters')->with('TYPO3\\CMS\\Extbase\\Tests\\Fixture\\ClassWithSetters', '__construct')->will($this->returnValue(array()));
273 $configuration = $this->buildConfiguration(array(\TYPO3\CMS\Extbase\Property\TypeConverter\PersistentObjectConverter::CONFIGURATION_CREATION_ALLOWED => TRUE));
274 $result = $this->converter->convertFrom($source, 'TYPO3\\CMS\\Extbase\\Tests\\Fixture\\ClassWithSetters', $convertedChildProperties, $configuration);
275 $this->assertSame($object, $result);
276 }
277
278 /**
279 * @test
280 */
281 public function convertFromForModelWithoutConstructorCreatesObject() {
282 $className = 'TYPO3\\CMS\\Extbase\\Tests\\Fixture\\ClassWithSetters';
283 $source = array('propertyX' => 'bar');
284 $model = new $className();
285 $convertedChildProperties = array('property1' => 'bar');
286 $this->mockObjectManager->expects($this->once())->method('get')->with($className)->will($this->returnValue($model));
287 $configuration = $this->buildConfiguration(array(\TYPO3\CMS\Extbase\Property\TypeConverter\PersistentObjectConverter::CONFIGURATION_CREATION_ALLOWED => TRUE));
288 $reflectionException = new \ReflectionException('Method ' . $className . '::__construct() does not exist');
289 $this->mockReflectionService->expects($this->once())->method('getMethodParameters')->with($className, '__construct')->will($this->throwException($reflectionException));
290 $result = $this->converter->convertFrom($source, $className, $convertedChildProperties, $configuration);
291 $this->assertSame($model, $result);
292 }
293
294 /**
295 * @test
296 * @author Sebastian Kurfürst <sebastian@typo3.org>
297 * @expectedException \TYPO3\CMS\Extbase\Property\Exception\InvalidTargetException
298 */
299 public function convertFromShouldThrowExceptionIfPropertyOnTargetObjectCouldNotBeSet() {
300 $source = array(
301 'propertyX' => 'bar'
302 );
303 $object = new \TYPO3\CMS\Extbase\Tests\Fixture\ClassWithSetters();
304 $convertedChildProperties = array(
305 'propertyNotExisting' => 'bar'
306 );
307 $this->mockObjectManager->expects($this->once())->method('get')->with('TYPO3\\CMS\\Extbase\\Tests\\Fixture\\ClassWithSetters')->will($this->returnValue($object));
308 $this->mockReflectionService->expects($this->once())->method('getMethodParameters')->with('TYPO3\\CMS\\Extbase\\Tests\\Fixture\\ClassWithSetters', '__construct')->will($this->returnValue(array()));
309 $configuration = $this->buildConfiguration(array(\TYPO3\CMS\Extbase\Property\TypeConverter\PersistentObjectConverter::CONFIGURATION_CREATION_ALLOWED => TRUE));
310 $result = $this->converter->convertFrom($source, 'TYPO3\\CMS\\Extbase\\Tests\\Fixture\\ClassWithSetters', $convertedChildProperties, $configuration);
311 $this->assertSame($object, $result);
312 }
313
314 /**
315 * @test
316 * @author Sebastian Kurfürst <sebastian@typo3.org>
317 */
318 public function convertFromShouldCreateObjectWhenThereAreConstructorParameters() {
319 $source = array(
320 'propertyX' => 'bar'
321 );
322 $object = new \TYPO3\CMS\Extbase\Tests\Fixture\ClassWithSettersAndConstructor('param1');
323 $convertedChildProperties = array(
324 'property1' => 'param1',
325 'property2' => 'bar'
326 );
327 $this->mockObjectManager->expects($this->once())->method('get')->with('TYPO3\\CMS\\Extbase\\Tests\\Fixture\\ClassWithSettersAndConstructor', 'param1')->will($this->returnValue($object));
328 $this->mockReflectionService->expects($this->once())->method('getMethodParameters')->with('TYPO3\\CMS\\Extbase\\Tests\\Fixture\\ClassWithSettersAndConstructor', '__construct')->will($this->returnValue(array(
329 'property1' => array('optional' => FALSE)
330 )));
331 $configuration = $this->buildConfiguration(array(\TYPO3\CMS\Extbase\Property\TypeConverter\PersistentObjectConverter::CONFIGURATION_CREATION_ALLOWED => TRUE));
332 $result = $this->converter->convertFrom($source, 'TYPO3\\CMS\\Extbase\\Tests\\Fixture\\ClassWithSettersAndConstructor', $convertedChildProperties, $configuration);
333 $this->assertSame($object, $result);
334 $this->assertEquals('bar', $object->getProperty2());
335 }
336
337 /**
338 * @test
339 * @author Sebastian Kurfürst <sebastian@typo3.org>
340 */
341 public function convertFromShouldCreateObjectWhenThereAreOptionalConstructorParameters() {
342 $source = array(
343 'propertyX' => 'bar'
344 );
345 $object = new \TYPO3\CMS\Extbase\Tests\Fixture\ClassWithSettersAndConstructor('param1');
346 $this->mockObjectManager->expects($this->once())->method('get')->with('TYPO3\\CMS\\Extbase\\Tests\\Fixture\\ClassWithSettersAndConstructor', 'thisIsTheDefaultValue')->will($this->returnValue($object));
347 $this->mockReflectionService->expects($this->once())->method('getMethodParameters')->with('TYPO3\\CMS\\Extbase\\Tests\\Fixture\\ClassWithSettersAndConstructor', '__construct')->will($this->returnValue(array(
348 'property1' => array('optional' => TRUE, 'defaultValue' => 'thisIsTheDefaultValue')
349 )));
350 $configuration = $this->buildConfiguration(array(\TYPO3\CMS\Extbase\Property\TypeConverter\PersistentObjectConverter::CONFIGURATION_CREATION_ALLOWED => TRUE));
351 $result = $this->converter->convertFrom($source, 'TYPO3\\CMS\\Extbase\\Tests\\Fixture\\ClassWithSettersAndConstructor', array(), $configuration);
352 $this->assertSame($object, $result);
353 }
354
355 /**
356 * @test
357 * @author Sebastian Kurfürst <sebastian@typo3.org>
358 * @expectedException \TYPO3\CMS\Extbase\Property\Exception\InvalidTargetException
359 */
360 public function convertFromShouldThrowExceptionIfRequiredConstructorParameterWasNotFound() {
361 $source = array(
362 'propertyX' => 'bar'
363 );
364 $object = new \TYPO3\CMS\Extbase\Tests\Fixture\ClassWithSettersAndConstructor('param1');
365 $convertedChildProperties = array(
366 'property2' => 'bar'
367 );
368 $this->mockReflectionService->expects($this->once())->method('getMethodParameters')->with('TYPO3\\CMS\\Extbase\\Tests\\Fixture\\ClassWithSettersAndConstructor', '__construct')->will($this->returnValue(array(
369 'property1' => array('optional' => FALSE)
370 )));
371 $configuration = $this->buildConfiguration(array(\TYPO3\CMS\Extbase\Property\TypeConverter\PersistentObjectConverter::CONFIGURATION_CREATION_ALLOWED => TRUE));
372 $result = $this->converter->convertFrom($source, 'TYPO3\\CMS\\Extbase\\Tests\\Fixture\\ClassWithSettersAndConstructor', $convertedChildProperties, $configuration);
373 $this->assertSame($object, $result);
374 }
375 }
376
377 ?>