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