d2ca16f380d10fb50afa17a1294cad2f1990bd23
[Packages/TYPO3.CMS.git] / typo3 / sysext / extbase / Tests / Unit / Persistence / Generic / Mapper / DataMapFactoryTest.php
1 <?php
2 namespace TYPO3\CMS\Extbase\Tests\Unit\Persistence\Generic\Mapper;
3
4 /*
5 * This file is part of the TYPO3 CMS project.
6 *
7 * It is free software; you can redistribute it and/or modify it under
8 * the terms of the GNU General Public License, either version 2
9 * of the License, or any later version.
10 *
11 * For the full copyright and license information, please read the
12 * LICENSE.txt file that was distributed with this source code.
13 *
14 * The TYPO3 project - inspiring people to share!
15 */
16
17 use TYPO3\CMS\Core\DataHandling\TableColumnSubType;
18 use TYPO3\CMS\Core\DataHandling\TableColumnType;
19 use TYPO3\CMS\Extbase\Persistence\Generic\Exception\InvalidClassException;
20 use TYPO3\CMS\Extbase\Persistence\Generic\Mapper\ColumnMap;
21 use TYPO3\TestingFramework\Core\AccessibleObjectInterface;
22
23 /**
24 * Test case
25 */
26 class DataMapFactoryTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
27 {
28 /**
29 * @return array
30 */
31 public function oneToOneRelation()
32 {
33 return [
34 ['Tx_Myext_Domain_Model_Foo'],
35 [\TYPO3\CMS\Extbase\Domain\Model\FrontendUser::class]
36 ];
37 }
38
39 /**
40 * @test
41 * @dataProvider oneToOneRelation
42 */
43 public function setRelationsDetectsOneToOneRelation($className)
44 {
45 $mockColumnMap = $this->createMock(\TYPO3\CMS\Extbase\Persistence\Generic\Mapper\ColumnMap::class);
46 $columnConfiguration = [
47 'type' => 'select',
48 'foreign_table' => 'tx_myextension_bar',
49 'foreign_field' => 'parentid'
50 ];
51 $propertyMetaData = [
52 'type' => $className,
53 'elementType' => null
54 ];
55 $mockDataMapFactory = $this->getAccessibleMock(\TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapFactory::class, ['setOneToOneRelation', 'setOneToManyRelation', 'setManyToManyRelation'], [], '', false);
56 $mockDataMapFactory->expects($this->once())->method('setOneToOneRelation')->will($this->returnValue($mockColumnMap));
57 $mockDataMapFactory->expects($this->never())->method('setOneToManyRelation');
58 $mockDataMapFactory->expects($this->never())->method('setManyToManyRelation');
59 $mockDataMapFactory->_callRef('setRelations', $mockColumnMap, $columnConfiguration, $propertyMetaData);
60 }
61
62 /**
63 * @test
64 */
65 public function settingOneToOneRelationSetsRelationTableMatchFields()
66 {
67 $mockColumnMap = $this->createMock(\TYPO3\CMS\Extbase\Persistence\Generic\Mapper\ColumnMap::class);
68 $matchFields = [
69 'fieldname' => 'foo_model'
70 ];
71 $columnConfiguration = [
72 'type' => 'select',
73 'foreign_table' => 'tx_myextension_bar',
74 'foreign_field' => 'parentid',
75 'foreign_match_fields' => $matchFields
76 ];
77
78 $mockColumnMap->expects($this->once())
79 ->method('setRelationTableMatchFields')
80 ->with($matchFields);
81 $mockDataMapFactory = $this->getAccessibleMock(\TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapFactory::class, ['dummy'], [], '', false);
82 $mockDataMapFactory->_call('setOneToOneRelation', $mockColumnMap, $columnConfiguration);
83 }
84
85 /**
86 * @test
87 */
88 public function settingOneToManyRelationSetsRelationTableMatchFields()
89 {
90 $mockColumnMap = $this->createMock(\TYPO3\CMS\Extbase\Persistence\Generic\Mapper\ColumnMap::class);
91 $matchFields = [
92 'fieldname' => 'foo_model'
93 ];
94 $columnConfiguration = [
95 'type' => 'select',
96 'foreign_table' => 'tx_myextension_bar',
97 'foreign_field' => 'parentid',
98 'foreign_match_fields' => $matchFields
99 ];
100
101 $mockColumnMap->expects($this->once())
102 ->method('setRelationTableMatchFields')
103 ->with($matchFields);
104 $mockDataMapFactory = $this->getAccessibleMock(\TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapFactory::class, ['dummy'], [], '', false);
105 $mockDataMapFactory->_call('setOneToManyRelation', $mockColumnMap, $columnConfiguration);
106 }
107
108 /**
109 * @test
110 */
111 public function setRelationsDetectsOneToOneRelationWithIntermediateTable()
112 {
113 $mockColumnMap = $this->createMock(\TYPO3\CMS\Extbase\Persistence\Generic\Mapper\ColumnMap::class);
114 $columnConfiguration = [
115 'type' => 'select',
116 'foreign_table' => 'tx_myextension_bar',
117 'MM' => 'tx_myextension_mm'
118 ];
119 $propertyMetaData = [
120 'type' => 'Tx_Myext_Domain_Model_Foo',
121 'elementType' => null
122 ];
123 $mockDataMapFactory = $this->getAccessibleMock(\TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapFactory::class, ['setOneToOneRelation', 'setOneToManyRelation', 'setManyToManyRelation'], [], '', false);
124 $mockDataMapFactory->expects($this->never())->method('setOneToOneRelation');
125 $mockDataMapFactory->expects($this->never())->method('setOneToManyRelation');
126 $mockDataMapFactory->expects($this->once())->method('setManyToManyRelation')->will($this->returnValue($mockColumnMap));
127 $mockDataMapFactory->_callRef('setRelations', $mockColumnMap, $columnConfiguration, $propertyMetaData);
128 }
129
130 /**
131 * @test
132 */
133 public function setRelationsDetectsOneToManyRelation()
134 {
135 $mockColumnMap = $this->createMock(\TYPO3\CMS\Extbase\Persistence\Generic\Mapper\ColumnMap::class);
136 $columnConfiguration = [
137 'type' => 'select',
138 'foreign_table' => 'tx_myextension_bar',
139 'foreign_field' => 'parentid',
140 'foreign_table_field' => 'parenttable'
141 ];
142 $propertyMetaData = [
143 'type' => \TYPO3\CMS\Extbase\Persistence\ObjectStorage::class,
144 'elementType' => 'Tx_Myext_Domain_Model_Foo'
145 ];
146 $mockDataMapFactory = $this->getAccessibleMock(\TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapFactory::class, ['setOneToOneRelation', 'setOneToManyRelation', 'setManyToManyRelation'], [], '', false);
147 $mockDataMapFactory->expects($this->never())->method('setOneToOneRelation');
148 $mockDataMapFactory->expects($this->once())->method('setOneToManyRelation')->will($this->returnValue($mockColumnMap));
149 $mockDataMapFactory->expects($this->never())->method('setManyToManyRelation');
150 $mockDataMapFactory->_callRef('setRelations', $mockColumnMap, $columnConfiguration, $propertyMetaData);
151 }
152
153 /**
154 * @test
155 */
156 public function setRelationsDetectsSelectRenderTypeSingleAsNonRelational()
157 {
158 $columnMap = new \TYPO3\CMS\Extbase\Persistence\Generic\Mapper\ColumnMap('foo', 'foo');
159 $columnConfiguration = [
160 'type' => 'select',
161 'renderType' => 'selectSingle',
162 'items' => [
163 ['One', 1],
164 ['Two', 2],
165 ['Three', 3],
166 ],
167 ];
168 $propertyMetaData = [];
169 $mockDataMapFactory = $this->getAccessibleMock(\TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapFactory::class, ['setOneToOneRelation', 'setOneToManyRelation', 'setManyToManyRelation'], [], '', false);
170 $mockDataMapFactory->expects($this->never())->method('setOneToOneRelation');
171 $mockDataMapFactory->expects($this->never())->method('setOneToManyRelation');
172 $mockDataMapFactory->expects($this->never())->method('setManyToManyRelation');
173 $actualColumnMap = $mockDataMapFactory->_callRef('setRelations', $columnMap, $columnConfiguration, $propertyMetaData);
174 $this->assertSame($columnMap::RELATION_NONE, $actualColumnMap->getTypeOfRelation());
175 }
176
177 /**
178 * @return array
179 */
180 public function columnConfigurationIsInitializedWithMaxItemsEvaluationForTypeGroupDataProvider()
181 {
182 return [
183 'maxitems not set' => ['', 'RELATION_HAS_MANY'],
184 'maxitems equals 1' => ['1', 'RELATION_NONE'],
185 'maxitems higher than 1' => ['10', 'RELATION_HAS_MANY']
186 ];
187 }
188
189 /**
190 * @test
191 *
192 * @dataProvider columnConfigurationIsInitializedWithMaxItemsEvaluationForTypeGroupDataProvider
193 */
194 public function setRelationsDetectsTypeGroupAndRelationManyToMany($maxitems, $relation)
195 {
196 $columnMap = new \TYPO3\CMS\Extbase\Persistence\Generic\Mapper\ColumnMap('foo', 'foo');
197 if (empty($maxitems)) {
198 $columnConfiguration = [
199 'type' => 'group',
200 ];
201 } else {
202 $columnConfiguration = [
203 'type' => 'group',
204 'maxitems' => $maxitems
205 ];
206 }
207 $propertyMetaData = [];
208 $mockDataMapFactory = $this->getAccessibleMock(\TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapFactory::class, ['setOneToOneRelation', 'setOneToManyRelation', 'setManyToManyRelation'], [], '', false);
209 $mockDataMapFactory->expects($this->never())->method('setOneToOneRelation');
210 $mockDataMapFactory->expects($this->never())->method('setOneToManyRelation');
211 $mockDataMapFactory->expects($this->never())->method('setManyToManyRelation');
212 $actualColumnMap = $mockDataMapFactory->_callRef('setRelations', $columnMap, $columnConfiguration, $propertyMetaData);
213 $this->assertSame($relation, $actualColumnMap->getTypeOfRelation());
214 }
215
216 /**
217 * @test
218 */
219 public function setRelationsDetectsManyToManyRelationOfTypeSelect()
220 {
221 $mockColumnMap = $this->createMock(\TYPO3\CMS\Extbase\Persistence\Generic\Mapper\ColumnMap::class);
222 $columnConfiguration = [
223 'type' => 'select',
224 'foreign_table' => 'tx_myextension_bar',
225 'MM' => 'tx_myextension_mm'
226 ];
227 $propertyMetaData = [
228 'type' => \TYPO3\CMS\Extbase\Persistence\ObjectStorage::class,
229 'elementType' => 'Tx_Myext_Domain_Model_Foo'
230 ];
231 $mockDataMapFactory = $this->getAccessibleMock(\TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapFactory::class, ['setOneToOneRelation', 'setOneToManyRelation', 'setManyToManyRelation'], [], '', false);
232 $mockDataMapFactory->expects($this->never())->method('setOneToOneRelation');
233 $mockDataMapFactory->expects($this->never())->method('setOneToManyRelation');
234 $mockDataMapFactory->expects($this->once())->method('setManyToManyRelation')->will($this->returnValue($mockColumnMap));
235 $mockDataMapFactory->_callRef('setRelations', $mockColumnMap, $columnConfiguration, $propertyMetaData);
236 }
237
238 /**
239 * @test
240 */
241 public function setRelationsDetectsManyToManyRelationOfTypeInlineWithIntermediateTable()
242 {
243 $mockColumnMap = $this->createMock(\TYPO3\CMS\Extbase\Persistence\Generic\Mapper\ColumnMap::class);
244 $columnConfiguration = [
245 'type' => 'inline',
246 'foreign_table' => 'tx_myextension_righttable',
247 'MM' => 'tx_myextension_mm'
248 ];
249 $propertyMetaData = [
250 'type' => \TYPO3\CMS\Extbase\Persistence\ObjectStorage::class,
251 'elementType' => 'Tx_Myext_Domain_Model_Foo'
252 ];
253 $mockDataMapFactory = $this->getAccessibleMock(\TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapFactory::class, ['setOneToOneRelation', 'setOneToManyRelation', 'setManyToManyRelation'], [], '', false);
254 $mockDataMapFactory->expects($this->never())->method('setOneToOneRelation');
255 $mockDataMapFactory->expects($this->never())->method('setOneToManyRelation');
256 $mockDataMapFactory->expects($this->once())->method('setManyToManyRelation')->will($this->returnValue($mockColumnMap));
257 $mockDataMapFactory->_callRef('setRelations', $mockColumnMap, $columnConfiguration, $propertyMetaData);
258 }
259
260 /**
261 * @test
262 */
263 public function columnMapIsInitializedWithManyToManyRelationOfTypeSelect()
264 {
265 $leftColumnsDefinition = [
266 'rights' => [
267 'type' => 'select',
268 'foreign_table' => 'tx_myextension_righttable',
269 'foreign_table_where' => 'WHERE 1=1',
270 'MM' => 'tx_myextension_mm',
271 'MM_table_where' => 'WHERE 2=2'
272 ]
273 ];
274 $mockColumnMap = $this->createMock(\TYPO3\CMS\Extbase\Persistence\Generic\Mapper\ColumnMap::class);
275 $mockColumnMap->expects($this->once())->method('setTypeOfRelation')->with($this->equalTo(ColumnMap::RELATION_HAS_AND_BELONGS_TO_MANY));
276 $mockColumnMap->expects($this->once())->method('setRelationTableName')->with($this->equalTo('tx_myextension_mm'));
277 $mockColumnMap->expects($this->once())->method('setChildTableName')->with($this->equalTo('tx_myextension_righttable'));
278 $mockColumnMap->expects($this->once())->method('setChildTableWhereStatement')->with($this->equalTo('WHERE 1=1'));
279 $mockColumnMap->expects($this->once())->method('setChildSortByFieldName')->with($this->equalTo('sorting'));
280 $mockColumnMap->expects($this->once())->method('setParentKeyFieldName')->with($this->equalTo('uid_local'));
281 $mockColumnMap->expects($this->never())->method('setParentTableFieldName');
282 $mockColumnMap->expects($this->never())->method('setRelationTableMatchFields');
283 $mockColumnMap->expects($this->never())->method('setRelationTableInsertFields');
284 $mockDataMapFactory = $this->getAccessibleMock(\TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapFactory::class, ['dummy'], [], '', false);
285 $mockDataMapFactory->_callRef('setManyToManyRelation', $mockColumnMap, $leftColumnsDefinition['rights']);
286 }
287
288 /**
289 * @test
290 */
291 public function columnMapIsInitializedWithOppositeManyToManyRelationOfTypeSelect()
292 {
293 $rightColumnsDefinition = [
294 'lefts' => [
295 'type' => 'select',
296 'foreign_table' => 'tx_myextension_lefttable',
297 'MM' => 'tx_myextension_mm',
298 'MM_opposite_field' => 'rights'
299 ]
300 ];
301 $leftColumnsDefinition['rights']['MM_opposite_field'] = 'opposite_field';
302 $mockColumnMap = $this->createMock(\TYPO3\CMS\Extbase\Persistence\Generic\Mapper\ColumnMap::class);
303 $mockColumnMap->expects($this->once())->method('setTypeOfRelation')->with($this->equalTo(ColumnMap::RELATION_HAS_AND_BELONGS_TO_MANY));
304 $mockColumnMap->expects($this->once())->method('setRelationTableName')->with($this->equalTo('tx_myextension_mm'));
305 $mockColumnMap->expects($this->once())->method('setChildTableName')->with($this->equalTo('tx_myextension_lefttable'));
306 $mockColumnMap->expects($this->once())->method('setChildTableWhereStatement')->with(null);
307 $mockColumnMap->expects($this->once())->method('setChildSortByFieldName')->with($this->equalTo('sorting_foreign'));
308 $mockColumnMap->expects($this->once())->method('setParentKeyFieldName')->with($this->equalTo('uid_foreign'));
309 $mockColumnMap->expects($this->never())->method('setParentTableFieldName');
310 $mockColumnMap->expects($this->never())->method('setRelationTableMatchFields');
311 $mockColumnMap->expects($this->never())->method('setRelationTableInsertFields');
312 $mockDataMapFactory = $this->getAccessibleMock(\TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapFactory::class, ['dummy'], [], '', false);
313 $mockDataMapFactory->_callRef('setManyToManyRelation', $mockColumnMap, $rightColumnsDefinition['lefts']);
314 }
315
316 /**
317 * @test
318 */
319 public function columnMapIsInitializedWithManyToManyRelationOfTypeInlineAndIntermediateTable()
320 {
321 $leftColumnsDefinition = [
322 'rights' => [
323 'type' => 'inline',
324 'foreign_table' => 'tx_myextension_righttable',
325 'MM' => 'tx_myextension_mm',
326 'foreign_sortby' => 'sorting'
327 ]
328 ];
329 $mockColumnMap = $this->createMock(\TYPO3\CMS\Extbase\Persistence\Generic\Mapper\ColumnMap::class);
330 $mockColumnMap->expects($this->once())->method('setTypeOfRelation')->with($this->equalTo(ColumnMap::RELATION_HAS_AND_BELONGS_TO_MANY));
331 $mockColumnMap->expects($this->once())->method('setRelationTableName')->with($this->equalTo('tx_myextension_mm'));
332 $mockColumnMap->expects($this->once())->method('setChildTableName')->with($this->equalTo('tx_myextension_righttable'));
333 $mockColumnMap->expects($this->once())->method('setChildTableWhereStatement');
334 $mockColumnMap->expects($this->once())->method('setChildSortByFieldName')->with($this->equalTo('sorting'));
335 $mockColumnMap->expects($this->once())->method('setParentKeyFieldName')->with($this->equalTo('uid_local'));
336 $mockColumnMap->expects($this->never())->method('setParentTableFieldName');
337 $mockColumnMap->expects($this->never())->method('setRelationTableMatchFields');
338 $mockColumnMap->expects($this->never())->method('setRelationTableInsertFields');
339 $mockDataMapFactory = $this->getAccessibleMock(\TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapFactory::class, ['getColumnsDefinition'], [], '', false);
340 $mockDataMapFactory->expects($this->never())->method('getColumnsDefinition');
341 $mockDataMapFactory->_callRef('setManyToManyRelation', $mockColumnMap, $leftColumnsDefinition['rights']);
342 }
343
344 /**
345 * @test
346 */
347 public function columnMapIsInitializedWithManyToManyRelationWithoutPidColumn()
348 {
349 $leftColumnsDefinition = [
350 'rights' => [
351 'type' => 'select',
352 'foreign_table' => 'tx_myextension_righttable',
353 'foreign_table_where' => 'WHERE 1=1',
354 'MM' => 'tx_myextension_mm'
355 ]
356 ];
357 $mockColumnMap = $this->createMock(\TYPO3\CMS\Extbase\Persistence\Generic\Mapper\ColumnMap::class);
358 $mockColumnMap->expects($this->once())->method('setRelationTableName')->with($this->equalTo('tx_myextension_mm'));
359 $mockColumnMap->expects($this->once())->method('getRelationTableName')->will($this->returnValue('tx_myextension_mm'));
360 $mockColumnMap->expects($this->never())->method('setrelationTablePageIdColumnName');
361 $mockDataMapFactory = $this->getAccessibleMock(\TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapFactory::class, ['getControlSection'], [], '', false);
362 $mockDataMapFactory->expects($this->once())->method('getControlSection')->with($this->equalTo('tx_myextension_mm'))->will($this->returnValue(null));
363 $mockDataMapFactory->_callRef('setManyToManyRelation', $mockColumnMap, $leftColumnsDefinition['rights']);
364 }
365
366 /**
367 * @test
368 */
369 public function columnMapIsInitializedWithManyToManyRelationWithPidColumn()
370 {
371 $leftColumnsDefinition = [
372 'rights' => [
373 'type' => 'select',
374 'foreign_table' => 'tx_myextension_righttable',
375 'foreign_table_where' => 'WHERE 1=1',
376 'MM' => 'tx_myextension_mm'
377 ]
378 ];
379 $mockColumnMap = $this->createMock(\TYPO3\CMS\Extbase\Persistence\Generic\Mapper\ColumnMap::class);
380 $mockColumnMap->expects($this->once())->method('setRelationTableName')->with($this->equalTo('tx_myextension_mm'));
381 $mockColumnMap->expects($this->once())->method('getRelationTableName')->will($this->returnValue('tx_myextension_mm'));
382 $mockColumnMap->expects($this->once())->method('setrelationTablePageIdColumnName')->with($this->equalTo('pid'));
383 $mockDataMapFactory = $this->getAccessibleMock(\TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapFactory::class, ['getControlSection'], [], '', false);
384 $mockDataMapFactory->expects($this->once())->method('getControlSection')->with($this->equalTo('tx_myextension_mm'))->will($this->returnValue(['ctrl' => ['foo' => 'bar']]));
385 $mockDataMapFactory->_callRef('setManyToManyRelation', $mockColumnMap, $leftColumnsDefinition['rights']);
386 }
387
388 /**
389 * @return array
390 */
391 public function columnMapIsInitializedWithFieldEvaluationsForDateTimeFieldsDataProvider()
392 {
393 return [
394 'date field' => ['date', 'date'],
395 'datetime field' => ['datetime', 'datetime'],
396 'no date/datetime field' => ['', null],
397 ];
398 }
399
400 /**
401 * @param string $type
402 * @param NULL|string $expectedValue
403 * @test
404 * @dataProvider columnMapIsInitializedWithFieldEvaluationsForDateTimeFieldsDataProvider
405 */
406 public function columnMapIsInitializedWithFieldEvaluationsForDateTimeFields($type, $expectedValue)
407 {
408 $columnDefinition = [
409 'type' => 'input',
410 'dbType' => $type,
411 'eval' => $type,
412 ];
413
414 $mockColumnMap = $this->getMockBuilder(\TYPO3\CMS\Extbase\Persistence\Generic\Mapper\ColumnMap::class)
415 ->setMethods(['setDateTimeStorageFormat'])
416 ->disableOriginalConstructor()
417 ->getMock();
418
419 if ($expectedValue !== null) {
420 $mockColumnMap->expects($this->once())->method('setDateTimeStorageFormat')->with($this->equalTo($type));
421 } else {
422 $mockColumnMap->expects($this->never())->method('setDateTimeStorageFormat');
423 }
424
425 $accessibleClassName = $this->buildAccessibleProxy(\TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapFactory::class);
426 $accessibleDataMapFactory = new $accessibleClassName();
427 $accessibleDataMapFactory->_callRef('setFieldEvaluations', $mockColumnMap, $columnDefinition);
428 }
429
430 /**
431 * @test
432 */
433 public function buildDataMapThrowsExceptionIfClassNameIsNotKnown()
434 {
435 $this->expectException(InvalidClassException::class);
436 // @TODO expectExceptionCode is 0
437 $mockDataMapFactory = $this->getAccessibleMock(\TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapFactory::class, ['getControlSection'], [], '', false);
438 $cacheMock = $this->getMockBuilder(\TYPO3\CMS\Core\Cache\Frontend\VariableFrontend::class)
439 ->setMethods(['get'])
440 ->disableOriginalConstructor()
441 ->getMock();
442 $cacheMock->expects($this->any())->method('get')->will($this->returnValue(false));
443 $mockDataMapFactory->_set('dataMapCache', $cacheMock);
444 $mockDataMapFactory->buildDataMap('UnknownObject');
445 }
446
447 /**
448 * @test
449 */
450 public function buildDataMapFetchesSubclassesRecursively()
451 {
452 $this->markTestSkipped('Incomplete mocking in a complex scenario. This should be a functional test');
453 $configuration = [
454 'persistence' => [
455 'classes' => [
456 \TYPO3\CMS\Extbase\Domain\Model\FrontendUser::class => [
457 'subclasses' => [
458 'Tx_SampleExt_Domain_Model_LevelOne1' => 'Tx_SampleExt_Domain_Model_LevelOne1',
459 'Tx_SampleExt_Domain_Model_LevelOne2' => 'Tx_SampleExt_Domain_Model_LevelOne2'
460 ]
461 ],
462 'Tx_SampleExt_Domain_Model_LevelOne1' => [
463 'subclasses' => [
464 'Tx_SampleExt_Domain_Model_LevelTwo1' => 'Tx_SampleExt_Domain_Model_LevelTwo1',
465 'Tx_SampleExt_Domain_Model_LevelTwo2' => 'Tx_SampleExt_Domain_Model_LevelTwo2'
466 ]
467 ],
468 'Tx_SampleExt_Domain_Model_LevelOne2' => [
469 'subclasses' => []
470 ]
471 ]
472 ]
473 ];
474 $expectedSubclasses = [
475 'Tx_SampleExt_Domain_Model_LevelOne1',
476 'Tx_SampleExt_Domain_Model_LevelTwo1',
477 'Tx_SampleExt_Domain_Model_LevelTwo2',
478 'Tx_SampleExt_Domain_Model_LevelOne2'
479 ];
480
481 /** @var \TYPO3\CMS\Extbase\Object\ObjectManagerInterface|\PHPUnit_Framework_MockObject_MockObject $objectManager */
482 $objectManager = $this->getMockBuilder(\TYPO3\CMS\Extbase\Object\ObjectManager::class)
483 ->setMethods(['dummy'])
484 ->disableOriginalConstructor()
485 ->getMock();
486
487 /** @var $configurationManager \TYPO3\CMS\Extbase\Configuration\ConfigurationManager|\PHPUnit_Framework_MockObject_MockObject */
488 $configurationManager = $this->createMock(\TYPO3\CMS\Extbase\Configuration\ConfigurationManager::class);
489 $configurationManager->expects($this->once())->method('getConfiguration')->with('Framework')->will($this->returnValue($configuration));
490 /** @var \TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapFactory $dataMapFactory */
491 $dataMapFactory = $this->getAccessibleMock(\TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapFactory::class, ['test']);
492 $dataMapFactory->_set('reflectionService', new \TYPO3\CMS\Extbase\Reflection\ReflectionService());
493 $dataMapFactory->_set('objectManager', $objectManager);
494 $dataMapFactory->_set('configurationManager', $configurationManager);
495 $cacheMock = $this->createMock(\TYPO3\CMS\Core\Cache\Frontend\VariableFrontend::class);
496 $cacheMock->expects($this->any())->method('get')->will($this->returnValue(false));
497 $dataMapFactory->_set('dataMapCache', $cacheMock);
498 $dataMap = $dataMapFactory->buildDataMap(\TYPO3\CMS\Extbase\Domain\Model\FrontendUser::class);
499 $this->assertSame($expectedSubclasses, $dataMap->getSubclasses());
500 }
501
502 /**
503 * @return array
504 */
505 public function classNameTableNameMappings()
506 {
507 return [
508 'Core classes' => [\TYPO3\CMS\Belog\Domain\Model\LogEntry::class, 'tx_belog_domain_model_logentry'],
509 'Core classes with namespaces and leading backslash' => [\TYPO3\CMS\Belog\Domain\Model\LogEntry::class, 'tx_belog_domain_model_logentry'],
510 'Extension classes' => ['ExtbaseTeam\\BlogExample\\Domain\\Model\\Blog', 'tx_blogexample_domain_model_blog'],
511 'Extension classes with namespaces and leading backslash' => ['\\ExtbaseTeam\\BlogExample\\Domain\\Model\\Blog', 'tx_blogexample_domain_model_blog'],
512 'Extension classes without namespace' => ['Tx_News_Domain_Model_News', 'tx_news_domain_model_news'],
513 'Extension classes without namespace but leading slash' => ['\\Tx_News_Domain_Model_News', 'tx_news_domain_model_news'],
514 ];
515 }
516
517 /**
518 * @test
519 * @dataProvider classNameTableNameMappings
520 */
521 public function resolveTableNameReturnsExpectedTablenames($className, $expected)
522 {
523 $dataMapFactory = $this->getAccessibleMock(\TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapFactory::class, ['dummy']);
524 $this->assertSame($expected, $dataMapFactory->_call('resolveTableName', $className));
525 }
526
527 /**
528 * @test
529 */
530 public function createColumnMapReturnsAValidColumnMap()
531 {
532 /** @var $dataMapFactory \TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapFactory */
533 $dataMapFactory = $this->getAccessibleMock(\TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapFactory::class, ['dummy']);
534
535 /** @var \TYPO3\CMS\Extbase\Object\ObjectManagerInterface|\PHPUnit_Framework_MockObject_MockObject $objectManager */
536 $objectManager = $this->createMock(\TYPO3\CMS\Extbase\Object\ObjectManager::class);
537 $columnMap = $this->getMockBuilder(\TYPO3\CMS\Extbase\Persistence\Generic\Mapper\ColumnMap::class)
538 ->setConstructorArgs(['column', 'property'])
539 ->getMock();
540 $objectManager->expects($this->once())->method('get')->will($this->returnValue($columnMap));
541
542 $dataMapFactory->_set('objectManager', $objectManager);
543
544 $this->assertEquals(
545 $columnMap,
546 $dataMapFactory->_call('createColumnMap', 'column', 'property')
547 );
548 }
549
550 /**
551 * @return array
552 */
553 public function tcaConfigurationsContainingTypeAndInternalType()
554 {
555 return [
556 [['type' => 'input'], TableColumnType::INPUT, null],
557 [['type' => 'text'], TableColumnType::TEXT, null],
558 [['type' => 'check'], TableColumnType::CHECK, null],
559 [['type' => 'radio'], TableColumnType::RADIO, null],
560 [['type' => 'select'], TableColumnType::SELECT, null],
561 [['type' => 'group', 'internal_type' => 'db'], TableColumnType::GROUP, TableColumnSubType::DB],
562 [['type' => 'group', 'internal_type' => 'file'], TableColumnType::GROUP, TableColumnSubType::FILE],
563 [['type' => 'group', 'internal_type' => 'file_reference'], TableColumnType::GROUP, TableColumnSubType::FILE_REFERENCE],
564 [['type' => 'group', 'internal_type' => 'folder'], TableColumnType::GROUP, TableColumnSubType::FOLDER],
565 [['type' => 'none'], TableColumnType::NONE, null],
566 [['type' => 'passthrough'], TableColumnType::PASSTHROUGH, null],
567 [['type' => 'user'], TableColumnType::USER, null],
568 [['type' => 'flex'], TableColumnType::FLEX, null],
569 [['type' => 'inline'], TableColumnType::INLINE, null],
570 ];
571 }
572
573 /**
574 * @test
575 * @dataProvider tcaConfigurationsContainingTypeAndInternalType
576 *
577 * @param array $columnConfiguration
578 * @param string $type
579 * @param string $internalType
580 */
581 public function setTypeDetectsTypeAndInternalTypeProperly(array $columnConfiguration, $type, $internalType)
582 {
583 /** @var $dataMapFactory \TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapFactory | AccessibleObjectInterface */
584 $dataMapFactory = $this->getAccessibleMock(\TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapFactory::class, ['dummy']);
585
586 /** @var ColumnMap $columnMap */
587 $columnMap = $this->getAccessibleMock(\TYPO3\CMS\Extbase\Persistence\Generic\Mapper\ColumnMap::class, ['dummy'], [], '', false);
588
589 $dataMapFactory->_call('setType', $columnMap, $columnConfiguration);
590
591 $this->assertEquals($type, (string)$columnMap->getType());
592 $this->assertEquals($internalType, (string)$columnMap->getInternalType());
593 }
594 }