[FEATURE] Integrate preliminary PackageManager API
[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 $GLOBALS['TYPO3_CONF_VARS']['EXT']['extList'] = '';
247 ExtensionManagementUtility::extPath('bar');
248 }
249
250 /**
251 * @test
252 */
253 public function extPathSearchesForPathOfExtensionInRequiredExtensionList() {
254 $this->setExpectedException('BadFunctionCallException', '', 1365429656);
255 unset($GLOBALS['TYPO3_LOADED_EXT']);
256 $GLOBALS['TYPO3_CONF_VARS']['EXT']['requiredExt'] = 'foo';
257 $GLOBALS['TYPO3_CONF_VARS']['EXT']['extList'] = '';
258 ExtensionManagementUtility::extPath('foo');
259 }
260
261 /**
262 * @test
263 */
264 public function extPathSearchesForPathOfExtensionInExtList() {
265 $this->setExpectedException('BadFunctionCallException', '', 1365429656);
266 unset($GLOBALS['TYPO3_LOADED_EXT']);
267 $GLOBALS['TYPO3_CONF_VARS']['EXT']['requiredExt'] = '';
268 $GLOBALS['TYPO3_CONF_VARS']['EXT']['extListArray'] = array('foo');
269 ExtensionManagementUtility::extPath('foo');
270 }
271
272 //////////////////////
273 // Utility functions
274 //////////////////////
275 /**
276 * Generates a basic TCA for a given table.
277 *
278 * @param string $table name of the table, must not be empty
279 * @return array generated TCA for the given table, will not be empty
280 */
281 private function generateTCAForTable($table) {
282 $tca = array();
283 $tca[$table] = array();
284 $tca[$table]['columns'] = array(
285 'fieldA' => array(),
286 'fieldC' => array()
287 );
288 $tca[$table]['types'] = array(
289 'typeA' => array('showitem' => 'fieldA, fieldB, fieldC;labelC;paletteC;specialC, fieldD'),
290 'typeB' => array('showitem' => 'fieldA, fieldB, fieldC;labelC;paletteC;specialC, fieldD'),
291 'typeC' => array('showitem' => 'fieldC;;paletteD')
292 );
293 $tca[$table]['palettes'] = array(
294 'paletteA' => array('showitem' => 'fieldX, fieldY'),
295 'paletteB' => array('showitem' => 'fieldX, fieldY'),
296 'paletteC' => array('showitem' => 'fieldX, fieldY'),
297 'paletteD' => array('showitem' => 'fieldX, fieldY')
298 );
299 return $tca;
300 }
301
302 /////////////////////////////////////////////
303 // Tests concerning getExtensionKeyByPrefix
304 /////////////////////////////////////////////
305 /**
306 * @test
307 * @see ExtensionManagementUtility::getExtensionKeyByPrefix
308 */
309 public function getExtensionKeyByPrefixForLoadedExtensionWithUnderscoresReturnsExtensionKey() {
310 ExtensionManagementUtility::clearExtensionKeyMap();
311 $uniqueSuffix = uniqid('test');
312 $extensionKey = 'tt_news' . $uniqueSuffix;
313 $extensionPrefix = 'tx_ttnews' . $uniqueSuffix;
314 $package = $this->getMockBuilder('TYPO3\\CMS\\Core\\Package\\Package')
315 ->disableOriginalConstructor()
316 ->setMethods(array('getPackageKey'))
317 ->getMock();
318 $package->expects($this->exactly(2))
319 ->method('getPackageKey')
320 ->will($this->returnValue($extensionKey));
321 $packageManager = $this->getMock('TYPO3\\CMS\\Core\\Package\\PackageManager', array('getActivePackages'));
322 $packageManager->expects($this->once())
323 ->method('getActivePackages')
324 ->will($this->returnValue(array($extensionKey => $package)));
325 ExtensionManagementUtility::setPackageManager($packageManager);
326 $this->assertEquals($extensionKey, ExtensionManagementUtility::getExtensionKeyByPrefix($extensionPrefix));
327 }
328
329 /**
330 * @test
331 * @see ExtensionManagementUtility::getExtensionKeyByPrefix
332 */
333 public function getExtensionKeyByPrefixForLoadedExtensionWithoutUnderscoresReturnsExtensionKey() {
334 ExtensionManagementUtility::clearExtensionKeyMap();
335 $uniqueSuffix = uniqid('test');
336 $extensionKey = 'kickstarter' . $uniqueSuffix;
337 $extensionPrefix = 'tx_kickstarter' . $uniqueSuffix;
338 $package = $this->getMockBuilder('TYPO3\\CMS\\Core\\Package\\Package')
339 ->disableOriginalConstructor()
340 ->setMethods(array('getPackageKey'))
341 ->getMock();
342 $package->expects($this->exactly(2))
343 ->method('getPackageKey')
344 ->will($this->returnValue($extensionKey));
345 $packageManager = $this->getMock('TYPO3\\CMS\\Core\\Package\\PackageManager', array('getActivePackages'));
346 $packageManager->expects($this->once())
347 ->method('getActivePackages')
348 ->will($this->returnValue(array($extensionKey => $package)));
349 ExtensionManagementUtility::setPackageManager($packageManager);
350 $this->assertEquals($extensionKey, ExtensionManagementUtility::getExtensionKeyByPrefix($extensionPrefix));
351 }
352
353 /**
354 * @test
355 * @see ExtensionManagementUtility::getExtensionKeyByPrefix
356 */
357 public function getExtensionKeyByPrefixForNotLoadedExtensionReturnsFalse() {
358 ExtensionManagementUtility::clearExtensionKeyMap();
359 $uniqueSuffix = uniqid('test');
360 $extensionKey = 'unloadedextension' . $uniqueSuffix;
361 $extensionPrefix = 'tx_unloadedextension' . $uniqueSuffix;
362 $this->assertFalse(ExtensionManagementUtility::getExtensionKeyByPrefix($extensionPrefix));
363 }
364
365 //////////////////////////////////////
366 // Tests concerning addToAllTCAtypes
367 //////////////////////////////////////
368 /**
369 * Tests whether fields can be add to all TCA types and duplicate fields are considered.
370 *
371 * @test
372 * @see ExtensionManagementUtility::addToAllTCAtypes()
373 */
374 public function canAddFieldsToAllTCATypesBeforeExistingOnes() {
375 $table = uniqid('tx_coretest_table');
376 $GLOBALS['TCA'] = $this->generateTCAForTable($table);
377 ExtensionManagementUtility::addToAllTCAtypes($table, 'newA, newA, newB, fieldA', '', 'before:fieldD');
378 // Checking typeA:
379 $this->assertEquals('fieldA, fieldB, fieldC;labelC;paletteC;specialC, newA, newB, fieldD', $GLOBALS['TCA'][$table]['types']['typeA']['showitem']);
380 // Checking typeB:
381 $this->assertEquals('fieldA, fieldB, fieldC;labelC;paletteC;specialC, newA, newB, fieldD', $GLOBALS['TCA'][$table]['types']['typeB']['showitem']);
382 }
383
384 /**
385 * Tests whether fields can be add to all TCA types and duplicate fields are considered.
386 *
387 * @test
388 * @see ExtensionManagementUtility::addToAllTCAtypes()
389 */
390 public function canAddFieldsToAllTCATypesAfterExistingOnes() {
391 $table = uniqid('tx_coretest_table');
392 $GLOBALS['TCA'] = $this->generateTCAForTable($table);
393 ExtensionManagementUtility::addToAllTCAtypes($table, 'newA, newA, newB, fieldA', '', 'after:fieldC');
394 // Checking typeA:
395 $this->assertEquals('fieldA, fieldB, fieldC;labelC;paletteC;specialC, newA, newB, fieldD', $GLOBALS['TCA'][$table]['types']['typeA']['showitem']);
396 // Checking typeB:
397 $this->assertEquals('fieldA, fieldB, fieldC;labelC;paletteC;specialC, newA, newB, fieldD', $GLOBALS['TCA'][$table]['types']['typeB']['showitem']);
398 }
399
400 /**
401 * Tests whether fields can be add to a TCA type before existing ones
402 *
403 * @test
404 * @see ExtensionManagementUtility::addToAllTCAtypes()
405 */
406 public function canAddFieldsToTCATypeBeforeExistingOnes() {
407 $table = uniqid('tx_coretest_table');
408 $GLOBALS['TCA'] = $this->generateTCAForTable($table);
409 ExtensionManagementUtility::addToAllTCAtypes($table, 'newA, newA, newB, fieldA', 'typeA', 'before:fieldD');
410 // Checking typeA:
411 $this->assertEquals('fieldA, fieldB, fieldC;labelC;paletteC;specialC, newA, newB, fieldD', $GLOBALS['TCA'][$table]['types']['typeA']['showitem']);
412 // Checking typeB:
413 $this->assertEquals('fieldA, fieldB, fieldC;labelC;paletteC;specialC, fieldD', $GLOBALS['TCA'][$table]['types']['typeB']['showitem']);
414 }
415
416 /**
417 * Tests whether fields can be add to a TCA type after existing ones
418 *
419 * @test
420 * @see ExtensionManagementUtility::addToAllTCAtypes()
421 */
422 public function canAddFieldsToTCATypeAfterExistingOnes() {
423 $table = uniqid('tx_coretest_table');
424 $GLOBALS['TCA'] = $this->generateTCAForTable($table);
425 ExtensionManagementUtility::addToAllTCAtypes($table, 'newA, newA, newB, fieldA', 'typeA', 'after:fieldC');
426 // Checking typeA:
427 $this->assertEquals('fieldA, fieldB, fieldC;labelC;paletteC;specialC, newA, newB, fieldD', $GLOBALS['TCA'][$table]['types']['typeA']['showitem']);
428 // Checking typeB:
429 $this->assertEquals('fieldA, fieldB, fieldC;labelC;paletteC;specialC, fieldD', $GLOBALS['TCA'][$table]['types']['typeB']['showitem']);
430 }
431
432 /**
433 * Test wheter replacing other TCA fields works as promissed
434 *
435 * @test
436 * @see ExtensionManagementUtility::addFieldsToAllPalettesOfField()
437 */
438 public function canAddFieldsToTCATypeAndReplaceExistingOnes() {
439 $table = uniqid('tx_coretest_table');
440 $GLOBALS['TCA'] = $this->generateTCAForTable($table);
441 $typesBefore = $GLOBALS['TCA'][$table]['types'];
442 ExtensionManagementUtility::addToAllTCAtypes($table, 'fieldZ', '', 'replace:fieldX');
443 $this->assertEquals($typesBefore, $GLOBALS['TCA'][$table]['types'], 'It\'s wrong that the "types" array changes here - the replaced field is only on palettes');
444 // unchanged because the palette is not used
445 $this->assertEquals('fieldX, fieldY', $GLOBALS['TCA'][$table]['palettes']['paletteA']['showitem']);
446 // unchanged because the palette is not used
447 $this->assertEquals('fieldX, fieldY', $GLOBALS['TCA'][$table]['palettes']['paletteB']['showitem']);
448 $this->assertEquals('fieldZ, fieldY', $GLOBALS['TCA'][$table]['palettes']['paletteC']['showitem']);
449 $this->assertEquals('fieldZ, fieldY', $GLOBALS['TCA'][$table]['palettes']['paletteD']['showitem']);
450 }
451
452 ///////////////////////////////////////////////////
453 // Tests concerning addFieldsToAllPalettesOfField
454 ///////////////////////////////////////////////////
455 /**
456 * Tests whether fields can be added to a palette before existing elements.
457 *
458 * @test
459 * @see ExtensionManagementUtility::addFieldsToPalette()
460 */
461 public function canAddFieldsToPaletteBeforeExistingOnes() {
462 $table = uniqid('tx_coretest_table');
463 $GLOBALS['TCA'] = $this->generateTCAForTable($table);
464 ExtensionManagementUtility::addFieldsToPalette($table, 'paletteA', 'newA, newA, newB, fieldX', 'before:fieldY');
465 $this->assertEquals('fieldX, newA, newB, fieldY', $GLOBALS['TCA'][$table]['palettes']['paletteA']['showitem']);
466 }
467
468 /**
469 * Tests whether fields can be added to a palette after existing elements.
470 *
471 * @test
472 * @see ExtensionManagementUtility::addFieldsToPalette()
473 */
474 public function canAddFieldsToPaletteAfterExistingOnes() {
475 $table = uniqid('tx_coretest_table');
476 $GLOBALS['TCA'] = $this->generateTCAForTable($table);
477 ExtensionManagementUtility::addFieldsToPalette($table, 'paletteA', 'newA, newA, newB, fieldX', 'after:fieldX');
478 $this->assertEquals('fieldX, newA, newB, fieldY', $GLOBALS['TCA'][$table]['palettes']['paletteA']['showitem']);
479 }
480
481 /**
482 * Tests whether fields can be added to a palette after a not existing elements.
483 *
484 * @test
485 * @see ExtensionManagementUtility::addFieldsToPalette()
486 */
487 public function canAddFieldsToPaletteAfterNotExistingOnes() {
488 $table = uniqid('tx_coretest_table');
489 $GLOBALS['TCA'] = $this->generateTCAForTable($table);
490 ExtensionManagementUtility::addFieldsToPalette($table, 'paletteA', 'newA, newA, newB, fieldX', 'after:' . uniqid('notExisting'));
491 $this->assertEquals('fieldX, fieldY, newA, newB', $GLOBALS['TCA'][$table]['palettes']['paletteA']['showitem']);
492 }
493
494 /**
495 * Tests whether fields can be added to all palettes of a regular field before existing ones.
496 *
497 * @test
498 * @see ExtensionManagementUtility::addFieldsToAllPalettesOfField()
499 */
500 public function canAddFieldsToAllPalettesOfFieldBeforeExistingOnes() {
501 $table = uniqid('tx_coretest_table');
502 $GLOBALS['TCA'] = $this->generateTCAForTable($table);
503 ExtensionManagementUtility::addFieldsToAllPalettesOfField($table, 'fieldC', 'newA, newA, newB, fieldX', 'before:fieldY');
504 $this->assertEquals('fieldX, fieldY', $GLOBALS['TCA'][$table]['palettes']['paletteA']['showitem']);
505 $this->assertEquals('fieldX, fieldY', $GLOBALS['TCA'][$table]['palettes']['paletteB']['showitem']);
506 $this->assertEquals('fieldX, newA, newB, fieldY', $GLOBALS['TCA'][$table]['palettes']['paletteC']['showitem']);
507 $this->assertEquals('fieldX, newA, newB, fieldY', $GLOBALS['TCA'][$table]['palettes']['paletteD']['showitem']);
508 }
509
510 /**
511 * Tests whether fields can be added to all palettes of a regular field after existing ones.
512 *
513 * @test
514 * @see ExtensionManagementUtility::addFieldsToAllPalettesOfField()
515 */
516 public function canAddFieldsToAllPalettesOfFieldAfterExistingOnes() {
517 $table = uniqid('tx_coretest_table');
518 $GLOBALS['TCA'] = $this->generateTCAForTable($table);
519 ExtensionManagementUtility::addFieldsToAllPalettesOfField($table, 'fieldC', 'newA, newA, newB, fieldX', 'after:fieldX');
520 $this->assertEquals('fieldX, fieldY', $GLOBALS['TCA'][$table]['palettes']['paletteA']['showitem']);
521 $this->assertEquals('fieldX, fieldY', $GLOBALS['TCA'][$table]['palettes']['paletteB']['showitem']);
522 $this->assertEquals('fieldX, newA, newB, fieldY', $GLOBALS['TCA'][$table]['palettes']['paletteC']['showitem']);
523 $this->assertEquals('fieldX, newA, newB, fieldY', $GLOBALS['TCA'][$table]['palettes']['paletteD']['showitem']);
524 }
525
526 /**
527 * Tests whether fields can be added to all palettes of a regular field after a not existing field.
528 *
529 * @test
530 * @see ExtensionManagementUtility::addFieldsToAllPalettesOfField()
531 */
532 public function canAddFieldsToAllPalettesOfFieldAfterNotExistingOnes() {
533 $table = uniqid('tx_coretest_table');
534 $GLOBALS['TCA'] = $this->generateTCAForTable($table);
535 ExtensionManagementUtility::addFieldsToAllPalettesOfField($table, 'fieldC', 'newA, newA, newB, fieldX', 'after:' . uniqid('notExisting'));
536 $this->assertEquals('fieldX, fieldY', $GLOBALS['TCA'][$table]['palettes']['paletteA']['showitem']);
537 $this->assertEquals('fieldX, fieldY', $GLOBALS['TCA'][$table]['palettes']['paletteB']['showitem']);
538 $this->assertEquals('fieldX, fieldY, newA, newB', $GLOBALS['TCA'][$table]['palettes']['paletteC']['showitem']);
539 $this->assertEquals('fieldX, fieldY, newA, newB', $GLOBALS['TCA'][$table]['palettes']['paletteD']['showitem']);
540 }
541
542 /**
543 * Tests whether fields are added to a new palette that did not exist before.
544 *
545 * @test
546 * @see ExtensionManagementUtility::addFieldsToAllPalettesOfField()
547 */
548 public function canAddFieldsToAllPalettesOfFieldWithoutPaletteExistingBefore() {
549 $table = uniqid('tx_coretest_table');
550 $GLOBALS['TCA'] = $this->generateTCAForTable($table);
551 ExtensionManagementUtility::addFieldsToAllPalettesOfField($table, 'fieldA', 'newA, newA, newB, fieldX');
552 $this->assertEquals('fieldX, fieldY', $GLOBALS['TCA'][$table]['palettes']['paletteA']['showitem']);
553 $this->assertEquals('fieldX, fieldY', $GLOBALS['TCA'][$table]['palettes']['paletteB']['showitem']);
554 $this->assertEquals('fieldX, fieldY', $GLOBALS['TCA'][$table]['palettes']['paletteC']['showitem']);
555 $this->assertEquals('fieldX, fieldY', $GLOBALS['TCA'][$table]['palettes']['paletteD']['showitem']);
556 $this->assertEquals('newA, newB, fieldX', $GLOBALS['TCA'][$table]['palettes']['generatedFor-fieldA']['showitem']);
557 }
558
559 /////////////////////////////////////////
560 // Tests concerning addTcaSelectItem
561 /////////////////////////////////////////
562 /**
563 * @test
564 * @expectedException \InvalidArgumentException
565 */
566 public function addTcaSelectItemThrowsExceptionIfTableIsNotOfTypeString() {
567 ExtensionManagementUtility::addTcaSelectItem(array(), 'foo', array());
568 }
569
570 /**
571 * @test
572 * @expectedException \InvalidArgumentException
573 */
574 public function addTcaSelectItemThrowsExceptionIfFieldIsNotOfTypeString() {
575 ExtensionManagementUtility::addTcaSelectItem('foo', array(), array());
576 }
577
578 /**
579 * @test
580 * @expectedException \InvalidArgumentException
581 */
582 public function addTcaSelectItemThrowsExceptionIfRelativeToFieldIsNotOfTypeString() {
583 ExtensionManagementUtility::addTcaSelectItem('foo', 'bar', array(), array());
584 }
585
586 /**
587 * @test
588 * @expectedException \InvalidArgumentException
589 */
590 public function addTcaSelectItemThrowsExceptionIfRelativePositionIsNotOfTypeString() {
591 ExtensionManagementUtility::addTcaSelectItem('foo', 'bar', array(), 'foo', array());
592 }
593
594 /**
595 * @test
596 * @expectedException \InvalidArgumentException
597 */
598 public function addTcaSelectItemThrowsExceptionIfRelativePositionIsNotOneOfValidKeywords() {
599 ExtensionManagementUtility::addTcaSelectItem('foo', 'bar', array(), 'foo', 'not allowed keyword');
600 }
601
602 /**
603 * @test
604 * @expectedException \RuntimeException
605 */
606 public function addTcaSelectItemThrowsExceptionIfFieldIsNotFoundInTca() {
607 $GLOBALS['TCA'] = array();
608 ExtensionManagementUtility::addTcaSelectItem('foo', 'bar', array());
609 }
610
611 /**
612 * Data provider for addTcaSelectItemInsertsItemAtSpecifiedPosition
613 */
614 public function addTcaSelectItemDataProvider() {
615 // Every array splits into:
616 // - relativeToField
617 // - relativePosition
618 // - expectedResultArray
619 return array(
620 'add at end of array' => array(
621 '',
622 '',
623 array(
624 0 => array('firstElement'),
625 1 => array('matchMe'),
626 2 => array('thirdElement'),
627 3 => array('insertedElement')
628 )
629 ),
630 'replace element' => array(
631 'matchMe',
632 'replace',
633 array(
634 0 => array('firstElement'),
635 1 => array('insertedElement'),
636 2 => array('thirdElement')
637 )
638 ),
639 'add element after' => array(
640 'matchMe',
641 'after',
642 array(
643 0 => array('firstElement'),
644 1 => array('matchMe'),
645 2 => array('insertedElement'),
646 3 => array('thirdElement')
647 )
648 ),
649 'add element before' => array(
650 'matchMe',
651 'before',
652 array(
653 0 => array('firstElement'),
654 1 => array('insertedElement'),
655 2 => array('matchMe'),
656 3 => array('thirdElement')
657 )
658 ),
659 'add at end if relative position was not found' => array(
660 'notExistingItem',
661 'after',
662 array(
663 0 => array('firstElement'),
664 1 => array('matchMe'),
665 2 => array('thirdElement'),
666 3 => array('insertedElement')
667 )
668 )
669 );
670 }
671
672 /**
673 * @test
674 * @dataProvider addTcaSelectItemDataProvider
675 */
676 public function addTcaSelectItemInsertsItemAtSpecifiedPosition($relativeToField, $relativePosition, $expectedResultArray) {
677 $GLOBALS['TCA'] = array(
678 'testTable' => array(
679 'columns' => array(
680 'testField' => array(
681 'config' => array(
682 'items' => array(
683 '0' => array('firstElement'),
684 '1' => array('matchMe'),
685 2 => array('thirdElement')
686 )
687 )
688 )
689 )
690 )
691 );
692 ExtensionManagementUtility::addTcaSelectItem('testTable', 'testField', array('insertedElement'), $relativeToField, $relativePosition);
693 $this->assertEquals($expectedResultArray, $GLOBALS['TCA']['testTable']['columns']['testField']['config']['items']);
694 }
695
696 /////////////////////////////////////////
697 // Tests concerning loadExtLocalconf
698 /////////////////////////////////////////
699 /**
700 * @test
701 */
702 public function loadExtLocalconfDoesNotReadFromCacheIfCachingIsDenied() {
703 $GLOBALS['typo3CacheManager'] = $this->getMock('TYPO3\\CMS\\Core\\Cache\\CacheManager', array('getCache'));
704 $GLOBALS['typo3CacheManager']->expects($this->never())->method('getCache');
705 $GLOBALS['TYPO3_LOADED_EXT'] = new \TYPO3\CMS\Core\Compatibility\LoadedExtensionsArray($this->createMockPackageManagerWithMockPackage(uniqid()));
706 ExtensionManagementUtility::loadExtLocalconf(FALSE);
707 }
708
709 /**
710 * @test
711 */
712 public function loadExtLocalconfRequiresCacheFileIfExistsAndCachingIsAllowed() {
713 $mockCache = $this->getMock(
714 'TYPO3\\CMS\\Core\\Cache\\Frontend\\AbstractFrontend',
715 array('getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove', 'flush', 'flushByTag', 'requireOnce'),
716 array(),
717 '',
718 FALSE
719 );
720 $GLOBALS['typo3CacheManager'] = $this->getMock('TYPO3\\CMS\\Core\\Cache\\CacheManager', array('getCache'));
721 $GLOBALS['typo3CacheManager']->expects($this->any())->method('getCache')->will($this->returnValue($mockCache));
722 $mockCache->expects($this->any())->method('has')->will($this->returnValue(TRUE));
723 $mockCache->expects($this->once())->method('requireOnce');
724 ExtensionManagementUtility::loadExtLocalconf(TRUE);
725 }
726
727 /////////////////////////////////////////
728 // Tests concerning loadSingleExtLocalconfFiles
729 /////////////////////////////////////////
730 /**
731 * @test
732 * @expectedException \RuntimeException
733 */
734 public function loadSingleExtLocalconfFilesRequiresExtLocalconfFileRegisteredInGlobalTypo3LoadedExt() {
735 $extensionName = uniqid('foo');
736 $packageManager = $this->createMockPackageManagerWithMockPackage($extensionName);
737 $extLocalconfLocation = $packageManager->getPackage($extensionName)->getPackagePath() . 'ext_localconf.php';
738 file_put_contents($extLocalconfLocation, "<?php\n\nthrow new RuntimeException('', 1340559079);\n\n?>");
739 $GLOBALS['TYPO3_LOADED_EXT'] = new \TYPO3\CMS\Core\Compatibility\LoadedExtensionsArray($packageManager);
740 ExtensionManagementUtilityAccessibleProxy::loadSingleExtLocalconfFiles();
741 }
742
743 /////////////////////////////////////////
744 // Tests concerning createExtLocalconfCacheEntry
745 /////////////////////////////////////////
746 /**
747 * @test
748 */
749 public function createExtLocalconfCacheEntryWritesCacheEntryWithContentOfLoadedExtensionExtLocalconf() {
750 $extensionName = uniqid('foo');
751 $packageManager = $this->createMockPackageManagerWithMockPackage($extensionName);
752 $extLocalconfLocation = $packageManager->getPackage($extensionName)->getPackagePath() . 'ext_localconf.php';
753 $this->testFilesToDelete[] = $extLocalconfLocation;
754 $uniqueStringInLocalconf = uniqid('foo');
755 file_put_contents($extLocalconfLocation, "<?php\n\n" . $uniqueStringInLocalconf . "\n\n?>");
756 $GLOBALS['TYPO3_LOADED_EXT'] = new \TYPO3\CMS\Core\Compatibility\LoadedExtensionsArray($packageManager);
757 $mockCache = $this->getMock(
758 'TYPO3\\CMS\\Core\\Cache\\Frontend\\AbstractFrontend',
759 array('getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove', 'flush', 'flushByTag', 'requireOnce'),
760 array(),
761 '',
762 FALSE
763 );
764 $GLOBALS['typo3CacheManager'] = $this->getMock('TYPO3\\CMS\\Core\\Cache\\CacheManager', array('getCache'));
765 $GLOBALS['typo3CacheManager']->expects($this->any())->method('getCache')->will($this->returnValue($mockCache));
766 $mockCache->expects($this->once())->method('set')->with($this->anything(), $this->stringContains($uniqueStringInLocalconf), $this->anything());
767 ExtensionManagementUtilityAccessibleProxy::createExtLocalconfCacheEntry();
768 }
769
770 /**
771 * @test
772 */
773 public function createExtLocalconfCacheEntryWritesCacheEntryWithExtensionContentOnlyIfExtLocalconfExists() {
774 $extensionName = uniqid('foo');
775 $packageManager = $this->createMockPackageManagerWithMockPackage($extensionName);
776 $GLOBALS['TYPO3_LOADED_EXT'] = new \TYPO3\CMS\Core\Compatibility\LoadedExtensionsArray($packageManager);
777 $mockCache = $this->getMock(
778 'TYPO3\\CMS\\Core\\Cache\\Frontend\\AbstractFrontend',
779 array('getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove', 'flush', 'flushByTag', 'requireOnce'),
780 array(),
781 '',
782 FALSE
783 );
784 $GLOBALS['typo3CacheManager'] = $this->getMock('TYPO3\\CMS\\Core\\Cache\\CacheManager', array('getCache'));
785 $GLOBALS['typo3CacheManager']->expects($this->any())->method('getCache')->will($this->returnValue($mockCache));
786 $mockCache->expects($this->once())
787 ->method('set')
788 ->with($this->anything(), $this->logicalNot($this->stringContains($extensionName)), $this->anything());
789 ExtensionManagementUtilityAccessibleProxy::createExtLocalconfCacheEntry();
790 }
791
792 /**
793 * @test
794 */
795 public function createExtLocalconfCacheEntryWritesCacheEntryWithNoTags() {
796 $mockCache = $this->getMock(
797 'TYPO3\\CMS\\Core\\Cache\\Frontend\\AbstractFrontend',
798 array('getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove', 'flush', 'flushByTag', 'requireOnce'),
799 array(),
800 '',
801 FALSE
802 );
803 $GLOBALS['typo3CacheManager'] = $this->getMock('TYPO3\\CMS\\Core\\Cache\\CacheManager', array('getCache'));
804 $GLOBALS['typo3CacheManager']->expects($this->any())->method('getCache')->will($this->returnValue($mockCache));
805 $mockCache->expects($this->once())->method('set')->with($this->anything(), $this->anything(), $this->equalTo(array()));
806 $GLOBALS['TYPO3_LOADED_EXT'] = new \TYPO3\CMS\Core\Compatibility\LoadedExtensionsArray($this->createMockPackageManagerWithMockPackage(uniqid()));
807 ExtensionManagementUtilityAccessibleProxy::createExtLocalconfCacheEntry();
808 }
809
810 /////////////////////////////////////////
811 // Tests concerning getExtLocalconfCacheIdentifier
812 /////////////////////////////////////////
813 /**
814 * @test
815 */
816 public function getExtLocalconfCacheIdentifierCreatesSha1WithFourtyCharactersAndPrefix() {
817 $prefix = 'ext_localconf_';
818 $identifier = ExtensionManagementUtilityAccessibleProxy::getExtLocalconfCacheIdentifier();
819 $this->assertStringStartsWith($prefix, $identifier);
820 $sha1 = str_replace($prefix, '', $identifier);
821 $this->assertEquals(40, strlen($sha1));
822 }
823
824 /////////////////////////////////////////
825 // Tests concerning loadBaseTca
826 /////////////////////////////////////////
827
828 /**
829 * @test
830 */
831 public function loadBaseTcaDoesNotReadFromCacheIfCachingIsDenied() {
832 $GLOBALS['typo3CacheManager'] = $this->getMock('TYPO3\\CMS\\Core\\Cache\\CacheManager', array('getCache'));
833 $GLOBALS['typo3CacheManager']->expects($this->never())->method('getCache');
834 ExtensionManagementUtility::loadBaseTca(FALSE);
835 }
836
837 /**
838 * @test
839 */
840 public function loadBaseTcaRequiresCacheFileIfExistsAndCachingIsAllowed() {
841 $mockCache = $this->getMock(
842 'TYPO3\\CMS\\Core\\Cache\\Frontend\\AbstractFrontend',
843 array('getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove', 'flush', 'flushByTag', 'requireOnce'),
844 array(),
845 '',
846 FALSE
847 );
848 $GLOBALS['typo3CacheManager'] = $this->getMock('TYPO3\\CMS\\Core\\Cache\\CacheManager', array('getCache'));
849 $GLOBALS['typo3CacheManager']->expects($this->any())->method('getCache')->will($this->returnValue($mockCache));
850 $mockCache->expects($this->any())->method('has')->will($this->returnValue(TRUE));
851 $mockCache->expects($this->once())->method('requireOnce');
852 ExtensionManagementUtility::loadBaseTca(TRUE);
853 }
854
855 /**
856 * @test
857 */
858 public function loadBaseTcaCreatesCacheFileWithContentOfAnExtensionsConfigurationTcaPhpFile() {
859 $extensionName = uniqid('test_baseTca_');
860 $packageManager = $this->createMockPackageManagerWithMockPackage($extensionName);
861 $packagePath = $packageManager->getPackage($extensionName)->getPackagePath();
862 \TYPO3\CMS\Core\Utility\GeneralUtility::mkdir($packagePath);
863 \TYPO3\CMS\Core\Utility\GeneralUtility::mkdir($packagePath . 'Configuration/');
864 \TYPO3\CMS\Core\Utility\GeneralUtility::mkdir($packagePath . 'Configuration/TCA/');
865 $GLOBALS['TYPO3_LOADED_EXT'] = new \TYPO3\CMS\Core\Compatibility\LoadedExtensionsArray($packageManager);
866 ExtensionManagementUtility::setPackageManager($packageManager);
867 $uniqueTableName = uniqid('table_name_');
868 $uniqueStringInTableConfiguration = uniqid('table_configuration_');
869 $tableConfiguration = '<?php return array(\'foo\' => \'' . $uniqueStringInTableConfiguration . '\'); ?>';
870 file_put_contents($packagePath . 'Configuration/TCA/' . $uniqueTableName . '.php', $tableConfiguration);
871 $mockCache = $this->getMock(
872 'TYPO3\\CMS\\Core\\Cache\\Frontend\\AbstractFrontend',
873 array('getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove', 'flush', 'flushByTag', 'requireOnce'),
874 array(),
875 '',
876 FALSE
877 );
878 $GLOBALS['typo3CacheManager'] = $this->getMock('TYPO3\\CMS\\Core\\Cache\\CacheManager', array('getCache'));
879 $GLOBALS['typo3CacheManager']->expects($this->any())->method('getCache')->will($this->returnValue($mockCache));
880 $mockCache->expects($this->once())->method('has')->will($this->returnValue(FALSE));
881 $mockCache->expects($this->once())->method('set')->with($this->anything(), $this->stringContains($uniqueStringInTableConfiguration), $this->anything());
882 ExtensionManagementUtility::loadBaseTca(TRUE);
883 }
884
885 /**
886 * @test
887 */
888 public function loadBaseTcaWritesCacheEntryWithNoTags() {
889 $mockCache = $this->getMock(
890 'TYPO3\\CMS\\Core\\Cache\\Frontend\\AbstractFrontend',
891 array('getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove', 'flush', 'flushByTag', 'requireOnce'),
892 array(),
893 '',
894 FALSE
895 );
896 $GLOBALS['typo3CacheManager'] = $this->getMock('TYPO3\\CMS\\Core\\Cache\\CacheManager', array('getCache'));
897 $GLOBALS['typo3CacheManager']->expects($this->any())->method('getCache')->will($this->returnValue($mockCache));
898 $mockCache->expects($this->once())->method('has')->will($this->returnValue(FALSE));
899 $mockCache->expects($this->once())->method('set')->with($this->anything(), $this->anything(), $this->equalTo(array()));
900 ExtensionManagementUtility::loadBaseTca();
901 }
902
903 /////////////////////////////////////////
904 // Tests concerning getBaseTcaCacheIdentifier
905 /////////////////////////////////////////
906
907 /**
908 * @test
909 */
910 public function getBaseTcaCacheIdentifierCreatesSha1WithFourtyCharactersAndPrefix() {
911 $prefix = 'tca_base_';
912 $identifier = ExtensionManagementUtilityAccessibleProxy::getBaseTcaCacheIdentifier();
913 $this->assertStringStartsWith($prefix, $identifier);
914 $sha1 = str_replace($prefix, '', $identifier);
915 $this->assertEquals(40, strlen($sha1));
916 }
917
918 /////////////////////////////////////////
919 // Tests concerning loadExtTables
920 /////////////////////////////////////////
921 /**
922 * @test
923 */
924 public function loadExtTablesDoesNotReadFromCacheIfCachingIsDenied() {
925 $GLOBALS['typo3CacheManager'] = $this->getMock('TYPO3\\CMS\\Core\\Cache\\CacheManager', array('getCache'));
926 $GLOBALS['typo3CacheManager']->expects($this->never())->method('getCache');
927 $GLOBALS['TYPO3_LOADED_EXT'] = new \TYPO3\CMS\Core\Compatibility\LoadedExtensionsArray($this->createMockPackageManagerWithMockPackage(uniqid()));
928 ExtensionManagementUtility::loadExtLocalconf(FALSE);
929 }
930
931 /**
932 * @test
933 */
934 public function loadExtTablesRequiresCacheFileIfExistsAndCachingIsAllowed() {
935 $mockCache = $this->getMock(
936 'TYPO3\\CMS\\Core\\Cache\\Frontend\\AbstractFrontend',
937 array('getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove', 'flush', 'flushByTag', 'requireOnce'),
938 array(),
939 '',
940 FALSE
941 );
942 $GLOBALS['typo3CacheManager'] = $this->getMock('TYPO3\\CMS\\Core\\Cache\\CacheManager', array('getCache'));
943 $GLOBALS['typo3CacheManager']->expects($this->any())->method('getCache')->will($this->returnValue($mockCache));
944 $mockCache->expects($this->any())->method('has')->will($this->returnValue(TRUE));
945 $mockCache->expects($this->once())->method('requireOnce');
946 // Reset the internal cache access tracking variable of extMgm
947 // This method is only in the ProxyClass!
948 ExtensionManagementUtilityAccessibleProxy::resetExtTablesWasReadFromCacheOnceBoolean();
949 ExtensionManagementUtility::loadExtTables(TRUE);
950 }
951
952 /////////////////////////////////////////
953 // Tests concerning createExtTablesCacheEntry
954 /////////////////////////////////////////
955 /**
956 * @test
957 */
958 public function createExtTablesCacheEntryWritesCacheEntryWithContentOfLoadedExtensionExtTables() {
959 $extensionName = uniqid('foo');
960 $extTablesLocation = PATH_site . 'typo3temp/' . uniqid('test_ext_tables') . '.php';
961 $this->testFilesToDelete[] = $extTablesLocation;
962 $uniqueStringInTables = uniqid('foo');
963 file_put_contents($extTablesLocation, "<?php\n\n$uniqueStringInTables\n\n?>");
964 $GLOBALS['TYPO3_LOADED_EXT'] = array(
965 $extensionName => array(
966 'ext_tables.php' => $extTablesLocation
967 )
968 );
969 $mockCache = $this->getMock(
970 'TYPO3\\CMS\\Core\\Cache\\Frontend\\AbstractFrontend',
971 array('getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove', 'flush', 'flushByTag', 'requireOnce'),
972 array(),
973 '',
974 FALSE
975 );
976 $GLOBALS['typo3CacheManager'] = $this->getMock('TYPO3\\CMS\\Core\\Cache\\CacheManager', array('getCache'));
977 $GLOBALS['typo3CacheManager']->expects($this->any())->method('getCache')->will($this->returnValue($mockCache));
978 $mockCache->expects($this->once())->method('set')->with($this->anything(), $this->stringContains($uniqueStringInTables), $this->anything());
979 ExtensionManagementUtilityAccessibleProxy::createExtTablesCacheEntry();
980 }
981
982 /**
983 * @test
984 */
985 public function createExtTablesCacheEntryWritesCacheEntryWithExtensionContentOnlyIfExtTablesExists() {
986 $extensionName = uniqid('foo');
987 $GLOBALS['TYPO3_LOADED_EXT'] = array(
988 $extensionName => array(),
989 );
990 $mockCache = $this->getMock(
991 'TYPO3\\CMS\\Core\\Cache\\Frontend\\AbstractFrontend',
992 array('getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove', 'flush', 'flushByTag', 'requireOnce'),
993 array(),
994 '',
995 FALSE
996 );
997 $GLOBALS['typo3CacheManager'] = $this->getMock('TYPO3\\CMS\\Core\\Cache\\CacheManager', array('getCache'));
998 $GLOBALS['typo3CacheManager']->expects($this->any())->method('getCache')->will($this->returnValue($mockCache));
999 $mockCache->expects($this->once())
1000 ->method('set')
1001 ->with($this->anything(), $this->logicalNot($this->stringContains($extensionName)), $this->anything());
1002 ExtensionManagementUtilityAccessibleProxy::createExtTablesCacheEntry();
1003 }
1004
1005 /**
1006 * @test
1007 */
1008 public function createExtTablesCacheEntryWritesCacheEntryWithNoTags() {
1009 $mockCache = $this->getMock(
1010 'TYPO3\\CMS\\Core\\Cache\\Frontend\\AbstractFrontend',
1011 array('getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove', 'flush', 'flushByTag', 'requireOnce'),
1012 array(),
1013 '',
1014 FALSE
1015 );
1016 $GLOBALS['typo3CacheManager'] = $this->getMock('TYPO3\\CMS\\Core\\Cache\\CacheManager', array('getCache'));
1017 $GLOBALS['typo3CacheManager']->expects($this->any())->method('getCache')->will($this->returnValue($mockCache));
1018 $mockCache->expects($this->once())->method('set')->with($this->anything(), $this->anything(), $this->equalTo(array()));
1019 $GLOBALS['TYPO3_LOADED_EXT'] = new \TYPO3\CMS\Core\Compatibility\LoadedExtensionsArray($this->createMockPackageManagerWithMockPackage(uniqid()));
1020 ExtensionManagementUtilityAccessibleProxy::createExtTablesCacheEntry();
1021 }
1022
1023 /////////////////////////////////////////
1024 // Tests concerning getExtTablesCacheIdentifier
1025 /////////////////////////////////////////
1026 /**
1027 * @test
1028 */
1029 public function getExtTablesCacheIdentifierCreatesSha1WithFourtyCharactersAndPrefix() {
1030 $prefix = 'ext_tables_';
1031 $identifier = ExtensionManagementUtilityAccessibleProxy::getExtTablesCacheIdentifier();
1032 $this->assertStringStartsWith($prefix, $identifier);
1033 $sha1 = str_replace($prefix, '', $identifier);
1034 $this->assertEquals(40, strlen($sha1));
1035 }
1036
1037 /////////////////////////////////////////
1038 // Tests concerning removeCacheFiles
1039 /////////////////////////////////////////
1040 /**
1041 * @test
1042 */
1043 public function removeCacheFilesFlushesCache() {
1044 $mockCache = $this->getMock(
1045 'TYPO3\\CMS\\Core\\Cache\\Frontend\\AbstractFrontend',
1046 array('getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove', 'flush', 'flushByTag', 'requireOnce'),
1047 array(),
1048 '',
1049 FALSE
1050 );
1051 $GLOBALS['typo3CacheManager'] = $this->getMock('TYPO3\\CMS\\Core\\Cache\\CacheManager', array('getCache'));
1052 $GLOBALS['typo3CacheManager']->expects($this->any())->method('getCache')->will($this->returnValue($mockCache));
1053 $mockCache->expects($this->once())->method('flush');
1054 ExtensionManagementUtility::removeCacheFiles();
1055 }
1056
1057 /////////////////////////////////////////
1058 // Tests concerning loadNewTcaColumnsConfigFiles
1059 /////////////////////////////////////////
1060
1061 /**
1062 * @test
1063 * @expectedException \RuntimeException
1064 */
1065 public function loadNewTcaColumnsConfigFilesIncludesDefinedDynamicConfigFileIfNoColumnsExist() {
1066 $GLOBALS['TCA'] = array(
1067 'test' => array(
1068 'ctrl' => array(
1069 'dynamicConfigFile' => __DIR__ . '/Fixtures/RuntimeException.php'
1070 ),
1071 ),
1072 );
1073 ExtensionManagementUtility::loadNewTcaColumnsConfigFiles();
1074 }
1075
1076 /**
1077 * @test
1078 */
1079 public function loadNewTcaColumnsConfigFilesDoesNotIncludeFileIfColumnsExist() {
1080 $GLOBALS['TCA'] = array(
1081 'test' => array(
1082 'ctrl' => array(
1083 'dynamicConfigFile' => __DIR__ . '/Fixtures/RuntimeException.php'
1084 ),
1085 'columns' => array(
1086 'foo' => 'bar',
1087 ),
1088 ),
1089 );
1090 ExtensionManagementUtility::loadNewTcaColumnsConfigFiles();
1091 }
1092
1093 /////////////////////////////////////////
1094 // Tests concerning getExtensionVersion
1095 /////////////////////////////////////////
1096 /**
1097 * Data provider for negative getExtensionVersion() tests.
1098 *
1099 * @return array
1100 */
1101 public function getExtensionVersionFaultyDataProvider() {
1102 return array(
1103 array(''),
1104 array(0),
1105 array(new \stdClass()),
1106 array(TRUE)
1107 );
1108 }
1109
1110 /**
1111 * @test
1112 * @expectedException \InvalidArgumentException
1113 * @dataProvider getExtensionVersionFaultyDataProvider
1114 */
1115 public function getExtensionVersionForFaultyExtensionKeyThrowsException($key) {
1116 ExtensionManagementUtility::getExtensionVersion($key);
1117 }
1118
1119 /**
1120 * @test
1121 */
1122 public function getExtensionVersionForNotLoadedExtensionReturnsEmptyString() {
1123 ExtensionManagementUtility::clearExtensionKeyMap();
1124 $uniqueSuffix = uniqid('test');
1125 $extensionKey = 'unloadedextension' . $uniqueSuffix;
1126 $this->assertEquals('', ExtensionManagementUtility::getExtensionVersion($extensionKey));
1127 }
1128
1129 /**
1130 * @test
1131 */
1132 public function getExtensionVersionForLoadedExtensionReturnsExtensionVersion() {
1133 ExtensionManagementUtility::clearExtensionKeyMap();
1134 $className = uniqid('ExtensionManagementUtility');
1135 eval(
1136 'namespace ' . __NAMESPACE__ .';' .
1137 'class ' . $className . ' extends \\TYPO3\\CMS\\Core\\Utility\\ExtensionManagementUtility {' .
1138 ' public static function isLoaded() {' .
1139 ' return TRUE;' .
1140 ' }' .
1141 '}'
1142 );
1143 $className = __NAMESPACE__ . '\\' . $className;
1144 ExtensionManagementUtility::clearExtensionKeyMap();
1145 $uniqueSuffix = uniqid('test');
1146 $extensionKey = 'unloadedextension' . $uniqueSuffix;
1147 $packageMetaData = $this->getMock('TYPO3\\Flow\\Package\\MetaData', array('getVersion'), array($extensionKey));
1148 $packageMetaData->expects($this->any())->method('getVersion')->will($this->returnValue('1.2.3'));
1149 $packageManager = $this->createMockPackageManagerWithMockPackage($extensionKey, array('getPackagePath', 'getPackageKey', 'getPackageMetaData'));
1150 /** @var \PHPUnit_Framework_MockObject_MockObject $package */
1151 $package = $packageManager->getPackage($extensionKey);
1152 $package->expects($this->any())
1153 ->method('getPackageMetaData')
1154 ->will($this->returnValue($packageMetaData));
1155 ExtensionManagementUtility::setPackageManager($packageManager);
1156 $this->assertEquals('1.2.3', ExtensionManagementUtility::getExtensionVersion($extensionKey));
1157 }
1158
1159 /////////////////////////////////////////
1160 // Tests concerning loadExtension
1161 /////////////////////////////////////////
1162 /**
1163 * @test
1164 * @expectedException \RuntimeException
1165 */
1166 public function loadExtensionThrowsExceptionIfExtensionIsLoaded() {
1167 $extensionKey = uniqid('test');
1168 $packageManager = $this->createMockPackageManagerWithMockPackage($extensionKey);
1169 ExtensionManagementUtility::setPackageManager($packageManager);
1170 ExtensionManagementUtility::loadExtension($extensionKey);
1171 }
1172
1173 /////////////////////////////////////////
1174 // Tests concerning unloadExtension
1175 /////////////////////////////////////////
1176 /**
1177 * @test
1178 * @expectedException \RuntimeException
1179 */
1180 public function unloadExtensionThrowsExceptionIfExtensionIsNotLoaded() {
1181 $className = uniqid('ExtensionManagementUtility');
1182 eval(
1183 'namespace ' . __NAMESPACE__ . ';' .
1184 'class ' . $className . ' extends \\TYPO3\\CMS\\Core\\Utility\\ExtensionManagementUtility {' .
1185 ' public static function isLoaded() {' .
1186 ' return FALSE;' .
1187 ' }' .
1188 '}'
1189 );
1190 $className = __NAMESPACE__ . '\\' . $className;
1191 $className::unloadExtension('test');
1192 }
1193
1194 /**
1195 * @test
1196 * @expectedException \RuntimeException
1197 */
1198 public function unloadExtensionThrowsExceptionIfExtensionIsRequired() {
1199 $extensionKey = uniqid('test');
1200 $className = uniqid('ExtensionManagementUtility');
1201 eval(
1202 'namespace ' . __NAMESPACE__ . ';' .
1203 'class ' . $className . ' extends \\TYPO3\\CMS\\Core\\Utility\\ExtensionManagementUtility {' .
1204 ' public static function isLoaded() {' .
1205 ' return TRUE;' .
1206 ' }' .
1207 ' public static function getRequiredExtensionListArray() {' .
1208 ' return array(\'' . $extensionKey . '\');' .
1209 ' }' .
1210 '}'
1211 );
1212 $className = __NAMESPACE__ . '\\' . $className;
1213 $className::unloadExtension($extensionKey);
1214 }
1215
1216 /**
1217 * @test
1218 * @expectedException \RuntimeException
1219 */
1220 public function unloadExtensionRemovesExtensionFromExtList() {
1221 if (!file_exists((PATH_typo3conf . 'LocalConfiguration.php'))) {
1222 $this->markTestSkipped('Test is not available until update wizard to transform localconf.php was run.');
1223 }
1224 $extensionKeyToUnload = uniqid('unloadMe');
1225 $className = uniqid('ExtensionManagementUtility');
1226 eval(
1227 'namespace ' . __NAMESPACE__ . ';' .
1228 'class ' . $className . ' extends \\TYPO3\\CMS\\Core\\Utility\\ExtensionManagementUtility {' .
1229 ' public static function isLoaded() {' .
1230 ' return TRUE;' .
1231 ' }' .
1232 ' public static function writeNewExtensionList($extList) {' .
1233 ' if (!in_array(' . $extensionKeyToUnload . ', $extList)) {' .
1234 ' throw new \\RuntimeException(\'test\');' .
1235 ' }' .
1236 ' }' .
1237 '}'
1238 );
1239 $className = __NAMESPACE__ . '\\' . $className;
1240 $className::unloadExtension($extensionKeyToUnload);
1241 }
1242
1243 /////////////////////////////////////////
1244 // Tests concerning makeCategorizable
1245 /////////////////////////////////////////
1246 /**
1247 * @test
1248 */
1249 public function isMakeCategorizableAvailableInRegistryWithDefaultField() {
1250 $extensionKey = uniqid('extension');
1251 $tableName = uniqid('table');
1252 $GLOBALS['TCA'][$tableName] = array(
1253 'ctrl' => array(),
1254 'columns' => array()
1255 );
1256 $registryMock = $this->getMock('TYPO3\\CMS\\Core\\Category\\CategoryRegistry', array('dummy'));
1257 \TYPO3\CMS\Core\Utility\GeneralUtility::setSingletonInstance('TYPO3\\CMS\\Core\\Category\\CategoryRegistry', $registryMock);
1258 ExtensionManagementUtility::makeCategorizable($extensionKey, $tableName);
1259 $registryMock->applyTca();
1260 $this->assertNotEmpty($GLOBALS['TCA'][$tableName]['columns']['categories']);
1261 }
1262
1263 /**
1264 * @test
1265 */
1266 public function isMakeCategorizableAvailableInRegistryWithSpecifictField() {
1267 $extensionKey = uniqid('extension');
1268 $tableName = uniqid('table');
1269 $fieldName = uniqid('field');
1270 $GLOBALS['TCA'][$tableName] = array(
1271 'ctrl' => array(),
1272 'columns' => array()
1273 );
1274 $registryMock = $this->getMock('TYPO3\\CMS\\Core\\Category\\CategoryRegistry', array('dummy'));
1275 \TYPO3\CMS\Core\Utility\GeneralUtility::setSingletonInstance('TYPO3\\CMS\\Core\\Category\\CategoryRegistry', $registryMock);
1276 ExtensionManagementUtility::makeCategorizable($extensionKey, $tableName, $fieldName);
1277 $registryMock->applyTca();
1278 $this->assertNotEmpty($GLOBALS['TCA'][$tableName]['columns'][$fieldName]);
1279 }
1280
1281 }