[BUGFIX] Compare field names without configuration
[Packages/TYPO3.CMS.git] / typo3 / sysext / core / Tests / Unit / Utility / ExtensionManagementUtilityTest.php
1 <?php
2 namespace TYPO3\CMS\Core\Tests\Unit\Utility;
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\Package\PackageManager;
18 use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
19 use TYPO3\CMS\Core\Utility\GeneralUtility;
20
21 /**
22 * Testcase for ExtensionManagementUtility
23 *
24 * @author Oliver Hader <oliver@typo3.org>
25 * @author Oliver Klee <typo3-coding@oliverklee.de>
26 */
27 class ExtensionManagementUtilityTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
28
29 /**
30 * @var array A backup of registered singleton instances
31 */
32 protected $singletonInstances = array();
33
34 /**
35 * @var \TYPO3\CMS\Core\Package\PackageManager
36 */
37 protected $backUpPackageManager;
38
39 protected function setUp() {
40 $this->singletonInstances = GeneralUtility::getSingletonInstances();
41 $this->createAccessibleProxyClass();
42 $this->backUpPackageManager = ExtensionManagementUtilityAccessibleProxy::getPackageManager();
43 $this->singletonInstances = GeneralUtility::getSingletonInstances();
44 }
45
46 protected function tearDown() {
47 ExtensionManagementUtility::clearExtensionKeyMap();
48 ExtensionManagementUtilityAccessibleProxy::setPackageManager($this->backUpPackageManager);
49 ExtensionManagementUtilityAccessibleProxy::setCacheManager(NULL);
50 $GLOBALS['TYPO3_LOADED_EXT'] = new \TYPO3\CMS\Core\Compatibility\LoadedExtensionsArray($this->backUpPackageManager);
51 GeneralUtility::resetSingletonInstances($this->singletonInstances);
52 parent::tearDown();
53 }
54
55 /**
56 * Create a subclass with protected methods made public
57 *
58 * @return void
59 * @TODO: Move this to a fixture file
60 */
61 protected function createAccessibleProxyClass() {
62 $className = 'ExtensionManagementUtilityAccessibleProxy';
63 if (!class_exists(__NAMESPACE__ . '\\' . $className, FALSE)) {
64 eval(
65 'namespace ' . __NAMESPACE__ . ';' .
66 'class ' . $className . ' extends \\TYPO3\\CMS\\Core\\Utility\\ExtensionManagementUtility {' .
67 ' static public function setCacheManager(\TYPO3\CMS\Core\Cache\CacheManager $cacheManager = NULL) {' .
68 ' static::$cacheManager = $cacheManager;' .
69 ' }' .
70 ' public static function getPackageManager() {' .
71 ' return static::$packageManager;' .
72 ' }' .
73 ' public static function createTypo3LoadedExtensionInformationArray() {' .
74 ' return parent::createTypo3LoadedExtensionInformationArray();' .
75 ' }' .
76 ' public static function getTypo3LoadedExtensionInformationCacheIdentifier() {' .
77 ' return parent::getTypo3LoadedExtensionInformationCacheIdentifier();' .
78 ' }' .
79 ' public static function getExtLocalconfCacheIdentifier() {' .
80 ' return parent::getExtLocalconfCacheIdentifier();' .
81 ' }' .
82 ' public static function loadSingleExtLocalconfFiles() {' .
83 ' return parent::loadSingleExtLocalconfFiles();' .
84 ' }' .
85 ' public static function getBaseTcaCacheIdentifier() {' .
86 ' return parent::getBaseTcaCacheIdentifier();' .
87 ' }' .
88 ' public static function resetExtTablesWasReadFromCacheOnceBoolean() {' .
89 ' self::$extTablesWasReadFromCacheOnce = FALSE;' .
90 ' }' .
91 ' public static function createExtLocalconfCacheEntry() {' .
92 ' return parent::createExtLocalconfCacheEntry();' .
93 ' }' .
94 ' public static function createExtTablesCacheEntry() {' .
95 ' return parent::createExtTablesCacheEntry();' .
96 ' }' .
97 ' public static function getExtTablesCacheIdentifier() {' .
98 ' return parent::getExtTablesCacheIdentifier();' .
99 ' }' .
100 ' public static function buildBaseTcaFromSingleFiles() {' .
101 ' $GLOBALS[\'TCA\'] = array();' .
102 ' }' .
103 ' public static function emitTcaIsBeingBuiltSignal(array $tca) {' .
104 ' }' .
105 ' public static function removeDuplicatesForInsertion($insertionList, $list = \'\') {' .
106 ' return parent::removeDuplicatesForInsertion($insertionList, $list);' .
107 ' }' .
108 '}'
109 );
110 }
111 }
112
113 /**
114 * @param string $packageKey
115 * @param array $packageMethods
116 * @return PackageManager|\PHPUnit_Framework_MockObject_MockObject
117 */
118 protected function createMockPackageManagerWithMockPackage($packageKey, $packageMethods = array('getPackagePath', 'getPackageKey')) {
119 $packagePath = PATH_site . 'typo3temp/' . $packageKey . '/';
120 GeneralUtility::mkdir_deep($packagePath);
121 $this->testFilesToDelete[] = $packagePath;
122 $package = $this->getMockBuilder(\TYPO3\CMS\Core\Package\Package::class)
123 ->disableOriginalConstructor()
124 ->setMethods($packageMethods)
125 ->getMock();
126 $packageManager = $this->getMock(
127 \TYPO3\CMS\Core\Package\PackageManager::class,
128 array('isPackageActive', 'getPackage', 'getActivePackages')
129 );
130 $package->expects($this->any())
131 ->method('getPackagePath')
132 ->will($this->returnValue($packagePath));
133 $package->expects($this->any())
134 ->method('getPackageKey')
135 ->will($this->returnValue($packageKey));
136 $packageManager->expects($this->any())
137 ->method('isPackageActive')
138 ->will($this->returnValueMap(array(
139 array(NULL, FALSE),
140 array($packageKey, TRUE)
141 )));
142 $packageManager->expects($this->any())
143 ->method('getPackage')
144 ->with($this->equalTo($packageKey))
145 ->will($this->returnValue($package));
146 $packageManager->expects($this->any())
147 ->method('getActivePackages')
148 ->will($this->returnValue(array($packageKey => $package)));
149 return $packageManager;
150 }
151
152 ///////////////////////////////
153 // Tests concerning isLoaded
154 ///////////////////////////////
155 /**
156 * @test
157 */
158 public function isLoadedReturnsTrueIfExtensionIsLoaded() {
159 $this->assertTrue(ExtensionManagementUtility::isLoaded('cms'));
160 }
161
162 /**
163 * @test
164 */
165 public function isLoadedReturnsFalseIfExtensionIsNotLoadedAndExitIsDisabled() {
166 $this->assertFalse(ExtensionManagementUtility::isLoaded($this->getUniqueId('foobar'), FALSE));
167 }
168
169 /**
170 * @test
171 * @expectedException \BadFunctionCallException
172 */
173 public function isLoadedThrowsExceptionIfExtensionIsNotLoaded() {
174 $this->assertFalse(ExtensionManagementUtility::isLoaded($this->getUniqueId('foobar'), TRUE));
175 }
176
177 ///////////////////////////////
178 // Tests concerning extPath
179 ///////////////////////////////
180 /**
181 * @test
182 * @expectedException \BadFunctionCallException
183 */
184 public function extPathThrowsExceptionIfExtensionIsNotLoaded() {
185 $packageName = $this->getUniqueId('foo');
186 $packageManager = $this->getMock(\TYPO3\CMS\Core\Package\PackageManager::class, array('isPackageActive'));
187 $packageManager->expects($this->once())
188 ->method('isPackageActive')
189 ->with($this->equalTo($packageName))
190 ->will($this->returnValue(FALSE));
191 ExtensionManagementUtility::setPackageManager($packageManager);
192 ExtensionManagementUtility::extPath($packageName);
193 }
194
195 /**
196 * @test
197 */
198 public function extPathAppendsScriptNameToPath() {
199 $package = $this->getMockBuilder(\TYPO3\CMS\Core\Package\Package::class)
200 ->disableOriginalConstructor()
201 ->setMethods(array('getPackagePath'))
202 ->getMock();
203 $packageManager = $this->getMock(\TYPO3\CMS\Core\Package\PackageManager::class, array('isPackageActive', 'getPackage'));
204 $package->expects($this->once())
205 ->method('getPackagePath')
206 ->will($this->returnValue(PATH_site . 'foo/'));
207 $packageManager->expects($this->once())
208 ->method('isPackageActive')
209 ->with($this->equalTo('foo'))
210 ->will($this->returnValue(TRUE));
211 $packageManager->expects($this->once())
212 ->method('getPackage')
213 ->with('foo')
214 ->will($this->returnValue($package));
215 ExtensionManagementUtility::setPackageManager($packageManager);
216 $this->assertSame(PATH_site . 'foo/bar.txt', ExtensionManagementUtility::extPath('foo', 'bar.txt'));
217 }
218
219 //////////////////////
220 // Utility functions
221 //////////////////////
222 /**
223 * Generates a basic TCA for a given table.
224 *
225 * @param string $table name of the table, must not be empty
226 * @return array generated TCA for the given table, will not be empty
227 */
228 private function generateTCAForTable($table) {
229 $tca = array();
230 $tca[$table] = array();
231 $tca[$table]['columns'] = array(
232 'fieldA' => array(),
233 'fieldC' => array()
234 );
235 $tca[$table]['types'] = array(
236 'typeA' => array('showitem' => 'fieldA, fieldB, fieldC;labelC;paletteC;specialC, fieldC1, fieldD, fieldD1'),
237 'typeB' => array('showitem' => 'fieldA, fieldB, fieldC;labelC;paletteC;specialC, fieldC1, fieldD, fieldD1'),
238 'typeC' => array('showitem' => 'fieldC;;paletteD')
239 );
240 $tca[$table]['palettes'] = array(
241 'paletteA' => array('showitem' => 'fieldX, fieldX1, fieldY'),
242 'paletteB' => array('showitem' => 'fieldX, fieldX1, fieldY'),
243 'paletteC' => array('showitem' => 'fieldX, fieldX1, fieldY'),
244 'paletteD' => array('showitem' => 'fieldX, fieldX1, fieldY')
245 );
246 return $tca;
247 }
248
249 /**
250 * Data provider for getClassNamePrefixForExtensionKey.
251 *
252 * @return array
253 */
254 public function extensionKeyDataProvider() {
255 return array(
256 'Without underscores' => array(
257 'testkey',
258 'tx_testkey'
259 ),
260 'With underscores' => array(
261 'this_is_a_test_extension',
262 'tx_thisisatestextension'
263 ),
264 'With user prefix and without underscores' => array(
265 'user_testkey',
266 'user_testkey'
267 ),
268 'With user prefix and with underscores' => array(
269 'user_test_key',
270 'user_testkey'
271 ),
272 );
273 }
274
275 /**
276 * @test
277 * @param string $extensionName
278 * @param string $expectedPrefix
279 * @dataProvider extensionKeyDataProvider
280 */
281 public function getClassNamePrefixForExtensionKey($extensionName, $expectedPrefix) {
282 $this->assertSame($expectedPrefix, ExtensionManagementUtility::getCN($extensionName));
283 }
284
285 /////////////////////////////////////////////
286 // Tests concerning getExtensionKeyByPrefix
287 /////////////////////////////////////////////
288 /**
289 * @test
290 * @see ExtensionManagementUtility::getExtensionKeyByPrefix
291 */
292 public function getExtensionKeyByPrefixForLoadedExtensionWithUnderscoresReturnsExtensionKey() {
293 ExtensionManagementUtility::clearExtensionKeyMap();
294 $uniqueSuffix = $this->getUniqueId('test');
295 $extensionKey = 'tt_news' . $uniqueSuffix;
296 $extensionPrefix = 'tx_ttnews' . $uniqueSuffix;
297 $package = $this->getMockBuilder(\TYPO3\CMS\Core\Package\Package::class)
298 ->disableOriginalConstructor()
299 ->setMethods(array('getPackageKey'))
300 ->getMock();
301 $package->expects($this->exactly(2))
302 ->method('getPackageKey')
303 ->will($this->returnValue($extensionKey));
304 $packageManager = $this->getMock(\TYPO3\CMS\Core\Package\PackageManager::class, array('getActivePackages'));
305 $packageManager->expects($this->once())
306 ->method('getActivePackages')
307 ->will($this->returnValue(array($extensionKey => $package)));
308 ExtensionManagementUtility::setPackageManager($packageManager);
309 $this->assertEquals($extensionKey, ExtensionManagementUtility::getExtensionKeyByPrefix($extensionPrefix));
310 }
311
312 /**
313 * @test
314 * @see ExtensionManagementUtility::getExtensionKeyByPrefix
315 */
316 public function getExtensionKeyByPrefixForLoadedExtensionWithoutUnderscoresReturnsExtensionKey() {
317 ExtensionManagementUtility::clearExtensionKeyMap();
318 $uniqueSuffix = $this->getUniqueId('test');
319 $extensionKey = 'kickstarter' . $uniqueSuffix;
320 $extensionPrefix = 'tx_kickstarter' . $uniqueSuffix;
321 $package = $this->getMockBuilder(\TYPO3\CMS\Core\Package\Package::class)
322 ->disableOriginalConstructor()
323 ->setMethods(array('getPackageKey'))
324 ->getMock();
325 $package->expects($this->exactly(2))
326 ->method('getPackageKey')
327 ->will($this->returnValue($extensionKey));
328 $packageManager = $this->getMock(\TYPO3\CMS\Core\Package\PackageManager::class, array('getActivePackages'));
329 $packageManager->expects($this->once())
330 ->method('getActivePackages')
331 ->will($this->returnValue(array($extensionKey => $package)));
332 ExtensionManagementUtility::setPackageManager($packageManager);
333 $this->assertEquals($extensionKey, ExtensionManagementUtility::getExtensionKeyByPrefix($extensionPrefix));
334 }
335
336 /**
337 * @test
338 * @see ExtensionManagementUtility::getExtensionKeyByPrefix
339 */
340 public function getExtensionKeyByPrefixForNotLoadedExtensionReturnsFalse() {
341 ExtensionManagementUtility::clearExtensionKeyMap();
342 $uniqueSuffix = $this->getUniqueId('test');
343 $extensionKey = 'unloadedextension' . $uniqueSuffix;
344 $extensionPrefix = 'tx_unloadedextension' . $uniqueSuffix;
345 $this->assertFalse(ExtensionManagementUtility::getExtensionKeyByPrefix($extensionPrefix));
346 }
347
348 //////////////////////////////////////
349 // Tests concerning addToAllTCAtypes
350 //////////////////////////////////////
351 /**
352 * Tests whether fields can be add to all TCA types and duplicate fields are considered.
353 *
354 * @test
355 * @see ExtensionManagementUtility::addToAllTCAtypes()
356 */
357 public function canAddFieldsToAllTCATypesBeforeExistingOnes() {
358 $table = $this->getUniqueId('tx_coretest_table');
359 $GLOBALS['TCA'] = $this->generateTCAForTable($table);
360 ExtensionManagementUtility::addToAllTCAtypes($table, 'newA, newA, newB, fieldA', '', 'before:fieldD');
361 // Checking typeA:
362 $this->assertEquals('fieldA, fieldB, fieldC;labelC;paletteC;specialC, fieldC1, newA, newB, fieldD, fieldD1', $GLOBALS['TCA'][$table]['types']['typeA']['showitem']);
363 // Checking typeB:
364 $this->assertEquals('fieldA, fieldB, fieldC;labelC;paletteC;specialC, fieldC1, newA, newB, fieldD, fieldD1', $GLOBALS['TCA'][$table]['types']['typeB']['showitem']);
365 }
366
367 /**
368 * Tests whether fields can be add to all TCA types and duplicate fields are considered.
369 *
370 * @test
371 * @see ExtensionManagementUtility::addToAllTCAtypes()
372 */
373 public function canAddFieldsToAllTCATypesAfterExistingOnes() {
374 $table = $this->getUniqueId('tx_coretest_table');
375 $GLOBALS['TCA'] = $this->generateTCAForTable($table);
376 ExtensionManagementUtility::addToAllTCAtypes($table, 'newA, newA, newB, fieldA', '', 'after:fieldC');
377 // Checking typeA:
378 $this->assertEquals('fieldA, fieldB, fieldC;labelC;paletteC;specialC, newA, newB, fieldC1, fieldD, fieldD1', $GLOBALS['TCA'][$table]['types']['typeA']['showitem']);
379 // Checking typeB:
380 $this->assertEquals('fieldA, fieldB, fieldC;labelC;paletteC;specialC, newA, newB, fieldC1, fieldD, fieldD1', $GLOBALS['TCA'][$table]['types']['typeB']['showitem']);
381 }
382
383 /**
384 * Tests whether fields can be add to a TCA type before existing ones
385 *
386 * @test
387 * @see ExtensionManagementUtility::addToAllTCAtypes()
388 */
389 public function canAddFieldsToTCATypeBeforeExistingOnes() {
390 $table = $this->getUniqueId('tx_coretest_table');
391 $GLOBALS['TCA'] = $this->generateTCAForTable($table);
392 ExtensionManagementUtility::addToAllTCAtypes($table, 'newA, newA, newB, fieldA', 'typeA', 'before:fieldD');
393 // Checking typeA:
394 $this->assertEquals('fieldA, fieldB, fieldC;labelC;paletteC;specialC, fieldC1, newA, newB, fieldD, fieldD1', $GLOBALS['TCA'][$table]['types']['typeA']['showitem']);
395 // Checking typeB:
396 $this->assertEquals('fieldA, fieldB, fieldC;labelC;paletteC;specialC, fieldC1, fieldD, fieldD1', $GLOBALS['TCA'][$table]['types']['typeB']['showitem']);
397 }
398
399 /**
400 * Tests whether fields can be add to a TCA type after existing ones
401 *
402 * @test
403 * @see ExtensionManagementUtility::addToAllTCAtypes()
404 */
405 public function canAddFieldsToTCATypeAfterExistingOnes() {
406 $table = $this->getUniqueId('tx_coretest_table');
407 $GLOBALS['TCA'] = $this->generateTCAForTable($table);
408 ExtensionManagementUtility::addToAllTCAtypes($table, 'newA, newA, newB, fieldA', 'typeA', 'after:fieldC');
409 // Checking typeA:
410 $this->assertEquals('fieldA, fieldB, fieldC;labelC;paletteC;specialC, newA, newB, fieldC1, fieldD, fieldD1', $GLOBALS['TCA'][$table]['types']['typeA']['showitem']);
411 // Checking typeB:
412 $this->assertEquals('fieldA, fieldB, fieldC;labelC;paletteC;specialC, fieldC1, fieldD, fieldD1', $GLOBALS['TCA'][$table]['types']['typeB']['showitem']);
413 }
414
415 /**
416 * Test wheter replacing other TCA fields works as promissed
417 *
418 * @test
419 * @see ExtensionManagementUtility::addFieldsToAllPalettesOfField()
420 */
421 public function canAddFieldsToTCATypeAndReplaceExistingOnes() {
422 $table = $this->getUniqueId('tx_coretest_table');
423 $GLOBALS['TCA'] = $this->generateTCAForTable($table);
424 $typesBefore = $GLOBALS['TCA'][$table]['types'];
425 ExtensionManagementUtility::addToAllTCAtypes($table, 'fieldZ', '', 'replace:fieldX');
426 $this->assertEquals($typesBefore, $GLOBALS['TCA'][$table]['types'], 'It\'s wrong that the "types" array changes here - the replaced field is only on palettes');
427 // unchanged because the palette is not used
428 $this->assertEquals('fieldX, fieldX1, fieldY', $GLOBALS['TCA'][$table]['palettes']['paletteA']['showitem']);
429 // unchanged because the palette is not used
430 $this->assertEquals('fieldX, fieldX1, fieldY', $GLOBALS['TCA'][$table]['palettes']['paletteB']['showitem']);
431 $this->assertEquals('fieldZ, fieldX1, fieldY', $GLOBALS['TCA'][$table]['palettes']['paletteC']['showitem']);
432 $this->assertEquals('fieldZ, fieldX1, fieldY', $GLOBALS['TCA'][$table]['palettes']['paletteD']['showitem']);
433 }
434
435 ///////////////////////////////////////////////////
436 // Tests concerning addFieldsToAllPalettesOfField
437 ///////////////////////////////////////////////////
438 /**
439 * Tests whether fields can be added to a palette before existing elements.
440 *
441 * @test
442 * @see ExtensionManagementUtility::addFieldsToPalette()
443 */
444 public function canAddFieldsToPaletteBeforeExistingOnes() {
445 $table = $this->getUniqueId('tx_coretest_table');
446 $GLOBALS['TCA'] = $this->generateTCAForTable($table);
447 ExtensionManagementUtility::addFieldsToPalette($table, 'paletteA', 'newA, newA, newB, fieldX', 'before:fieldY');
448 $this->assertEquals('fieldX, fieldX1, newA, newB, fieldY', $GLOBALS['TCA'][$table]['palettes']['paletteA']['showitem']);
449 }
450
451 /**
452 * Tests whether fields can be added to a palette after existing elements.
453 *
454 * @test
455 * @see ExtensionManagementUtility::addFieldsToPalette()
456 */
457 public function canAddFieldsToPaletteAfterExistingOnes() {
458 $table = $this->getUniqueId('tx_coretest_table');
459 $GLOBALS['TCA'] = $this->generateTCAForTable($table);
460 ExtensionManagementUtility::addFieldsToPalette($table, 'paletteA', 'newA, newA, newB, fieldX', 'after:fieldX');
461 $this->assertEquals('fieldX, newA, newB, fieldX1, fieldY', $GLOBALS['TCA'][$table]['palettes']['paletteA']['showitem']);
462 }
463
464 /**
465 * Tests whether fields can be added to a palette after a not existing elements.
466 *
467 * @test
468 * @see ExtensionManagementUtility::addFieldsToPalette()
469 */
470 public function canAddFieldsToPaletteAfterNotExistingOnes() {
471 $table = $this->getUniqueId('tx_coretest_table');
472 $GLOBALS['TCA'] = $this->generateTCAForTable($table);
473 ExtensionManagementUtility::addFieldsToPalette($table, 'paletteA', 'newA, newA, newB, fieldX', 'after:' . $this->getUniqueId('notExisting'));
474 $this->assertEquals('fieldX, fieldX1, fieldY, newA, newB', $GLOBALS['TCA'][$table]['palettes']['paletteA']['showitem']);
475 }
476
477 /**
478 * @return array
479 */
480 public function removeDuplicatesForInsertionRemovesDuplicatesDataProvider() {
481 return array(
482 'Simple' => array(
483 'field_b, field_d, field_c',
484 'field_a, field_b, field_c',
485 'field_d'
486 ),
487 'with linebreaks' => array(
488 'field_b, --linebreak--, field_d, --linebreak--, field_c',
489 'field_a, field_b, field_c',
490 '--linebreak--, field_d, --linebreak--'
491 ),
492 'with linebreaks in list and insertion list' => array(
493 'field_b, --linebreak--, field_d, --linebreak--, field_c',
494 'field_a, field_b, --linebreak--, field_c',
495 '--linebreak--, field_d, --linebreak--'
496 ),
497 'with configuration in list' => array(
498 'field_b, field_d, field_c;;;4-4-4',
499 'field_a, field_b;;;;2-2-2, field_c;;;;3-3-3',
500 'field_d',
501 ),
502 'with configuration in list and insertion list' => array(
503 'field_b, field_d;;;3-3-3, field_c;;;4-4-4',
504 'field_a, field_b;;;;2-2-2, field_c;;;;3-3-3',
505 'field_d;;;3-3-3',
506 ),
507 );
508 }
509
510 /**
511 * @test
512 * @dataProvider removeDuplicatesForInsertionRemovesDuplicatesDataProvider
513 * @param $insertionList
514 * @param $list
515 * @param $expected
516 */
517 public function removeDuplicatesForInsertionRemovesDuplicates($insertionList, $list, $expected) {
518 $result = ExtensionManagementUtilityAccessibleProxy::removeDuplicatesForInsertion($insertionList, $list);
519 $this->assertSame($expected, $result);
520 }
521
522 /**
523 * Tests whether fields can be added to all palettes of a regular field before existing ones.
524 *
525 * @test
526 * @see ExtensionManagementUtility::addFieldsToAllPalettesOfField()
527 */
528 public function canAddFieldsToAllPalettesOfFieldBeforeExistingOnes() {
529 $table = $this->getUniqueId('tx_coretest_table');
530 $GLOBALS['TCA'] = $this->generateTCAForTable($table);
531 ExtensionManagementUtility::addFieldsToAllPalettesOfField($table, 'fieldC', 'newA, newA, newB, fieldX', 'before:fieldY');
532 $this->assertEquals('fieldX, fieldX1, fieldY', $GLOBALS['TCA'][$table]['palettes']['paletteA']['showitem']);
533 $this->assertEquals('fieldX, fieldX1, fieldY', $GLOBALS['TCA'][$table]['palettes']['paletteB']['showitem']);
534 $this->assertEquals('fieldX, fieldX1, newA, newB, fieldY', $GLOBALS['TCA'][$table]['palettes']['paletteC']['showitem']);
535 $this->assertEquals('fieldX, fieldX1, newA, newB, fieldY', $GLOBALS['TCA'][$table]['palettes']['paletteD']['showitem']);
536 }
537
538 /**
539 * Tests whether fields can be added to all palettes of a regular field after existing ones.
540 *
541 * @test
542 * @see ExtensionManagementUtility::addFieldsToAllPalettesOfField()
543 */
544 public function canAddFieldsToAllPalettesOfFieldAfterExistingOnes() {
545 $table = $this->getUniqueId('tx_coretest_table');
546 $GLOBALS['TCA'] = $this->generateTCAForTable($table);
547 ExtensionManagementUtility::addFieldsToAllPalettesOfField($table, 'fieldC', 'newA, newA, newB, fieldX', 'after:fieldX');
548 $this->assertEquals('fieldX, fieldX1, fieldY', $GLOBALS['TCA'][$table]['palettes']['paletteA']['showitem']);
549 $this->assertEquals('fieldX, fieldX1, fieldY', $GLOBALS['TCA'][$table]['palettes']['paletteB']['showitem']);
550 $this->assertEquals('fieldX, newA, newB, fieldX1, fieldY', $GLOBALS['TCA'][$table]['palettes']['paletteC']['showitem']);
551 $this->assertEquals('fieldX, newA, newB, fieldX1, fieldY', $GLOBALS['TCA'][$table]['palettes']['paletteD']['showitem']);
552 }
553
554 /**
555 * Tests whether fields can be added to all palettes of a regular field after a not existing field.
556 *
557 * @test
558 * @see ExtensionManagementUtility::addFieldsToAllPalettesOfField()
559 */
560 public function canAddFieldsToAllPalettesOfFieldAfterNotExistingOnes() {
561 $table = $this->getUniqueId('tx_coretest_table');
562 $GLOBALS['TCA'] = $this->generateTCAForTable($table);
563 ExtensionManagementUtility::addFieldsToAllPalettesOfField($table, 'fieldC', 'newA, newA, newB, fieldX', 'after:' . $this->getUniqueId('notExisting'));
564 $this->assertEquals('fieldX, fieldX1, fieldY', $GLOBALS['TCA'][$table]['palettes']['paletteA']['showitem']);
565 $this->assertEquals('fieldX, fieldX1, fieldY', $GLOBALS['TCA'][$table]['palettes']['paletteB']['showitem']);
566 $this->assertEquals('fieldX, fieldX1, fieldY, newA, newB', $GLOBALS['TCA'][$table]['palettes']['paletteC']['showitem']);
567 $this->assertEquals('fieldX, fieldX1, fieldY, newA, newB', $GLOBALS['TCA'][$table]['palettes']['paletteD']['showitem']);
568 }
569
570 /**
571 * Tests whether fields are added to a new palette that did not exist before.
572 *
573 * @test
574 * @see ExtensionManagementUtility::addFieldsToAllPalettesOfField()
575 */
576 public function canAddFieldsToAllPalettesOfFieldWithoutPaletteExistingBefore() {
577 $table = $this->getUniqueId('tx_coretest_table');
578 $GLOBALS['TCA'] = $this->generateTCAForTable($table);
579 ExtensionManagementUtility::addFieldsToAllPalettesOfField($table, 'fieldA', 'newA, newA, newB, fieldX');
580 $this->assertEquals('fieldX, fieldX1, fieldY', $GLOBALS['TCA'][$table]['palettes']['paletteA']['showitem']);
581 $this->assertEquals('fieldX, fieldX1, fieldY', $GLOBALS['TCA'][$table]['palettes']['paletteB']['showitem']);
582 $this->assertEquals('fieldX, fieldX1, fieldY', $GLOBALS['TCA'][$table]['palettes']['paletteC']['showitem']);
583 $this->assertEquals('fieldX, fieldX1, fieldY', $GLOBALS['TCA'][$table]['palettes']['paletteD']['showitem']);
584 $this->assertEquals('newA, newB, fieldX', $GLOBALS['TCA'][$table]['palettes']['generatedFor-fieldA']['showitem']);
585 }
586
587 /**
588 * Data provider for executePositionedStringInsertionTrimsCorrectCharacters
589 * @return array
590 */
591 public function executePositionedStringInsertionTrimsCorrectCharactersDataProvider() {
592 return array(
593 'normal characters' => array(
594 'tr0',
595 'tr0',
596 ),
597 'newlines' => array(
598 "test\n",
599 'test',
600 ),
601 'newlines with carriage return' => array(
602 "test\r\n",
603 'test',
604 ),
605 'tabs' => array(
606 "test\t",
607 'test',
608 ),
609 'commas' => array(
610 "test,",
611 'test',
612 ),
613 'multiple commas with trailing spaces' => array(
614 "test,,\t, \r\n",
615 'test',
616 ),
617 );
618 }
619
620 /**
621 * @test
622 * @dataProvider executePositionedStringInsertionTrimsCorrectCharactersDataProvider
623 */
624 public function executePositionedStringInsertionTrimsCorrectCharacters($string, $expectedResult) {
625 $extensionManagementUtility = $this->getAccessibleMock(\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::class, array('dummy'));
626 $string = $extensionManagementUtility->_call('executePositionedStringInsertion', $string, '');
627 $this->assertEquals($expectedResult, $string);
628 }
629
630 /////////////////////////////////////////
631 // Tests concerning addTcaSelectItem
632 /////////////////////////////////////////
633 /**
634 * @test
635 * @expectedException \InvalidArgumentException
636 */
637 public function addTcaSelectItemThrowsExceptionIfTableIsNotOfTypeString() {
638 ExtensionManagementUtility::addTcaSelectItem(array(), 'foo', array());
639 }
640
641 /**
642 * @test
643 * @expectedException \InvalidArgumentException
644 */
645 public function addTcaSelectItemThrowsExceptionIfFieldIsNotOfTypeString() {
646 ExtensionManagementUtility::addTcaSelectItem('foo', array(), array());
647 }
648
649 /**
650 * @test
651 * @expectedException \InvalidArgumentException
652 */
653 public function addTcaSelectItemThrowsExceptionIfRelativeToFieldIsNotOfTypeString() {
654 ExtensionManagementUtility::addTcaSelectItem('foo', 'bar', array(), array());
655 }
656
657 /**
658 * @test
659 * @expectedException \InvalidArgumentException
660 */
661 public function addTcaSelectItemThrowsExceptionIfRelativePositionIsNotOfTypeString() {
662 ExtensionManagementUtility::addTcaSelectItem('foo', 'bar', array(), 'foo', array());
663 }
664
665 /**
666 * @test
667 * @expectedException \InvalidArgumentException
668 */
669 public function addTcaSelectItemThrowsExceptionIfRelativePositionIsNotOneOfValidKeywords() {
670 ExtensionManagementUtility::addTcaSelectItem('foo', 'bar', array(), 'foo', 'not allowed keyword');
671 }
672
673 /**
674 * @test
675 * @expectedException \RuntimeException
676 */
677 public function addTcaSelectItemThrowsExceptionIfFieldIsNotFoundInTca() {
678 $GLOBALS['TCA'] = array();
679 ExtensionManagementUtility::addTcaSelectItem('foo', 'bar', array());
680 }
681
682 /**
683 * Data provider for addTcaSelectItemInsertsItemAtSpecifiedPosition
684 */
685 public function addTcaSelectItemDataProvider() {
686 // Every array splits into:
687 // - relativeToField
688 // - relativePosition
689 // - expectedResultArray
690 return array(
691 'add at end of array' => array(
692 '',
693 '',
694 array(
695 0 => array('firstElement'),
696 1 => array('matchMe'),
697 2 => array('thirdElement'),
698 3 => array('insertedElement')
699 )
700 ),
701 'replace element' => array(
702 'matchMe',
703 'replace',
704 array(
705 0 => array('firstElement'),
706 1 => array('insertedElement'),
707 2 => array('thirdElement')
708 )
709 ),
710 'add element after' => array(
711 'matchMe',
712 'after',
713 array(
714 0 => array('firstElement'),
715 1 => array('matchMe'),
716 2 => array('insertedElement'),
717 3 => array('thirdElement')
718 )
719 ),
720 'add element before' => array(
721 'matchMe',
722 'before',
723 array(
724 0 => array('firstElement'),
725 1 => array('insertedElement'),
726 2 => array('matchMe'),
727 3 => array('thirdElement')
728 )
729 ),
730 'add at end if relative position was not found' => array(
731 'notExistingItem',
732 'after',
733 array(
734 0 => array('firstElement'),
735 1 => array('matchMe'),
736 2 => array('thirdElement'),
737 3 => array('insertedElement')
738 )
739 )
740 );
741 }
742
743 /**
744 * @test
745 * @dataProvider addTcaSelectItemDataProvider
746 */
747 public function addTcaSelectItemInsertsItemAtSpecifiedPosition($relativeToField, $relativePosition, $expectedResultArray) {
748 $GLOBALS['TCA'] = array(
749 'testTable' => array(
750 'columns' => array(
751 'testField' => array(
752 'config' => array(
753 'items' => array(
754 '0' => array('firstElement'),
755 '1' => array('matchMe'),
756 2 => array('thirdElement')
757 )
758 )
759 )
760 )
761 )
762 );
763 ExtensionManagementUtility::addTcaSelectItem('testTable', 'testField', array('insertedElement'), $relativeToField, $relativePosition);
764 $this->assertEquals($expectedResultArray, $GLOBALS['TCA']['testTable']['columns']['testField']['config']['items']);
765 }
766
767 /////////////////////////////////////////
768 // Tests concerning loadExtLocalconf
769 /////////////////////////////////////////
770 /**
771 * @test
772 */
773 public function loadExtLocalconfDoesNotReadFromCacheIfCachingIsDenied() {
774 $mockCacheManager = $this->getMock(\TYPO3\CMS\Core\Cache\CacheManager::class, array('getCache'));
775 $mockCacheManager->expects($this->never())->method('getCache');
776 ExtensionManagementUtilityAccessibleProxy::setCacheManager($mockCacheManager);
777 $GLOBALS['TYPO3_LOADED_EXT'] = new \TYPO3\CMS\Core\Compatibility\LoadedExtensionsArray($this->createMockPackageManagerWithMockPackage($this->getUniqueId()));
778 ExtensionManagementUtility::loadExtLocalconf(FALSE);
779 }
780
781 /**
782 * @test
783 */
784 public function loadExtLocalconfRequiresCacheFileIfExistsAndCachingIsAllowed() {
785 $mockCache = $this->getMock(
786 \TYPO3\CMS\Core\Cache\Frontend\AbstractFrontend::class,
787 array('getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove', 'flush', 'flushByTag', 'requireOnce'),
788 array(),
789 '',
790 FALSE
791 );
792 $mockCacheManager = $this->getMock(\TYPO3\CMS\Core\Cache\CacheManager::class, array('getCache'));
793 $mockCacheManager->expects($this->any())->method('getCache')->will($this->returnValue($mockCache));
794 ExtensionManagementUtilityAccessibleProxy::setCacheManager($mockCacheManager);
795 $mockCache->expects($this->any())->method('has')->will($this->returnValue(TRUE));
796 $mockCache->expects($this->once())->method('requireOnce');
797 ExtensionManagementUtility::loadExtLocalconf(TRUE);
798 }
799
800 /////////////////////////////////////////
801 // Tests concerning loadSingleExtLocalconfFiles
802 /////////////////////////////////////////
803 /**
804 * @test
805 * @expectedException \RuntimeException
806 */
807 public function loadSingleExtLocalconfFilesRequiresExtLocalconfFileRegisteredInGlobalTypo3LoadedExt() {
808 $extensionName = $this->getUniqueId('foo');
809 $packageManager = $this->createMockPackageManagerWithMockPackage($extensionName);
810 $extLocalconfLocation = $packageManager->getPackage($extensionName)->getPackagePath() . 'ext_localconf.php';
811 file_put_contents($extLocalconfLocation, "<?php\n\nthrow new RuntimeException('', 1340559079);\n\n?>");
812 $GLOBALS['TYPO3_LOADED_EXT'] = new \TYPO3\CMS\Core\Compatibility\LoadedExtensionsArray($packageManager);
813 ExtensionManagementUtilityAccessibleProxy::loadSingleExtLocalconfFiles();
814 }
815
816
817 /////////////////////////////////////////
818 // Tests concerning addModule
819 /////////////////////////////////////////
820
821 /**
822 * Data provider for addModule tests
823 * @return array
824 */
825 public function addModulePositionTestsDataProvider() {
826 return array(
827 'can add new main module if none exists' => array(
828 'top',
829 '',
830 'newModule'
831 ),
832 'can add new sub module if no position specified' => array(
833 '',
834 'some,modules',
835 'some,modules,newModule'
836 ),
837 'can add new sub module to top of module' => array(
838 'top',
839 'some,modules',
840 'newModule,some,modules'
841 ),
842 'can add new sub module if bottom of module' => array(
843 'bottom',
844 'some,modules',
845 'some,modules,newModule'
846 ),
847 'can add new sub module before specified sub module' => array(
848 'before:modules',
849 'some,modules',
850 'some,newModule,modules'
851 ),
852 'can add new sub module after specified sub module' => array(
853 'after:some',
854 'some,modules',
855 'some,newModule,modules'
856 ),
857 'can add new sub module at the bottom if specified sub module to add before does not exist' => array(
858 'before:modules',
859 'some,otherModules',
860 'some,otherModules,newModule'
861 ),
862 'can add new sub module at the bottom if specified sub module to add after does not exist' => array(
863 'after:some',
864 'someOther,modules',
865 'someOther,modules,newModule'
866 ),
867 );
868 }
869
870 /**
871 * @test
872 * @dataProvider addModulePositionTestsDataProvider
873 */
874 public function addModuleCanAddModule($position, $existing, $expected) {
875 $mainModule = 'foobar';
876 $subModule = 'newModule';
877 if ($existing) {
878 $GLOBALS['TBE_MODULES'][$mainModule] = $existing;
879 }
880
881 ExtensionManagementUtility::addModule($mainModule, $subModule, $position);
882
883 $this->assertTrue(isset($GLOBALS['TBE_MODULES'][$mainModule]));
884 $this->assertEquals($expected, $GLOBALS['TBE_MODULES'][$mainModule]);
885 }
886
887 /////////////////////////////////////////
888 // Tests concerning createExtLocalconfCacheEntry
889 /////////////////////////////////////////
890 /**
891 * @test
892 */
893 public function createExtLocalconfCacheEntryWritesCacheEntryWithContentOfLoadedExtensionExtLocalconf() {
894 $extensionName = $this->getUniqueId('foo');
895 $packageManager = $this->createMockPackageManagerWithMockPackage($extensionName);
896 $extLocalconfLocation = $packageManager->getPackage($extensionName)->getPackagePath() . 'ext_localconf.php';
897 $uniqueStringInLocalconf = $this->getUniqueId('foo');
898 file_put_contents($extLocalconfLocation, "<?php\n\n" . $uniqueStringInLocalconf . "\n\n?>");
899 $GLOBALS['TYPO3_LOADED_EXT'] = new \TYPO3\CMS\Core\Compatibility\LoadedExtensionsArray($packageManager);
900 $mockCache = $this->getMock(
901 \TYPO3\CMS\Core\Cache\Frontend\AbstractFrontend::class,
902 array('getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove', 'flush', 'flushByTag', 'requireOnce'),
903 array(),
904 '',
905 FALSE
906 );
907 $mockCacheManager = $this->getMock(\TYPO3\CMS\Core\Cache\CacheManager::class, array('getCache'));
908 $mockCacheManager->expects($this->any())->method('getCache')->will($this->returnValue($mockCache));
909 ExtensionManagementUtilityAccessibleProxy::setCacheManager($mockCacheManager);
910 $mockCache->expects($this->once())->method('set')->with($this->anything(), $this->stringContains($uniqueStringInLocalconf), $this->anything());
911 ExtensionManagementUtilityAccessibleProxy::createExtLocalconfCacheEntry();
912 }
913
914 /**
915 * @test
916 */
917 public function createExtLocalconfCacheEntryWritesCacheEntryWithExtensionContentOnlyIfExtLocalconfExists() {
918 $extensionName = $this->getUniqueId('foo');
919 $packageManager = $this->createMockPackageManagerWithMockPackage($extensionName);
920 $GLOBALS['TYPO3_LOADED_EXT'] = new \TYPO3\CMS\Core\Compatibility\LoadedExtensionsArray($packageManager);
921 $mockCache = $this->getMock(
922 \TYPO3\CMS\Core\Cache\Frontend\AbstractFrontend::class,
923 array('getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove', 'flush', 'flushByTag', 'requireOnce'),
924 array(),
925 '',
926 FALSE
927 );
928 $mockCacheManager = $this->getMock(\TYPO3\CMS\Core\Cache\CacheManager::class, array('getCache'));
929 $mockCacheManager->expects($this->any())->method('getCache')->will($this->returnValue($mockCache));
930 ExtensionManagementUtilityAccessibleProxy::setCacheManager($mockCacheManager);
931 $mockCache->expects($this->once())
932 ->method('set')
933 ->with($this->anything(), $this->logicalNot($this->stringContains($extensionName)), $this->anything());
934 ExtensionManagementUtilityAccessibleProxy::createExtLocalconfCacheEntry();
935 }
936
937 /**
938 * @test
939 */
940 public function createExtLocalconfCacheEntryWritesCacheEntryWithNoTags() {
941 $mockCache = $this->getMock(
942 \TYPO3\CMS\Core\Cache\Frontend\AbstractFrontend::class,
943 array('getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove', 'flush', 'flushByTag', 'requireOnce'),
944 array(),
945 '',
946 FALSE
947 );
948 $mockCacheManager = $this->getMock(\TYPO3\CMS\Core\Cache\CacheManager::class, array('getCache'));
949 $mockCacheManager->expects($this->any())->method('getCache')->will($this->returnValue($mockCache));
950 ExtensionManagementUtilityAccessibleProxy::setCacheManager($mockCacheManager);
951 $mockCache->expects($this->once())->method('set')->with($this->anything(), $this->anything(), $this->equalTo(array()));
952 $GLOBALS['TYPO3_LOADED_EXT'] = new \TYPO3\CMS\Core\Compatibility\LoadedExtensionsArray($this->createMockPackageManagerWithMockPackage($this->getUniqueId()));
953 ExtensionManagementUtilityAccessibleProxy::createExtLocalconfCacheEntry();
954 }
955
956 /////////////////////////////////////////
957 // Tests concerning getExtLocalconfCacheIdentifier
958 /////////////////////////////////////////
959 /**
960 * @test
961 */
962 public function getExtLocalconfCacheIdentifierCreatesSha1WithFourtyCharactersAndPrefix() {
963 $prefix = 'ext_localconf_';
964 $identifier = ExtensionManagementUtilityAccessibleProxy::getExtLocalconfCacheIdentifier();
965 $this->assertStringStartsWith($prefix, $identifier);
966 $sha1 = str_replace($prefix, '', $identifier);
967 $this->assertEquals(40, strlen($sha1));
968 }
969
970 /////////////////////////////////////////
971 // Tests concerning loadBaseTca
972 /////////////////////////////////////////
973
974 /**
975 * @test
976 */
977 public function loadBaseTcaDoesNotReadFromCacheIfCachingIsDenied() {
978 $mockCacheManager = $this->getMock(\TYPO3\CMS\Core\Cache\CacheManager::class, array('getCache'));
979 $mockCacheManager->expects($this->never())->method('getCache');
980 ExtensionManagementUtilityAccessibleProxy::setCacheManager($mockCacheManager);
981 ExtensionManagementUtilityAccessibleProxy::loadBaseTca(FALSE);
982 }
983
984 /**
985 * @test
986 */
987 public function loadBaseTcaRequiresCacheFileIfExistsAndCachingIsAllowed() {
988 $mockCache = $this->getMock(
989 \TYPO3\CMS\Core\Cache\Frontend\AbstractFrontend::class,
990 array('getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove', 'flush', 'flushByTag', 'requireOnce'),
991 array(),
992 '',
993 FALSE
994 );
995 $mockCacheManager = $this->getMock(\TYPO3\CMS\Core\Cache\CacheManager::class, array('getCache'));
996 $mockCacheManager->expects($this->any())->method('getCache')->will($this->returnValue($mockCache));
997 ExtensionManagementUtilityAccessibleProxy::setCacheManager($mockCacheManager);
998 $mockCache->expects($this->any())->method('has')->will($this->returnValue(TRUE));
999 $mockCache->expects($this->once())->method('get');
1000 ExtensionManagementUtilityAccessibleProxy::loadBaseTca(TRUE);
1001 }
1002
1003 /**
1004 * @test
1005 */
1006 public function loadBaseTcaCreatesCacheFileWithContentOfAnExtensionsConfigurationTcaPhpFile() {
1007 $extensionName = $this->getUniqueId('test_baseTca_');
1008 $packageManager = $this->createMockPackageManagerWithMockPackage($extensionName);
1009 $packagePath = $packageManager->getPackage($extensionName)->getPackagePath();
1010 GeneralUtility::mkdir($packagePath);
1011 GeneralUtility::mkdir($packagePath . 'Configuration/');
1012 GeneralUtility::mkdir($packagePath . 'Configuration/TCA/');
1013 $GLOBALS['TYPO3_LOADED_EXT'] = new \TYPO3\CMS\Core\Compatibility\LoadedExtensionsArray($packageManager);
1014 ExtensionManagementUtility::setPackageManager($packageManager);
1015 $uniqueTableName = $this->getUniqueId('table_name_');
1016 $uniqueStringInTableConfiguration = $this->getUniqueId('table_configuration_');
1017 $tableConfiguration = '<?php return array(\'foo\' => \'' . $uniqueStringInTableConfiguration . '\'); ?>';
1018 file_put_contents($packagePath . 'Configuration/TCA/' . $uniqueTableName . '.php', $tableConfiguration);
1019 $mockCache = $this->getMock(
1020 \TYPO3\CMS\Core\Cache\Frontend\AbstractFrontend::class,
1021 array('getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove', 'flush', 'flushByTag', 'requireOnce'),
1022 array(),
1023 '',
1024 FALSE
1025 );
1026 $mockCacheManager = $this->getMock(\TYPO3\CMS\Core\Cache\CacheManager::class, array('getCache'));
1027 $mockCacheManager->expects($this->any())->method('getCache')->will($this->returnValue($mockCache));
1028 ExtensionManagementUtilityAccessibleProxy::setCacheManager($mockCacheManager);
1029 $mockCache->expects($this->once())->method('has')->will($this->returnValue(FALSE));
1030 $mockCache->expects($this->once())->method('set')->with($this->anything(), $this->stringContains($uniqueStringInTableConfiguration), $this->anything());
1031 ExtensionManagementUtility::loadBaseTca(TRUE);
1032 }
1033
1034 /**
1035 * @test
1036 */
1037 public function loadBaseTcaWritesCacheEntryWithNoTags() {
1038 $mockCache = $this->getMock(
1039 \TYPO3\CMS\Core\Cache\Frontend\AbstractFrontend::class,
1040 array('getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove', 'flush', 'flushByTag', 'requireOnce'),
1041 array(),
1042 '',
1043 FALSE
1044 );
1045 $mockCacheManager = $this->getMock(\TYPO3\CMS\Core\Cache\CacheManager::class, array('getCache'));
1046 $mockCacheManager->expects($this->any())->method('getCache')->will($this->returnValue($mockCache));
1047 ExtensionManagementUtilityAccessibleProxy::setCacheManager($mockCacheManager);
1048 $mockCache->expects($this->once())->method('has')->will($this->returnValue(FALSE));
1049 $mockCache->expects($this->once())->method('set')->with($this->anything(), $this->anything(), $this->equalTo(array()));
1050 ExtensionManagementUtilityAccessibleProxy::loadBaseTca();
1051 }
1052
1053 /////////////////////////////////////////
1054 // Tests concerning getBaseTcaCacheIdentifier
1055 /////////////////////////////////////////
1056
1057 /**
1058 * @test
1059 */
1060 public function getBaseTcaCacheIdentifierCreatesSha1WithFourtyCharactersAndPrefix() {
1061 $prefix = 'tca_base_';
1062 $identifier = ExtensionManagementUtilityAccessibleProxy::getBaseTcaCacheIdentifier();
1063 $this->assertStringStartsWith($prefix, $identifier);
1064 $sha1 = str_replace($prefix, '', $identifier);
1065 $this->assertEquals(40, strlen($sha1));
1066 }
1067
1068 /////////////////////////////////////////
1069 // Tests concerning loadExtTables
1070 /////////////////////////////////////////
1071 /**
1072 * @test
1073 */
1074 public function loadExtTablesDoesNotReadFromCacheIfCachingIsDenied() {
1075 $mockCacheManager = $this->getMock(\TYPO3\CMS\Core\Cache\CacheManager::class, array('getCache'));
1076 $mockCacheManager->expects($this->never())->method('getCache');
1077 ExtensionManagementUtilityAccessibleProxy::setCacheManager($mockCacheManager);
1078 $GLOBALS['TYPO3_LOADED_EXT'] = new \TYPO3\CMS\Core\Compatibility\LoadedExtensionsArray($this->createMockPackageManagerWithMockPackage($this->getUniqueId()));
1079 ExtensionManagementUtility::loadExtLocalconf(FALSE);
1080 }
1081
1082 /**
1083 * @test
1084 */
1085 public function loadExtTablesRequiresCacheFileIfExistsAndCachingIsAllowed() {
1086 $mockCache = $this->getMock(
1087 \TYPO3\CMS\Core\Cache\Frontend\AbstractFrontend::class,
1088 array('getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove', 'flush', 'flushByTag', 'requireOnce'),
1089 array(),
1090 '',
1091 FALSE
1092 );
1093 $mockCacheManager = $this->getMock(\TYPO3\CMS\Core\Cache\CacheManager::class, array('getCache'));
1094 $mockCacheManager->expects($this->any())->method('getCache')->will($this->returnValue($mockCache));
1095 ExtensionManagementUtilityAccessibleProxy::setCacheManager($mockCacheManager);
1096 $mockCache->expects($this->any())->method('has')->will($this->returnValue(TRUE));
1097 $mockCache->expects($this->once())->method('requireOnce');
1098 // Reset the internal cache access tracking variable of extMgm
1099 // This method is only in the ProxyClass!
1100 ExtensionManagementUtilityAccessibleProxy::resetExtTablesWasReadFromCacheOnceBoolean();
1101 ExtensionManagementUtility::loadExtTables(TRUE);
1102 }
1103
1104 /////////////////////////////////////////
1105 // Tests concerning createExtTablesCacheEntry
1106 /////////////////////////////////////////
1107 /**
1108 * @test
1109 */
1110 public function createExtTablesCacheEntryWritesCacheEntryWithContentOfLoadedExtensionExtTables() {
1111 $extensionName = $this->getUniqueId('foo');
1112 $extTablesLocation = PATH_site . 'typo3temp/' . $this->getUniqueId('test_ext_tables') . '.php';
1113 $this->testFilesToDelete[] = $extTablesLocation;
1114 $uniqueStringInTables = $this->getUniqueId('foo');
1115 file_put_contents($extTablesLocation, "<?php\n\n$uniqueStringInTables\n\n?>");
1116 $GLOBALS['TYPO3_LOADED_EXT'] = array(
1117 $extensionName => array(
1118 'ext_tables.php' => $extTablesLocation
1119 )
1120 );
1121 $mockCache = $this->getMock(
1122 \TYPO3\CMS\Core\Cache\Frontend\AbstractFrontend::class,
1123 array('getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove', 'flush', 'flushByTag', 'requireOnce'),
1124 array(),
1125 '',
1126 FALSE
1127 );
1128 $mockCacheManager = $this->getMock(\TYPO3\CMS\Core\Cache\CacheManager::class, array('getCache'));
1129 $mockCacheManager->expects($this->any())->method('getCache')->will($this->returnValue($mockCache));
1130 ExtensionManagementUtilityAccessibleProxy::setCacheManager($mockCacheManager);
1131 $mockCache->expects($this->once())->method('set')->with($this->anything(), $this->stringContains($uniqueStringInTables), $this->anything());
1132 ExtensionManagementUtilityAccessibleProxy::createExtTablesCacheEntry();
1133 }
1134
1135 /**
1136 * @test
1137 */
1138 public function createExtTablesCacheEntryWritesCacheEntryWithExtensionContentOnlyIfExtTablesExists() {
1139 $extensionName = $this->getUniqueId('foo');
1140 $GLOBALS['TYPO3_LOADED_EXT'] = array(
1141 $extensionName => array(),
1142 );
1143 $mockCache = $this->getMock(
1144 \TYPO3\CMS\Core\Cache\Frontend\AbstractFrontend::class,
1145 array('getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove', 'flush', 'flushByTag', 'requireOnce'),
1146 array(),
1147 '',
1148 FALSE
1149 );
1150 $mockCacheManager = $this->getMock(\TYPO3\CMS\Core\Cache\CacheManager::class, array('getCache'));
1151 $mockCacheManager->expects($this->any())->method('getCache')->will($this->returnValue($mockCache));
1152 ExtensionManagementUtilityAccessibleProxy::setCacheManager($mockCacheManager);
1153 $mockCache->expects($this->once())
1154 ->method('set')
1155 ->with($this->anything(), $this->logicalNot($this->stringContains($extensionName)), $this->anything());
1156 ExtensionManagementUtilityAccessibleProxy::createExtTablesCacheEntry();
1157 }
1158
1159 /**
1160 * @test
1161 */
1162 public function createExtTablesCacheEntryWritesCacheEntryWithNoTags() {
1163 $mockCache = $this->getMock(
1164 \TYPO3\CMS\Core\Cache\Frontend\AbstractFrontend::class,
1165 array('getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove', 'flush', 'flushByTag', 'requireOnce'),
1166 array(),
1167 '',
1168 FALSE
1169 );
1170 $mockCacheManager = $this->getMock(\TYPO3\CMS\Core\Cache\CacheManager::class, array('getCache'));
1171 $mockCacheManager->expects($this->any())->method('getCache')->will($this->returnValue($mockCache));
1172 ExtensionManagementUtilityAccessibleProxy::setCacheManager($mockCacheManager);
1173 $mockCache->expects($this->once())->method('set')->with($this->anything(), $this->anything(), $this->equalTo(array()));
1174 $GLOBALS['TYPO3_LOADED_EXT'] = new \TYPO3\CMS\Core\Compatibility\LoadedExtensionsArray($this->createMockPackageManagerWithMockPackage($this->getUniqueId()));
1175 ExtensionManagementUtilityAccessibleProxy::createExtTablesCacheEntry();
1176 }
1177
1178 /////////////////////////////////////////
1179 // Tests concerning getExtTablesCacheIdentifier
1180 /////////////////////////////////////////
1181 /**
1182 * @test
1183 */
1184 public function getExtTablesCacheIdentifierCreatesSha1WithFourtyCharactersAndPrefix() {
1185 $prefix = 'ext_tables_';
1186 $identifier = ExtensionManagementUtilityAccessibleProxy::getExtTablesCacheIdentifier();
1187 $this->assertStringStartsWith($prefix, $identifier);
1188 $sha1 = str_replace($prefix, '', $identifier);
1189 $this->assertEquals(40, strlen($sha1));
1190 }
1191
1192 /////////////////////////////////////////
1193 // Tests concerning removeCacheFiles
1194 /////////////////////////////////////////
1195 /**
1196 * @test
1197 */
1198 public function removeCacheFilesFlushesSystemCaches() {
1199 $mockCacheManager = $this->getMock(\TYPO3\CMS\Core\Cache\CacheManager::class, array('flushCachesInGroup'));
1200 $mockCacheManager->expects($this->once())->method('flushCachesInGroup')->with('system');
1201 ExtensionManagementUtilityAccessibleProxy::setCacheManager($mockCacheManager);
1202 ExtensionManagementUtility::removeCacheFiles();
1203 }
1204
1205 /////////////////////////////////////////
1206 // Tests concerning loadNewTcaColumnsConfigFiles
1207 /////////////////////////////////////////
1208
1209 /**
1210 * @test
1211 * @expectedException \RuntimeException
1212 */
1213 public function loadNewTcaColumnsConfigFilesIncludesDefinedDynamicConfigFileIfNoColumnsExist() {
1214 $GLOBALS['TCA'] = array(
1215 'test' => array(
1216 'ctrl' => array(
1217 'dynamicConfigFile' => __DIR__ . '/Fixtures/RuntimeException.php'
1218 ),
1219 ),
1220 );
1221 ExtensionManagementUtility::loadNewTcaColumnsConfigFiles();
1222 }
1223
1224 /**
1225 * @test
1226 */
1227 public function loadNewTcaColumnsConfigFilesDoesNotIncludeFileIfColumnsExist() {
1228 $GLOBALS['TCA'] = array(
1229 'test' => array(
1230 'ctrl' => array(
1231 'dynamicConfigFile' => __DIR__ . '/Fixtures/RuntimeException.php'
1232 ),
1233 'columns' => array(
1234 'foo' => 'bar',
1235 ),
1236 ),
1237 );
1238 ExtensionManagementUtility::loadNewTcaColumnsConfigFiles();
1239 }
1240
1241 /////////////////////////////////////////
1242 // Tests concerning getExtensionVersion
1243 /////////////////////////////////////////
1244 /**
1245 * Data provider for negative getExtensionVersion() tests.
1246 *
1247 * @return array
1248 */
1249 public function getExtensionVersionFaultyDataProvider() {
1250 return array(
1251 array(''),
1252 array(0),
1253 array(new \stdClass()),
1254 array(TRUE)
1255 );
1256 }
1257
1258 /**
1259 * @test
1260 * @expectedException \InvalidArgumentException
1261 * @dataProvider getExtensionVersionFaultyDataProvider
1262 */
1263 public function getExtensionVersionForFaultyExtensionKeyThrowsException($key) {
1264 ExtensionManagementUtility::getExtensionVersion($key);
1265 }
1266
1267 /**
1268 * @test
1269 */
1270 public function getExtensionVersionForNotLoadedExtensionReturnsEmptyString() {
1271 ExtensionManagementUtility::clearExtensionKeyMap();
1272 $uniqueSuffix = $this->getUniqueId('test');
1273 $extensionKey = 'unloadedextension' . $uniqueSuffix;
1274 $this->assertEquals('', ExtensionManagementUtility::getExtensionVersion($extensionKey));
1275 }
1276
1277 /**
1278 * @test
1279 */
1280 public function getExtensionVersionForLoadedExtensionReturnsExtensionVersion() {
1281 ExtensionManagementUtility::clearExtensionKeyMap();
1282 $className = $this->getUniqueId('ExtensionManagementUtility');
1283 eval(
1284 'namespace ' . __NAMESPACE__ . ';' .
1285 'class ' . $className . ' extends \\TYPO3\\CMS\\Core\\Utility\\ExtensionManagementUtility {' .
1286 ' public static function isLoaded() {' .
1287 ' return TRUE;' .
1288 ' }' .
1289 '}'
1290 );
1291 $className = __NAMESPACE__ . '\\' . $className;
1292 ExtensionManagementUtility::clearExtensionKeyMap();
1293 $uniqueSuffix = $this->getUniqueId('test');
1294 $extensionKey = 'unloadedextension' . $uniqueSuffix;
1295 $packageMetaData = $this->getMock(\TYPO3\Flow\Package\MetaData::class, array('getVersion'), array($extensionKey));
1296 $packageMetaData->expects($this->any())->method('getVersion')->will($this->returnValue('1.2.3'));
1297 $packageManager = $this->createMockPackageManagerWithMockPackage($extensionKey, array('getPackagePath', 'getPackageKey', 'getPackageMetaData'));
1298 /** @var \PHPUnit_Framework_MockObject_MockObject $package */
1299 $package = $packageManager->getPackage($extensionKey);
1300 $package->expects($this->any())
1301 ->method('getPackageMetaData')
1302 ->will($this->returnValue($packageMetaData));
1303 ExtensionManagementUtility::setPackageManager($packageManager);
1304 $this->assertEquals('1.2.3', ExtensionManagementUtility::getExtensionVersion($extensionKey));
1305 }
1306
1307 /////////////////////////////////////////
1308 // Tests concerning loadExtension
1309 /////////////////////////////////////////
1310 /**
1311 * @test
1312 * @expectedException \RuntimeException
1313 */
1314 public function loadExtensionThrowsExceptionIfExtensionIsLoaded() {
1315 $extensionKey = $this->getUniqueId('test');
1316 $packageManager = $this->createMockPackageManagerWithMockPackage($extensionKey);
1317 ExtensionManagementUtility::setPackageManager($packageManager);
1318 ExtensionManagementUtility::loadExtension($extensionKey);
1319 }
1320
1321 /////////////////////////////////////////
1322 // Tests concerning unloadExtension
1323 /////////////////////////////////////////
1324 /**
1325 * @test
1326 * @expectedException \RuntimeException
1327 */
1328 public function unloadExtensionThrowsExceptionIfExtensionIsNotLoaded() {
1329 $packageName = $this->getUniqueId('foo');
1330 $packageManager = $this->getMock(\TYPO3\CMS\Core\Package\PackageManager::class, array('isPackageActive'));
1331 $packageManager->expects($this->once())
1332 ->method('isPackageActive')
1333 ->with($this->equalTo($packageName))
1334 ->will($this->returnValue(FALSE));
1335 ExtensionManagementUtility::setPackageManager($packageManager);
1336 ExtensionManagementUtility::unloadExtension($packageName);
1337 }
1338
1339 /**
1340 * @test
1341 */
1342 public function unloadExtensionCallsPackageManagerToDeactivatePackage() {
1343 $packageName = $this->getUniqueId('foo');
1344 $packageManager = $this->getMock(
1345 \TYPO3\CMS\Core\Package\PackageManager::class,
1346 array('isPackageActive', 'deactivatePackage')
1347 );
1348 $packageManager->expects($this->any())
1349 ->method('isPackageActive')
1350 ->will($this->returnValue(TRUE));
1351 $packageManager->expects($this->once())
1352 ->method('deactivatePackage')
1353 ->with($packageName);
1354 ExtensionManagementUtility::setPackageManager($packageManager);
1355 ExtensionManagementUtility::unloadExtension($packageName);
1356 }
1357
1358 /////////////////////////////////////////
1359 // Tests concerning makeCategorizable
1360 /////////////////////////////////////////
1361 /**
1362 * @test
1363 */
1364 public function doesMakeCategorizableCallsTheCategoryRegistryWithDefaultFieldName() {
1365 $extensionKey = $this->getUniqueId('extension');
1366 $tableName = $this->getUniqueId('table');
1367
1368 $registryMock = $this->getMock(\TYPO3\CMS\Core\Category\CategoryRegistry::class);
1369 $registryMock->expects($this->once())->method('add')->with($extensionKey, $tableName, 'categories', array());
1370 GeneralUtility::setSingletonInstance(\TYPO3\CMS\Core\Category\CategoryRegistry::class, $registryMock);
1371 ExtensionManagementUtility::makeCategorizable($extensionKey, $tableName);
1372 }
1373
1374 /**
1375 * @test
1376 */
1377 public function doesMakeCategorizableCallsTheCategoryRegistryWithFieldName() {
1378 $extensionKey = $this->getUniqueId('extension');
1379 $tableName = $this->getUniqueId('table');
1380 $fieldName = $this->getUniqueId('field');
1381
1382 $registryMock = $this->getMock(\TYPO3\CMS\Core\Category\CategoryRegistry::class);
1383 $registryMock->expects($this->once())->method('add')->with($extensionKey, $tableName, $fieldName, array());
1384 GeneralUtility::setSingletonInstance(\TYPO3\CMS\Core\Category\CategoryRegistry::class, $registryMock);
1385 ExtensionManagementUtility::makeCategorizable($extensionKey, $tableName, $fieldName);
1386 }
1387
1388 ///////////////////////////////
1389 // Tests concerning addPlugin
1390 ///////////////////////////////
1391
1392 /**
1393 * @test
1394 */
1395 public function addPluginSetsTcaCorrectlyForGivenExtkeyAsParameter() {
1396 $extKey = 'indexed_search';
1397 $GLOBALS['TYPO3_LOADED_EXT'] = array();
1398 $GLOBALS['TYPO3_LOADED_EXT'][$extKey]['ext_icon'] = 'foo.gif';
1399 $expectedTCA = array(
1400 array(
1401 'label',
1402 $extKey,
1403 'sysext/' . $extKey . '/foo.gif'
1404 )
1405 );
1406 $GLOBALS['TCA']['tt_content']['columns']['list_type']['config']['items'] = array();
1407 ExtensionManagementUtility::addPlugin(array('label', $extKey), 'list_type', $extKey);
1408 $this->assertEquals($expectedTCA, $GLOBALS['TCA']['tt_content']['columns']['list_type']['config']['items']);
1409 }
1410
1411 /**
1412 * @test
1413 */
1414 public function addPluginSetsTcaCorrectlyForGivenExtkeyAsGlobal() {
1415 $extKey = 'indexed_search';
1416 $GLOBALS['TYPO3_LOADED_EXT'] = array();
1417 $GLOBALS['TYPO3_LOADED_EXT'][$extKey]['ext_icon'] = 'foo.gif';
1418 $GLOBALS['_EXTKEY'] = $extKey;
1419 $expectedTCA = array(
1420 array(
1421 'label',
1422 $extKey,
1423 'sysext/' . $extKey . '/foo.gif'
1424 )
1425 );
1426 $GLOBALS['TCA']['tt_content']['columns']['list_type']['config']['items'] = array();
1427 ExtensionManagementUtility::addPlugin(array('label', $extKey));
1428 $this->assertEquals($expectedTCA, $GLOBALS['TCA']['tt_content']['columns']['list_type']['config']['items']);
1429 }
1430
1431 /**
1432 * @test
1433 * @expectedException \RuntimeException
1434 */
1435 public function addPluginThrowsExceptionForMissingExtkey() {
1436 ExtensionManagementUtility::addPlugin('test');
1437 }
1438
1439 }