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