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