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