[CLEANUP] Improve the @param/@return/@var PHPDoc
[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 public function setUp() {
40 $this->singletonInstances = GeneralUtility::getSingletonInstances();
41 $this->createAccessibleProxyClass();
42 $this->backUpPackageManager = ExtensionManagementUtilityAccessibleProxy::getPackageManager();
43 $this->singletonInstances = GeneralUtility::getSingletonInstances();
44 }
45
46 public 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(uniqid('foobar'), FALSE));
167 }
168
169 /**
170 * @test
171 * @expectedException \BadFunctionCallException
172 */
173 public function isLoadedThrowsExceptionIfExtensionIsNotLoaded() {
174 $this->assertFalse(ExtensionManagementUtility::isLoaded(uniqid('foobar'), TRUE));
175 }
176
177 ///////////////////////////////
178 // Tests concerning extPath
179 ///////////////////////////////
180 /**
181 * @test
182 * @expectedException \BadFunctionCallException
183 */
184 public function extPathThrowsExceptionIfExtensionIsNotLoaded() {
185 $packageName = uniqid('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 = uniqid('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 = uniqid('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 = uniqid('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 = uniqid('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 = uniqid('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 = uniqid('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 = uniqid('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 = uniqid('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 = uniqid('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 = uniqid('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 = uniqid('tx_coretest_table');
472 $GLOBALS['TCA'] = $this->generateTCAForTable($table);
473 ExtensionManagementUtility::addFieldsToPalette($table, 'paletteA', 'newA, newA, newB, fieldX', 'after:' . uniqid('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 );
498 }
499
500 /**
501 * @test
502 * @dataProvider removeDuplicatesForInsertionRemovesDuplicatesDataProvider
503 * @param $insertionList
504 * @param $list
505 * @param $expected
506 */
507 public function removeDuplicatesForInsertionRemovesDuplicates($insertionList, $list, $expected) {
508 $result = ExtensionManagementUtilityAccessibleProxy::removeDuplicatesForInsertion($insertionList, $list);
509 $this->assertSame($expected, $result);
510 }
511
512 /**
513 * Tests whether fields can be added to all palettes of a regular field before existing ones.
514 *
515 * @test
516 * @see ExtensionManagementUtility::addFieldsToAllPalettesOfField()
517 */
518 public function canAddFieldsToAllPalettesOfFieldBeforeExistingOnes() {
519 $table = uniqid('tx_coretest_table');
520 $GLOBALS['TCA'] = $this->generateTCAForTable($table);
521 ExtensionManagementUtility::addFieldsToAllPalettesOfField($table, 'fieldC', 'newA, newA, newB, fieldX', 'before:fieldY');
522 $this->assertEquals('fieldX, fieldX1, fieldY', $GLOBALS['TCA'][$table]['palettes']['paletteA']['showitem']);
523 $this->assertEquals('fieldX, fieldX1, fieldY', $GLOBALS['TCA'][$table]['palettes']['paletteB']['showitem']);
524 $this->assertEquals('fieldX, fieldX1, newA, newB, fieldY', $GLOBALS['TCA'][$table]['palettes']['paletteC']['showitem']);
525 $this->assertEquals('fieldX, fieldX1, newA, newB, fieldY', $GLOBALS['TCA'][$table]['palettes']['paletteD']['showitem']);
526 }
527
528 /**
529 * Tests whether fields can be added to all palettes of a regular field after existing ones.
530 *
531 * @test
532 * @see ExtensionManagementUtility::addFieldsToAllPalettesOfField()
533 */
534 public function canAddFieldsToAllPalettesOfFieldAfterExistingOnes() {
535 $table = uniqid('tx_coretest_table');
536 $GLOBALS['TCA'] = $this->generateTCAForTable($table);
537 ExtensionManagementUtility::addFieldsToAllPalettesOfField($table, 'fieldC', 'newA, newA, newB, fieldX', 'after:fieldX');
538 $this->assertEquals('fieldX, fieldX1, fieldY', $GLOBALS['TCA'][$table]['palettes']['paletteA']['showitem']);
539 $this->assertEquals('fieldX, fieldX1, fieldY', $GLOBALS['TCA'][$table]['palettes']['paletteB']['showitem']);
540 $this->assertEquals('fieldX, newA, newB, fieldX1, fieldY', $GLOBALS['TCA'][$table]['palettes']['paletteC']['showitem']);
541 $this->assertEquals('fieldX, newA, newB, fieldX1, fieldY', $GLOBALS['TCA'][$table]['palettes']['paletteD']['showitem']);
542 }
543
544 /**
545 * Tests whether fields can be added to all palettes of a regular field after a not existing field.
546 *
547 * @test
548 * @see ExtensionManagementUtility::addFieldsToAllPalettesOfField()
549 */
550 public function canAddFieldsToAllPalettesOfFieldAfterNotExistingOnes() {
551 $table = uniqid('tx_coretest_table');
552 $GLOBALS['TCA'] = $this->generateTCAForTable($table);
553 ExtensionManagementUtility::addFieldsToAllPalettesOfField($table, 'fieldC', 'newA, newA, newB, fieldX', 'after:' . uniqid('notExisting'));
554 $this->assertEquals('fieldX, fieldX1, fieldY', $GLOBALS['TCA'][$table]['palettes']['paletteA']['showitem']);
555 $this->assertEquals('fieldX, fieldX1, fieldY', $GLOBALS['TCA'][$table]['palettes']['paletteB']['showitem']);
556 $this->assertEquals('fieldX, fieldX1, fieldY, newA, newB', $GLOBALS['TCA'][$table]['palettes']['paletteC']['showitem']);
557 $this->assertEquals('fieldX, fieldX1, fieldY, newA, newB', $GLOBALS['TCA'][$table]['palettes']['paletteD']['showitem']);
558 }
559
560 /**
561 * Tests whether fields are added to a new palette that did not exist before.
562 *
563 * @test
564 * @see ExtensionManagementUtility::addFieldsToAllPalettesOfField()
565 */
566 public function canAddFieldsToAllPalettesOfFieldWithoutPaletteExistingBefore() {
567 $table = uniqid('tx_coretest_table');
568 $GLOBALS['TCA'] = $this->generateTCAForTable($table);
569 ExtensionManagementUtility::addFieldsToAllPalettesOfField($table, 'fieldA', 'newA, newA, newB, fieldX');
570 $this->assertEquals('fieldX, fieldX1, fieldY', $GLOBALS['TCA'][$table]['palettes']['paletteA']['showitem']);
571 $this->assertEquals('fieldX, fieldX1, fieldY', $GLOBALS['TCA'][$table]['palettes']['paletteB']['showitem']);
572 $this->assertEquals('fieldX, fieldX1, fieldY', $GLOBALS['TCA'][$table]['palettes']['paletteC']['showitem']);
573 $this->assertEquals('fieldX, fieldX1, fieldY', $GLOBALS['TCA'][$table]['palettes']['paletteD']['showitem']);
574 $this->assertEquals('newA, newB, fieldX', $GLOBALS['TCA'][$table]['palettes']['generatedFor-fieldA']['showitem']);
575 }
576
577 /**
578 * Data provider for executePositionedStringInsertionTrimsCorrectCharacters
579 * @return array
580 */
581 public function executePositionedStringInsertionTrimsCorrectCharactersDataProvider() {
582 return array(
583 'normal characters' => array(
584 'tr0',
585 'tr0',
586 ),
587 'newlines' => array(
588 "test\n",
589 'test',
590 ),
591 'newlines with carriage return' => array(
592 "test\r\n",
593 'test',
594 ),
595 'tabs' => array(
596 "test\t",
597 'test',
598 ),
599 'commas' => array(
600 "test,",
601 'test',
602 ),
603 'multiple commas with trailing spaces' => array(
604 "test,,\t, \r\n",
605 'test',
606 ),
607 );
608 }
609
610 /**
611 * @test
612 * @dataProvider executePositionedStringInsertionTrimsCorrectCharactersDataProvider
613 */
614 public function executePositionedStringInsertionTrimsCorrectCharacters($string, $expectedResult) {
615 $extensionManagementUtility = $this->getAccessibleMock(\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::class, array('dummy'));
616 $string = $extensionManagementUtility->_call('executePositionedStringInsertion', $string, '');
617 $this->assertEquals($expectedResult, $string);
618 }
619
620 /////////////////////////////////////////
621 // Tests concerning addTcaSelectItem
622 /////////////////////////////////////////
623 /**
624 * @test
625 * @expectedException \InvalidArgumentException
626 */
627 public function addTcaSelectItemThrowsExceptionIfTableIsNotOfTypeString() {
628 ExtensionManagementUtility::addTcaSelectItem(array(), 'foo', array());
629 }
630
631 /**
632 * @test
633 * @expectedException \InvalidArgumentException
634 */
635 public function addTcaSelectItemThrowsExceptionIfFieldIsNotOfTypeString() {
636 ExtensionManagementUtility::addTcaSelectItem('foo', array(), array());
637 }
638
639 /**
640 * @test
641 * @expectedException \InvalidArgumentException
642 */
643 public function addTcaSelectItemThrowsExceptionIfRelativeToFieldIsNotOfTypeString() {
644 ExtensionManagementUtility::addTcaSelectItem('foo', 'bar', array(), array());
645 }
646
647 /**
648 * @test
649 * @expectedException \InvalidArgumentException
650 */
651 public function addTcaSelectItemThrowsExceptionIfRelativePositionIsNotOfTypeString() {
652 ExtensionManagementUtility::addTcaSelectItem('foo', 'bar', array(), 'foo', array());
653 }
654
655 /**
656 * @test
657 * @expectedException \InvalidArgumentException
658 */
659 public function addTcaSelectItemThrowsExceptionIfRelativePositionIsNotOneOfValidKeywords() {
660 ExtensionManagementUtility::addTcaSelectItem('foo', 'bar', array(), 'foo', 'not allowed keyword');
661 }
662
663 /**
664 * @test
665 * @expectedException \RuntimeException
666 */
667 public function addTcaSelectItemThrowsExceptionIfFieldIsNotFoundInTca() {
668 $GLOBALS['TCA'] = array();
669 ExtensionManagementUtility::addTcaSelectItem('foo', 'bar', array());
670 }
671
672 /**
673 * Data provider for addTcaSelectItemInsertsItemAtSpecifiedPosition
674 */
675 public function addTcaSelectItemDataProvider() {
676 // Every array splits into:
677 // - relativeToField
678 // - relativePosition
679 // - expectedResultArray
680 return array(
681 'add at end of array' => array(
682 '',
683 '',
684 array(
685 0 => array('firstElement'),
686 1 => array('matchMe'),
687 2 => array('thirdElement'),
688 3 => array('insertedElement')
689 )
690 ),
691 'replace element' => array(
692 'matchMe',
693 'replace',
694 array(
695 0 => array('firstElement'),
696 1 => array('insertedElement'),
697 2 => array('thirdElement')
698 )
699 ),
700 'add element after' => array(
701 'matchMe',
702 'after',
703 array(
704 0 => array('firstElement'),
705 1 => array('matchMe'),
706 2 => array('insertedElement'),
707 3 => array('thirdElement')
708 )
709 ),
710 'add element before' => array(
711 'matchMe',
712 'before',
713 array(
714 0 => array('firstElement'),
715 1 => array('insertedElement'),
716 2 => array('matchMe'),
717 3 => array('thirdElement')
718 )
719 ),
720 'add at end if relative position was not found' => array(
721 'notExistingItem',
722 'after',
723 array(
724 0 => array('firstElement'),
725 1 => array('matchMe'),
726 2 => array('thirdElement'),
727 3 => array('insertedElement')
728 )
729 )
730 );
731 }
732
733 /**
734 * @test
735 * @dataProvider addTcaSelectItemDataProvider
736 */
737 public function addTcaSelectItemInsertsItemAtSpecifiedPosition($relativeToField, $relativePosition, $expectedResultArray) {
738 $GLOBALS['TCA'] = array(
739 'testTable' => array(
740 'columns' => array(
741 'testField' => array(
742 'config' => array(
743 'items' => array(
744 '0' => array('firstElement'),
745 '1' => array('matchMe'),
746 2 => array('thirdElement')
747 )
748 )
749 )
750 )
751 )
752 );
753 ExtensionManagementUtility::addTcaSelectItem('testTable', 'testField', array('insertedElement'), $relativeToField, $relativePosition);
754 $this->assertEquals($expectedResultArray, $GLOBALS['TCA']['testTable']['columns']['testField']['config']['items']);
755 }
756
757 /////////////////////////////////////////
758 // Tests concerning loadExtLocalconf
759 /////////////////////////////////////////
760 /**
761 * @test
762 */
763 public function loadExtLocalconfDoesNotReadFromCacheIfCachingIsDenied() {
764 $mockCacheManager = $this->getMock(\TYPO3\CMS\Core\Cache\CacheManager::class, array('getCache'));
765 $mockCacheManager->expects($this->never())->method('getCache');
766 ExtensionManagementUtilityAccessibleProxy::setCacheManager($mockCacheManager);
767 $GLOBALS['TYPO3_LOADED_EXT'] = new \TYPO3\CMS\Core\Compatibility\LoadedExtensionsArray($this->createMockPackageManagerWithMockPackage(uniqid()));
768 ExtensionManagementUtility::loadExtLocalconf(FALSE);
769 }
770
771 /**
772 * @test
773 */
774 public function loadExtLocalconfRequiresCacheFileIfExistsAndCachingIsAllowed() {
775 $mockCache = $this->getMock(
776 \TYPO3\CMS\Core\Cache\Frontend\AbstractFrontend::class,
777 array('getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove', 'flush', 'flushByTag', 'requireOnce'),
778 array(),
779 '',
780 FALSE
781 );
782 $mockCacheManager = $this->getMock(\TYPO3\CMS\Core\Cache\CacheManager::class, array('getCache'));
783 $mockCacheManager->expects($this->any())->method('getCache')->will($this->returnValue($mockCache));
784 ExtensionManagementUtilityAccessibleProxy::setCacheManager($mockCacheManager);
785 $mockCache->expects($this->any())->method('has')->will($this->returnValue(TRUE));
786 $mockCache->expects($this->once())->method('requireOnce');
787 ExtensionManagementUtility::loadExtLocalconf(TRUE);
788 }
789
790 /////////////////////////////////////////
791 // Tests concerning loadSingleExtLocalconfFiles
792 /////////////////////////////////////////
793 /**
794 * @test
795 * @expectedException \RuntimeException
796 */
797 public function loadSingleExtLocalconfFilesRequiresExtLocalconfFileRegisteredInGlobalTypo3LoadedExt() {
798 $extensionName = uniqid('foo');
799 $packageManager = $this->createMockPackageManagerWithMockPackage($extensionName);
800 $extLocalconfLocation = $packageManager->getPackage($extensionName)->getPackagePath() . 'ext_localconf.php';
801 file_put_contents($extLocalconfLocation, "<?php\n\nthrow new RuntimeException('', 1340559079);\n\n?>");
802 $GLOBALS['TYPO3_LOADED_EXT'] = new \TYPO3\CMS\Core\Compatibility\LoadedExtensionsArray($packageManager);
803 ExtensionManagementUtilityAccessibleProxy::loadSingleExtLocalconfFiles();
804 }
805
806
807 /////////////////////////////////////////
808 // Tests concerning addModule
809 /////////////////////////////////////////
810
811 /**
812 * Data provider for addModule tests
813 * @return array
814 */
815 public function addModulePositionTestsDataProvider() {
816 return array(
817 'can add new main module if none exists' => array(
818 'top',
819 '',
820 'newModule'
821 ),
822 'can add new sub module if no position specified' => array(
823 '',
824 'some,modules',
825 'some,modules,newModule'
826 ),
827 'can add new sub module to top of module' => array(
828 'top',
829 'some,modules',
830 'newModule,some,modules'
831 ),
832 'can add new sub module if bottom of module' => array(
833 'bottom',
834 'some,modules',
835 'some,modules,newModule'
836 ),
837 'can add new sub module before specified sub module' => array(
838 'before:modules',
839 'some,modules',
840 'some,newModule,modules'
841 ),
842 'can add new sub module after specified sub module' => array(
843 'after:some',
844 'some,modules',
845 'some,newModule,modules'
846 ),
847 'can add new sub module at the bottom if specified sub module to add before does not exist' => array(
848 'before:modules',
849 'some,otherModules',
850 'some,otherModules,newModule'
851 ),
852 'can add new sub module at the bottom if specified sub module to add after does not exist' => array(
853 'after:some',
854 'someOther,modules',
855 'someOther,modules,newModule'
856 ),
857 );
858 }
859
860 /**
861 * @test
862 * @dataProvider addModulePositionTestsDataProvider
863 */
864 public function addModuleCanAddModule($position, $existing, $expected) {
865 $mainModule = 'foobar';
866 $subModule = 'newModule';
867 if ($existing) {
868 $GLOBALS['TBE_MODULES'][$mainModule] = $existing;
869 }
870
871 ExtensionManagementUtility::addModule($mainModule, $subModule, $position);
872
873 $this->assertTrue(isset($GLOBALS['TBE_MODULES'][$mainModule]));
874 $this->assertEquals($expected, $GLOBALS['TBE_MODULES'][$mainModule]);
875 }
876
877 /////////////////////////////////////////
878 // Tests concerning createExtLocalconfCacheEntry
879 /////////////////////////////////////////
880 /**
881 * @test
882 */
883 public function createExtLocalconfCacheEntryWritesCacheEntryWithContentOfLoadedExtensionExtLocalconf() {
884 $extensionName = uniqid('foo');
885 $packageManager = $this->createMockPackageManagerWithMockPackage($extensionName);
886 $extLocalconfLocation = $packageManager->getPackage($extensionName)->getPackagePath() . 'ext_localconf.php';
887 $uniqueStringInLocalconf = uniqid('foo');
888 file_put_contents($extLocalconfLocation, "<?php\n\n" . $uniqueStringInLocalconf . "\n\n?>");
889 $GLOBALS['TYPO3_LOADED_EXT'] = new \TYPO3\CMS\Core\Compatibility\LoadedExtensionsArray($packageManager);
890 $mockCache = $this->getMock(
891 \TYPO3\CMS\Core\Cache\Frontend\AbstractFrontend::class,
892 array('getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove', 'flush', 'flushByTag', 'requireOnce'),
893 array(),
894 '',
895 FALSE
896 );
897 $mockCacheManager = $this->getMock(\TYPO3\CMS\Core\Cache\CacheManager::class, array('getCache'));
898 $mockCacheManager->expects($this->any())->method('getCache')->will($this->returnValue($mockCache));
899 ExtensionManagementUtilityAccessibleProxy::setCacheManager($mockCacheManager);
900 $mockCache->expects($this->once())->method('set')->with($this->anything(), $this->stringContains($uniqueStringInLocalconf), $this->anything());
901 ExtensionManagementUtilityAccessibleProxy::createExtLocalconfCacheEntry();
902 }
903
904 /**
905 * @test
906 */
907 public function createExtLocalconfCacheEntryWritesCacheEntryWithExtensionContentOnlyIfExtLocalconfExists() {
908 $extensionName = uniqid('foo');
909 $packageManager = $this->createMockPackageManagerWithMockPackage($extensionName);
910 $GLOBALS['TYPO3_LOADED_EXT'] = new \TYPO3\CMS\Core\Compatibility\LoadedExtensionsArray($packageManager);
911 $mockCache = $this->getMock(
912 \TYPO3\CMS\Core\Cache\Frontend\AbstractFrontend::class,
913 array('getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove', 'flush', 'flushByTag', 'requireOnce'),
914 array(),
915 '',
916 FALSE
917 );
918 $mockCacheManager = $this->getMock(\TYPO3\CMS\Core\Cache\CacheManager::class, array('getCache'));
919 $mockCacheManager->expects($this->any())->method('getCache')->will($this->returnValue($mockCache));
920 ExtensionManagementUtilityAccessibleProxy::setCacheManager($mockCacheManager);
921 $mockCache->expects($this->once())
922 ->method('set')
923 ->with($this->anything(), $this->logicalNot($this->stringContains($extensionName)), $this->anything());
924 ExtensionManagementUtilityAccessibleProxy::createExtLocalconfCacheEntry();
925 }
926
927 /**
928 * @test
929 */
930 public function createExtLocalconfCacheEntryWritesCacheEntryWithNoTags() {
931 $mockCache = $this->getMock(
932 \TYPO3\CMS\Core\Cache\Frontend\AbstractFrontend::class,
933 array('getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove', 'flush', 'flushByTag', 'requireOnce'),
934 array(),
935 '',
936 FALSE
937 );
938 $mockCacheManager = $this->getMock(\TYPO3\CMS\Core\Cache\CacheManager::class, array('getCache'));
939 $mockCacheManager->expects($this->any())->method('getCache')->will($this->returnValue($mockCache));
940 ExtensionManagementUtilityAccessibleProxy::setCacheManager($mockCacheManager);
941 $mockCache->expects($this->once())->method('set')->with($this->anything(), $this->anything(), $this->equalTo(array()));
942 $GLOBALS['TYPO3_LOADED_EXT'] = new \TYPO3\CMS\Core\Compatibility\LoadedExtensionsArray($this->createMockPackageManagerWithMockPackage(uniqid()));
943 ExtensionManagementUtilityAccessibleProxy::createExtLocalconfCacheEntry();
944 }
945
946 /////////////////////////////////////////
947 // Tests concerning getExtLocalconfCacheIdentifier
948 /////////////////////////////////////////
949 /**
950 * @test
951 */
952 public function getExtLocalconfCacheIdentifierCreatesSha1WithFourtyCharactersAndPrefix() {
953 $prefix = 'ext_localconf_';
954 $identifier = ExtensionManagementUtilityAccessibleProxy::getExtLocalconfCacheIdentifier();
955 $this->assertStringStartsWith($prefix, $identifier);
956 $sha1 = str_replace($prefix, '', $identifier);
957 $this->assertEquals(40, strlen($sha1));
958 }
959
960 /////////////////////////////////////////
961 // Tests concerning loadBaseTca
962 /////////////////////////////////////////
963
964 /**
965 * @test
966 */
967 public function loadBaseTcaDoesNotReadFromCacheIfCachingIsDenied() {
968 $mockCacheManager = $this->getMock(\TYPO3\CMS\Core\Cache\CacheManager::class, array('getCache'));
969 $mockCacheManager->expects($this->never())->method('getCache');
970 ExtensionManagementUtilityAccessibleProxy::setCacheManager($mockCacheManager);
971 ExtensionManagementUtilityAccessibleProxy::loadBaseTca(FALSE);
972 }
973
974 /**
975 * @test
976 */
977 public function loadBaseTcaRequiresCacheFileIfExistsAndCachingIsAllowed() {
978 $mockCache = $this->getMock(
979 \TYPO3\CMS\Core\Cache\Frontend\AbstractFrontend::class,
980 array('getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove', 'flush', 'flushByTag', 'requireOnce'),
981 array(),
982 '',
983 FALSE
984 );
985 $mockCacheManager = $this->getMock(\TYPO3\CMS\Core\Cache\CacheManager::class, array('getCache'));
986 $mockCacheManager->expects($this->any())->method('getCache')->will($this->returnValue($mockCache));
987 ExtensionManagementUtilityAccessibleProxy::setCacheManager($mockCacheManager);
988 $mockCache->expects($this->any())->method('has')->will($this->returnValue(TRUE));
989 $mockCache->expects($this->once())->method('get');
990 ExtensionManagementUtilityAccessibleProxy::loadBaseTca(TRUE);
991 }
992
993 /**
994 * @test
995 */
996 public function loadBaseTcaCreatesCacheFileWithContentOfAnExtensionsConfigurationTcaPhpFile() {
997 $extensionName = uniqid('test_baseTca_');
998 $packageManager = $this->createMockPackageManagerWithMockPackage($extensionName);
999 $packagePath = $packageManager->getPackage($extensionName)->getPackagePath();
1000 GeneralUtility::mkdir($packagePath);
1001 GeneralUtility::mkdir($packagePath . 'Configuration/');
1002 GeneralUtility::mkdir($packagePath . 'Configuration/TCA/');
1003 $GLOBALS['TYPO3_LOADED_EXT'] = new \TYPO3\CMS\Core\Compatibility\LoadedExtensionsArray($packageManager);
1004 ExtensionManagementUtility::setPackageManager($packageManager);
1005 $uniqueTableName = uniqid('table_name_');
1006 $uniqueStringInTableConfiguration = uniqid('table_configuration_');
1007 $tableConfiguration = '<?php return array(\'foo\' => \'' . $uniqueStringInTableConfiguration . '\'); ?>';
1008 file_put_contents($packagePath . 'Configuration/TCA/' . $uniqueTableName . '.php', $tableConfiguration);
1009 $mockCache = $this->getMock(
1010 \TYPO3\CMS\Core\Cache\Frontend\AbstractFrontend::class,
1011 array('getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove', 'flush', 'flushByTag', 'requireOnce'),
1012 array(),
1013 '',
1014 FALSE
1015 );
1016 $mockCacheManager = $this->getMock(\TYPO3\CMS\Core\Cache\CacheManager::class, array('getCache'));
1017 $mockCacheManager->expects($this->any())->method('getCache')->will($this->returnValue($mockCache));
1018 ExtensionManagementUtilityAccessibleProxy::setCacheManager($mockCacheManager);
1019 $mockCache->expects($this->once())->method('has')->will($this->returnValue(FALSE));
1020 $mockCache->expects($this->once())->method('set')->with($this->anything(), $this->stringContains($uniqueStringInTableConfiguration), $this->anything());
1021 ExtensionManagementUtility::loadBaseTca(TRUE);
1022 }
1023
1024 /**
1025 * @test
1026 */
1027 public function loadBaseTcaWritesCacheEntryWithNoTags() {
1028 $mockCache = $this->getMock(
1029 \TYPO3\CMS\Core\Cache\Frontend\AbstractFrontend::class,
1030 array('getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove', 'flush', 'flushByTag', 'requireOnce'),
1031 array(),
1032 '',
1033 FALSE
1034 );
1035 $mockCacheManager = $this->getMock(\TYPO3\CMS\Core\Cache\CacheManager::class, array('getCache'));
1036 $mockCacheManager->expects($this->any())->method('getCache')->will($this->returnValue($mockCache));
1037 ExtensionManagementUtilityAccessibleProxy::setCacheManager($mockCacheManager);
1038 $mockCache->expects($this->once())->method('has')->will($this->returnValue(FALSE));
1039 $mockCache->expects($this->once())->method('set')->with($this->anything(), $this->anything(), $this->equalTo(array()));
1040 ExtensionManagementUtilityAccessibleProxy::loadBaseTca();
1041 }
1042
1043 /////////////////////////////////////////
1044 // Tests concerning getBaseTcaCacheIdentifier
1045 /////////////////////////////////////////
1046
1047 /**
1048 * @test
1049 */
1050 public function getBaseTcaCacheIdentifierCreatesSha1WithFourtyCharactersAndPrefix() {
1051 $prefix = 'tca_base_';
1052 $identifier = ExtensionManagementUtilityAccessibleProxy::getBaseTcaCacheIdentifier();
1053 $this->assertStringStartsWith($prefix, $identifier);
1054 $sha1 = str_replace($prefix, '', $identifier);
1055 $this->assertEquals(40, strlen($sha1));
1056 }
1057
1058 /////////////////////////////////////////
1059 // Tests concerning loadExtTables
1060 /////////////////////////////////////////
1061 /**
1062 * @test
1063 */
1064 public function loadExtTablesDoesNotReadFromCacheIfCachingIsDenied() {
1065 $mockCacheManager = $this->getMock(\TYPO3\CMS\Core\Cache\CacheManager::class, array('getCache'));
1066 $mockCacheManager->expects($this->never())->method('getCache');
1067 ExtensionManagementUtilityAccessibleProxy::setCacheManager($mockCacheManager);
1068 $GLOBALS['TYPO3_LOADED_EXT'] = new \TYPO3\CMS\Core\Compatibility\LoadedExtensionsArray($this->createMockPackageManagerWithMockPackage(uniqid()));
1069 ExtensionManagementUtility::loadExtLocalconf(FALSE);
1070 }
1071
1072 /**
1073 * @test
1074 */
1075 public function loadExtTablesRequiresCacheFileIfExistsAndCachingIsAllowed() {
1076 $mockCache = $this->getMock(
1077 \TYPO3\CMS\Core\Cache\Frontend\AbstractFrontend::class,
1078 array('getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove', 'flush', 'flushByTag', 'requireOnce'),
1079 array(),
1080 '',
1081 FALSE
1082 );
1083 $mockCacheManager = $this->getMock(\TYPO3\CMS\Core\Cache\CacheManager::class, array('getCache'));
1084 $mockCacheManager->expects($this->any())->method('getCache')->will($this->returnValue($mockCache));
1085 ExtensionManagementUtilityAccessibleProxy::setCacheManager($mockCacheManager);
1086 $mockCache->expects($this->any())->method('has')->will($this->returnValue(TRUE));
1087 $mockCache->expects($this->once())->method('requireOnce');
1088 // Reset the internal cache access tracking variable of extMgm
1089 // This method is only in the ProxyClass!
1090 ExtensionManagementUtilityAccessibleProxy::resetExtTablesWasReadFromCacheOnceBoolean();
1091 ExtensionManagementUtility::loadExtTables(TRUE);
1092 }
1093
1094 /////////////////////////////////////////
1095 // Tests concerning createExtTablesCacheEntry
1096 /////////////////////////////////////////
1097 /**
1098 * @test
1099 */
1100 public function createExtTablesCacheEntryWritesCacheEntryWithContentOfLoadedExtensionExtTables() {
1101 $extensionName = uniqid('foo');
1102 $extTablesLocation = PATH_site . 'typo3temp/' . uniqid('test_ext_tables') . '.php';
1103 $this->testFilesToDelete[] = $extTablesLocation;
1104 $uniqueStringInTables = uniqid('foo');
1105 file_put_contents($extTablesLocation, "<?php\n\n$uniqueStringInTables\n\n?>");
1106 $GLOBALS['TYPO3_LOADED_EXT'] = array(
1107 $extensionName => array(
1108 'ext_tables.php' => $extTablesLocation
1109 )
1110 );
1111 $mockCache = $this->getMock(
1112 \TYPO3\CMS\Core\Cache\Frontend\AbstractFrontend::class,
1113 array('getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove', 'flush', 'flushByTag', 'requireOnce'),
1114 array(),
1115 '',
1116 FALSE
1117 );
1118 $mockCacheManager = $this->getMock(\TYPO3\CMS\Core\Cache\CacheManager::class, array('getCache'));
1119 $mockCacheManager->expects($this->any())->method('getCache')->will($this->returnValue($mockCache));
1120 ExtensionManagementUtilityAccessibleProxy::setCacheManager($mockCacheManager);
1121 $mockCache->expects($this->once())->method('set')->with($this->anything(), $this->stringContains($uniqueStringInTables), $this->anything());
1122 ExtensionManagementUtilityAccessibleProxy::createExtTablesCacheEntry();
1123 }
1124
1125 /**
1126 * @test
1127 */
1128 public function createExtTablesCacheEntryWritesCacheEntryWithExtensionContentOnlyIfExtTablesExists() {
1129 $extensionName = uniqid('foo');
1130 $GLOBALS['TYPO3_LOADED_EXT'] = array(
1131 $extensionName => array(),
1132 );
1133 $mockCache = $this->getMock(
1134 \TYPO3\CMS\Core\Cache\Frontend\AbstractFrontend::class,
1135 array('getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove', 'flush', 'flushByTag', 'requireOnce'),
1136 array(),
1137 '',
1138 FALSE
1139 );
1140 $mockCacheManager = $this->getMock(\TYPO3\CMS\Core\Cache\CacheManager::class, array('getCache'));
1141 $mockCacheManager->expects($this->any())->method('getCache')->will($this->returnValue($mockCache));
1142 ExtensionManagementUtilityAccessibleProxy::setCacheManager($mockCacheManager);
1143 $mockCache->expects($this->once())
1144 ->method('set')
1145 ->with($this->anything(), $this->logicalNot($this->stringContains($extensionName)), $this->anything());
1146 ExtensionManagementUtilityAccessibleProxy::createExtTablesCacheEntry();
1147 }
1148
1149 /**
1150 * @test
1151 */
1152 public function createExtTablesCacheEntryWritesCacheEntryWithNoTags() {
1153 $mockCache = $this->getMock(
1154 \TYPO3\CMS\Core\Cache\Frontend\AbstractFrontend::class,
1155 array('getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove', 'flush', 'flushByTag', 'requireOnce'),
1156 array(),
1157 '',
1158 FALSE
1159 );
1160 $mockCacheManager = $this->getMock(\TYPO3\CMS\Core\Cache\CacheManager::class, array('getCache'));
1161 $mockCacheManager->expects($this->any())->method('getCache')->will($this->returnValue($mockCache));
1162 ExtensionManagementUtilityAccessibleProxy::setCacheManager($mockCacheManager);
1163 $mockCache->expects($this->once())->method('set')->with($this->anything(), $this->anything(), $this->equalTo(array()));
1164 $GLOBALS['TYPO3_LOADED_EXT'] = new \TYPO3\CMS\Core\Compatibility\LoadedExtensionsArray($this->createMockPackageManagerWithMockPackage(uniqid()));
1165 ExtensionManagementUtilityAccessibleProxy::createExtTablesCacheEntry();
1166 }
1167
1168 /////////////////////////////////////////
1169 // Tests concerning getExtTablesCacheIdentifier
1170 /////////////////////////////////////////
1171 /**
1172 * @test
1173 */
1174 public function getExtTablesCacheIdentifierCreatesSha1WithFourtyCharactersAndPrefix() {
1175 $prefix = 'ext_tables_';
1176 $identifier = ExtensionManagementUtilityAccessibleProxy::getExtTablesCacheIdentifier();
1177 $this->assertStringStartsWith($prefix, $identifier);
1178 $sha1 = str_replace($prefix, '', $identifier);
1179 $this->assertEquals(40, strlen($sha1));
1180 }
1181
1182 /////////////////////////////////////////
1183 // Tests concerning removeCacheFiles
1184 /////////////////////////////////////////
1185 /**
1186 * @test
1187 */
1188 public function removeCacheFilesFlushesSystemCaches() {
1189 $mockCacheManager = $this->getMock(\TYPO3\CMS\Core\Cache\CacheManager::class, array('flushCachesInGroup'));
1190 $mockCacheManager->expects($this->once())->method('flushCachesInGroup')->with('system');
1191 ExtensionManagementUtilityAccessibleProxy::setCacheManager($mockCacheManager);
1192 ExtensionManagementUtility::removeCacheFiles();
1193 }
1194
1195 /////////////////////////////////////////
1196 // Tests concerning loadNewTcaColumnsConfigFiles
1197 /////////////////////////////////////////
1198
1199 /**
1200 * @test
1201 * @expectedException \RuntimeException
1202 */
1203 public function loadNewTcaColumnsConfigFilesIncludesDefinedDynamicConfigFileIfNoColumnsExist() {
1204 $GLOBALS['TCA'] = array(
1205 'test' => array(
1206 'ctrl' => array(
1207 'dynamicConfigFile' => __DIR__ . '/Fixtures/RuntimeException.php'
1208 ),
1209 ),
1210 );
1211 ExtensionManagementUtility::loadNewTcaColumnsConfigFiles();
1212 }
1213
1214 /**
1215 * @test
1216 */
1217 public function loadNewTcaColumnsConfigFilesDoesNotIncludeFileIfColumnsExist() {
1218 $GLOBALS['TCA'] = array(
1219 'test' => array(
1220 'ctrl' => array(
1221 'dynamicConfigFile' => __DIR__ . '/Fixtures/RuntimeException.php'
1222 ),
1223 'columns' => array(
1224 'foo' => 'bar',
1225 ),
1226 ),
1227 );
1228 ExtensionManagementUtility::loadNewTcaColumnsConfigFiles();
1229 }
1230
1231 /////////////////////////////////////////
1232 // Tests concerning getExtensionVersion
1233 /////////////////////////////////////////
1234 /**
1235 * Data provider for negative getExtensionVersion() tests.
1236 *
1237 * @return array
1238 */
1239 public function getExtensionVersionFaultyDataProvider() {
1240 return array(
1241 array(''),
1242 array(0),
1243 array(new \stdClass()),
1244 array(TRUE)
1245 );
1246 }
1247
1248 /**
1249 * @test
1250 * @expectedException \InvalidArgumentException
1251 * @dataProvider getExtensionVersionFaultyDataProvider
1252 */
1253 public function getExtensionVersionForFaultyExtensionKeyThrowsException($key) {
1254 ExtensionManagementUtility::getExtensionVersion($key);
1255 }
1256
1257 /**
1258 * @test
1259 */
1260 public function getExtensionVersionForNotLoadedExtensionReturnsEmptyString() {
1261 ExtensionManagementUtility::clearExtensionKeyMap();
1262 $uniqueSuffix = uniqid('test');
1263 $extensionKey = 'unloadedextension' . $uniqueSuffix;
1264 $this->assertEquals('', ExtensionManagementUtility::getExtensionVersion($extensionKey));
1265 }
1266
1267 /**
1268 * @test
1269 */
1270 public function getExtensionVersionForLoadedExtensionReturnsExtensionVersion() {
1271 ExtensionManagementUtility::clearExtensionKeyMap();
1272 $className = uniqid('ExtensionManagementUtility');
1273 eval(
1274 'namespace ' . __NAMESPACE__ . ';' .
1275 'class ' . $className . ' extends \\TYPO3\\CMS\\Core\\Utility\\ExtensionManagementUtility {' .
1276 ' public static function isLoaded() {' .
1277 ' return TRUE;' .
1278 ' }' .
1279 '}'
1280 );
1281 $className = __NAMESPACE__ . '\\' . $className;
1282 ExtensionManagementUtility::clearExtensionKeyMap();
1283 $uniqueSuffix = uniqid('test');
1284 $extensionKey = 'unloadedextension' . $uniqueSuffix;
1285 $packageMetaData = $this->getMock(\TYPO3\Flow\Package\MetaData::class, array('getVersion'), array($extensionKey));
1286 $packageMetaData->expects($this->any())->method('getVersion')->will($this->returnValue('1.2.3'));
1287 $packageManager = $this->createMockPackageManagerWithMockPackage($extensionKey, array('getPackagePath', 'getPackageKey', 'getPackageMetaData'));
1288 /** @var \PHPUnit_Framework_MockObject_MockObject $package */
1289 $package = $packageManager->getPackage($extensionKey);
1290 $package->expects($this->any())
1291 ->method('getPackageMetaData')
1292 ->will($this->returnValue($packageMetaData));
1293 ExtensionManagementUtility::setPackageManager($packageManager);
1294 $this->assertEquals('1.2.3', ExtensionManagementUtility::getExtensionVersion($extensionKey));
1295 }
1296
1297 /////////////////////////////////////////
1298 // Tests concerning loadExtension
1299 /////////////////////////////////////////
1300 /**
1301 * @test
1302 * @expectedException \RuntimeException
1303 */
1304 public function loadExtensionThrowsExceptionIfExtensionIsLoaded() {
1305 $extensionKey = uniqid('test');
1306 $packageManager = $this->createMockPackageManagerWithMockPackage($extensionKey);
1307 ExtensionManagementUtility::setPackageManager($packageManager);
1308 ExtensionManagementUtility::loadExtension($extensionKey);
1309 }
1310
1311 /////////////////////////////////////////
1312 // Tests concerning unloadExtension
1313 /////////////////////////////////////////
1314 /**
1315 * @test
1316 * @expectedException \RuntimeException
1317 */
1318 public function unloadExtensionThrowsExceptionIfExtensionIsNotLoaded() {
1319 $packageName = uniqid('foo');
1320 $packageManager = $this->getMock(\TYPO3\CMS\Core\Package\PackageManager::class, array('isPackageActive'));
1321 $packageManager->expects($this->once())
1322 ->method('isPackageActive')
1323 ->with($this->equalTo($packageName))
1324 ->will($this->returnValue(FALSE));
1325 ExtensionManagementUtility::setPackageManager($packageManager);
1326 ExtensionManagementUtility::unloadExtension($packageName);
1327 }
1328
1329 /**
1330 * @test
1331 */
1332 public function unloadExtensionCallsPackageManagerToDeactivatePackage() {
1333 $packageName = uniqid('foo');
1334 $packageManager = $this->getMock(
1335 \TYPO3\CMS\Core\Package\PackageManager::class,
1336 array('isPackageActive', 'deactivatePackage')
1337 );
1338 $packageManager->expects($this->any())
1339 ->method('isPackageActive')
1340 ->will($this->returnValue(TRUE));
1341 $packageManager->expects($this->once())
1342 ->method('deactivatePackage')
1343 ->with($packageName);
1344 ExtensionManagementUtility::setPackageManager($packageManager);
1345 ExtensionManagementUtility::unloadExtension($packageName);
1346 }
1347
1348 /////////////////////////////////////////
1349 // Tests concerning makeCategorizable
1350 /////////////////////////////////////////
1351 /**
1352 * @test
1353 */
1354 public function doesMakeCategorizableCallsTheCategoryRegistryWithDefaultFieldName() {
1355 $extensionKey = uniqid('extension');
1356 $tableName = uniqid('table');
1357
1358 $registryMock = $this->getMock(\TYPO3\CMS\Core\Category\CategoryRegistry::class);
1359 $registryMock->expects($this->once())->method('add')->with($extensionKey, $tableName, 'categories', array());
1360 GeneralUtility::setSingletonInstance(\TYPO3\CMS\Core\Category\CategoryRegistry::class, $registryMock);
1361 ExtensionManagementUtility::makeCategorizable($extensionKey, $tableName);
1362 }
1363
1364 /**
1365 * @test
1366 */
1367 public function doesMakeCategorizableCallsTheCategoryRegistryWithFieldName() {
1368 $extensionKey = uniqid('extension');
1369 $tableName = uniqid('table');
1370 $fieldName = uniqid('field');
1371
1372 $registryMock = $this->getMock(\TYPO3\CMS\Core\Category\CategoryRegistry::class);
1373 $registryMock->expects($this->once())->method('add')->with($extensionKey, $tableName, $fieldName, array());
1374 GeneralUtility::setSingletonInstance(\TYPO3\CMS\Core\Category\CategoryRegistry::class, $registryMock);
1375 ExtensionManagementUtility::makeCategorizable($extensionKey, $tableName, $fieldName);
1376 }
1377
1378 ///////////////////////////////
1379 // Tests concerning addPlugin
1380 ///////////////////////////////
1381
1382 /**
1383 * @test
1384 */
1385 public function addPluginSetsTcaCorrectlyForGivenExtkeyAsParameter() {
1386 $extKey = 'indexed_search';
1387 $GLOBALS['TYPO3_LOADED_EXT'] = array();
1388 $GLOBALS['TYPO3_LOADED_EXT'][$extKey]['ext_icon'] = 'foo.gif';
1389 $expectedTCA = array(
1390 array(
1391 'label',
1392 $extKey,
1393 'sysext/' . $extKey . '/foo.gif'
1394 )
1395 );
1396 $GLOBALS['TCA']['tt_content']['columns']['list_type']['config']['items'] = array();
1397 ExtensionManagementUtility::addPlugin(array('label', $extKey), 'list_type', $extKey);
1398 $this->assertEquals($expectedTCA, $GLOBALS['TCA']['tt_content']['columns']['list_type']['config']['items']);
1399 }
1400
1401 /**
1402 * @test
1403 */
1404 public function addPluginSetsTcaCorrectlyForGivenExtkeyAsGlobal() {
1405 $extKey = 'indexed_search';
1406 $GLOBALS['TYPO3_LOADED_EXT'] = array();
1407 $GLOBALS['TYPO3_LOADED_EXT'][$extKey]['ext_icon'] = 'foo.gif';
1408 $GLOBALS['_EXTKEY'] = $extKey;
1409 $expectedTCA = array(
1410 array(
1411 'label',
1412 $extKey,
1413 'sysext/' . $extKey . '/foo.gif'
1414 )
1415 );
1416 $GLOBALS['TCA']['tt_content']['columns']['list_type']['config']['items'] = array();
1417 ExtensionManagementUtility::addPlugin(array('label', $extKey));
1418 $this->assertEquals($expectedTCA, $GLOBALS['TCA']['tt_content']['columns']['list_type']['config']['items']);
1419 }
1420
1421 /**
1422 * @test
1423 * @expectedException \RuntimeException
1424 */
1425 public function addPluginThrowsExceptionForMissingExtkey() {
1426 ExtensionManagementUtility::addPlugin('test');
1427 }
1428
1429 }