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