[TASK] Deprecate $GLOBALS['TYPO3_LOADED_EXT']
[Packages/TYPO3.CMS.git] / typo3 / sysext / core / Tests / Unit / Utility / ExtensionManagementUtilityTest.php
1 <?php
2 namespace TYPO3\CMS\Core\Tests\Unit\Utility;
3
4 /*
5 * This file is part of the TYPO3 CMS project.
6 *
7 * It is free software; you can redistribute it and/or modify it under
8 * the terms of the GNU General Public License, either version 2
9 * of the License, or any later version.
10 *
11 * For the full copyright and license information, please read the
12 * LICENSE.txt file that was distributed with this source code.
13 *
14 * The TYPO3 project - inspiring people to share!
15 */
16
17 use TYPO3\CMS\Core\Cache\CacheManager;
18 use TYPO3\CMS\Core\Cache\Frontend\PhpFrontend;
19 use TYPO3\CMS\Core\Category\CategoryRegistry;
20 use TYPO3\CMS\Core\Core\Environment;
21 use TYPO3\CMS\Core\Package\MetaData;
22 use TYPO3\CMS\Core\Package\Package;
23 use TYPO3\CMS\Core\Package\PackageManager;
24 use TYPO3\CMS\Core\Tests\Unit\Utility\AccessibleProxies\ExtensionManagementUtilityAccessibleProxy;
25 use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
26 use TYPO3\CMS\Core\Utility\GeneralUtility;
27 use TYPO3\TestingFramework\Core\Unit\UnitTestCase;
28
29 /**
30 * Test case
31 */
32 class ExtensionManagementUtilityTest extends UnitTestCase
33 {
34 /**
35 * @var bool Reset singletons created by subject
36 */
37 protected $resetSingletonInstances = true;
38
39 /**
40 * @var \TYPO3\CMS\Core\Package\PackageManager
41 */
42 protected $backUpPackageManager;
43
44 /**
45 * Set up
46 */
47 protected function setUp()
48 {
49 $this->backUpPackageManager = ExtensionManagementUtilityAccessibleProxy::getPackageManager();
50 }
51
52 /**
53 * Tear down
54 */
55 protected function tearDown()
56 {
57 ExtensionManagementUtility::clearExtensionKeyMap();
58 ExtensionManagementUtilityAccessibleProxy::setPackageManager($this->backUpPackageManager);
59 ExtensionManagementUtilityAccessibleProxy::setCacheManager(null);
60 parent::tearDown();
61 }
62
63 /**
64 * @param string $packageKey
65 * @param array $packageMethods
66 * @return PackageManager|\PHPUnit_Framework_MockObject_MockObject
67 */
68 protected function createMockPackageManagerWithMockPackage($packageKey, $packageMethods = ['getPackagePath', 'getPackageKey'])
69 {
70 $packagePath = Environment::getVarPath() . '/tests/' . $packageKey . '/';
71 GeneralUtility::mkdir_deep($packagePath);
72 $this->testFilesToDelete[] = $packagePath;
73 $package = $this->getMockBuilder(Package::class)
74 ->disableOriginalConstructor()
75 ->setMethods($packageMethods)
76 ->getMock();
77 $packageManager = $this->getMockBuilder(PackageManager::class)
78 ->setMethods(['isPackageActive', 'getPackage', 'getActivePackages'])
79 ->disableOriginalConstructor()
80 ->getMock();
81 $package->expects($this->any())
82 ->method('getPackagePath')
83 ->will($this->returnValue($packagePath));
84 $package->expects($this->any())
85 ->method('getPackageKey')
86 ->will($this->returnValue($packageKey));
87 $packageManager->expects($this->any())
88 ->method('isPackageActive')
89 ->will($this->returnValueMap([
90 [null, false],
91 [$packageKey, true]
92 ]));
93 $packageManager->expects($this->any())
94 ->method('getPackage')
95 ->with($this->equalTo($packageKey))
96 ->will($this->returnValue($package));
97 $packageManager->expects($this->any())
98 ->method('getActivePackages')
99 ->will($this->returnValue([$packageKey => $package]));
100 return $packageManager;
101 }
102
103 ///////////////////////////////
104 // Tests concerning isLoaded
105 ///////////////////////////////
106 /**
107 * @test
108 */
109 public function isLoadedReturnsFalseIfExtensionIsNotLoaded()
110 {
111 $this->assertFalse(ExtensionManagementUtility::isLoaded($this->getUniqueId('foobar')));
112 }
113
114 ///////////////////////////////
115 // Tests concerning extPath
116 ///////////////////////////////
117 /**
118 * @test
119 */
120 public function extPathThrowsExceptionIfExtensionIsNotLoaded()
121 {
122 $this->expectException(\BadFunctionCallException::class);
123 $this->expectExceptionCode(1365429656);
124
125 $packageName = $this->getUniqueId('foo');
126 /** @var PackageManager|\PHPUnit_Framework_MockObject_MockObject $packageManager */
127 $packageManager = $this->getMockBuilder(PackageManager::class)
128 ->setMethods(['isPackageActive'])
129 ->disableOriginalConstructor()
130 ->getMock();
131 $packageManager->expects($this->once())
132 ->method('isPackageActive')
133 ->with($this->equalTo($packageName))
134 ->will($this->returnValue(false));
135 ExtensionManagementUtility::setPackageManager($packageManager);
136 ExtensionManagementUtility::extPath($packageName);
137 }
138
139 /**
140 * @test
141 */
142 public function extPathAppendsScriptNameToPath()
143 {
144 $package = $this->getMockBuilder(Package::class)
145 ->disableOriginalConstructor()
146 ->setMethods(['getPackagePath'])
147 ->getMock();
148 /** @var PackageManager|\PHPUnit_Framework_MockObject_MockObject $packageManager */
149 $packageManager = $this->getMockBuilder(PackageManager::class)
150 ->setMethods(['isPackageActive', 'getPackage'])
151 ->disableOriginalConstructor()
152 ->getMock();
153 $package->expects($this->once())
154 ->method('getPackagePath')
155 ->will($this->returnValue(Environment::getPublicPath() . '/foo/'));
156 $packageManager->expects($this->once())
157 ->method('isPackageActive')
158 ->with($this->equalTo('foo'))
159 ->will($this->returnValue(true));
160 $packageManager->expects($this->once())
161 ->method('getPackage')
162 ->with('foo')
163 ->will($this->returnValue($package));
164 ExtensionManagementUtility::setPackageManager($packageManager);
165 $this->assertSame(Environment::getPublicPath() . '/foo/bar.txt', ExtensionManagementUtility::extPath('foo', 'bar.txt'));
166 }
167
168 //////////////////////
169 // Utility functions
170 //////////////////////
171 /**
172 * Generates a basic TCA for a given table.
173 *
174 * @param string $table name of the table, must not be empty
175 * @return array generated TCA for the given table, will not be empty
176 */
177 private function generateTCAForTable($table)
178 {
179 $tca = [];
180 $tca[$table] = [];
181 $tca[$table]['columns'] = [
182 'fieldA' => [],
183 'fieldC' => []
184 ];
185 $tca[$table]['types'] = [
186 'typeA' => ['showitem' => 'fieldA, fieldB, fieldC;labelC, --palette--;;paletteC, fieldC1, fieldD, fieldD1'],
187 'typeB' => ['showitem' => 'fieldA, fieldB, fieldC;labelC, --palette--;;paletteC, fieldC1, fieldD, fieldD1'],
188 'typeC' => ['showitem' => 'fieldC;;paletteD']
189 ];
190 $tca[$table]['palettes'] = [
191 'paletteA' => ['showitem' => 'fieldX, fieldX1, fieldY'],
192 'paletteB' => ['showitem' => 'fieldX, fieldX1, fieldY'],
193 'paletteC' => ['showitem' => 'fieldX, fieldX1, fieldY'],
194 'paletteD' => ['showitem' => 'fieldX, fieldX1, fieldY']
195 ];
196 return $tca;
197 }
198
199 /**
200 * Data provider for getClassNamePrefixForExtensionKey.
201 *
202 * @return array
203 */
204 public function extensionKeyDataProvider()
205 {
206 return [
207 'Without underscores' => [
208 'testkey',
209 'tx_testkey'
210 ],
211 'With underscores' => [
212 'this_is_a_test_extension',
213 'tx_thisisatestextension'
214 ],
215 'With user prefix and without underscores' => [
216 'user_testkey',
217 'user_testkey'
218 ],
219 'With user prefix and with underscores' => [
220 'user_test_key',
221 'user_testkey'
222 ],
223 ];
224 }
225
226 /**
227 * @test
228 * @param string $extensionName
229 * @param string $expectedPrefix
230 * @dataProvider extensionKeyDataProvider
231 */
232 public function getClassNamePrefixForExtensionKey($extensionName, $expectedPrefix)
233 {
234 $this->assertSame($expectedPrefix, ExtensionManagementUtility::getCN($extensionName));
235 }
236
237 //////////////////////////////////////
238 // Tests concerning addToAllTCAtypes
239 //////////////////////////////////////
240 /**
241 * Tests whether fields can be add to all TCA types and duplicate fields are considered.
242 *
243 * @test
244 * @see ExtensionManagementUtility::addToAllTCAtypes()
245 */
246 public function canAddFieldsToAllTCATypesBeforeExistingOnes()
247 {
248 $table = $this->getUniqueId('tx_coretest_table');
249 $GLOBALS['TCA'] = $this->generateTCAForTable($table);
250 ExtensionManagementUtility::addToAllTCAtypes($table, 'newA, newA, newB, fieldA', '', 'before:fieldD');
251 // Checking typeA:
252 $this->assertEquals('fieldA, fieldB, fieldC;labelC, --palette--;;paletteC, fieldC1, newA, newB, fieldD, fieldD1', $GLOBALS['TCA'][$table]['types']['typeA']['showitem']);
253 // Checking typeB:
254 $this->assertEquals('fieldA, fieldB, fieldC;labelC, --palette--;;paletteC, fieldC1, newA, newB, fieldD, fieldD1', $GLOBALS['TCA'][$table]['types']['typeB']['showitem']);
255 }
256
257 /**
258 * Tests whether fields can be add to all TCA types and duplicate fields are considered.
259 *
260 * @test
261 * @see ExtensionManagementUtility::addToAllTCAtypes()
262 */
263 public function canAddFieldsToAllTCATypesAfterExistingOnes()
264 {
265 $table = $this->getUniqueId('tx_coretest_table');
266 $GLOBALS['TCA'] = $this->generateTCAForTable($table);
267 ExtensionManagementUtility::addToAllTCAtypes($table, 'newA, newA, newB, fieldA', '', 'after:fieldC');
268 // Checking typeA:
269 $this->assertEquals('fieldA, fieldB, fieldC;labelC, newA, newB, --palette--;;paletteC, fieldC1, fieldD, fieldD1', $GLOBALS['TCA'][$table]['types']['typeA']['showitem']);
270 // Checking typeB:
271 $this->assertEquals('fieldA, fieldB, fieldC;labelC, newA, newB, --palette--;;paletteC, fieldC1, fieldD, fieldD1', $GLOBALS['TCA'][$table]['types']['typeB']['showitem']);
272 }
273
274 /**
275 * Tests whether fields can be add to all TCA types and duplicate fields are considered.
276 *
277 * @test
278 * @see ExtensionManagementUtility::addToAllTCAtypes()
279 */
280 public function canAddFieldsToAllTCATypesRespectsPalettes()
281 {
282 $table = $this->getUniqueId('tx_coretest_table');
283 $GLOBALS['TCA'] = $this->generateTCAForTable($table);
284 $GLOBALS['TCA'][$table]['types']['typeD'] = ['showitem' => 'fieldY, --palette--;;standard, fieldZ'];
285 ExtensionManagementUtility::addToAllTCAtypes($table, 'newA, newA, newB, fieldA', '', 'after:--palette--;;standard');
286 // Checking typeD:
287 $this->assertEquals('fieldY, --palette--;;standard, newA, newB, fieldA, fieldZ', $GLOBALS['TCA'][$table]['types']['typeD']['showitem']);
288 }
289
290 /**
291 * Tests whether fields can be add to all TCA types and fields in pallets are respected.
292 *
293 * @test
294 * @see ExtensionManagementUtility::addToAllTCAtypes()
295 */
296 public function canAddFieldsToAllTCATypesRespectsPositionFieldInPalette()
297 {
298 $table = $this->getUniqueId('tx_coretest_table');
299 $GLOBALS['TCA'] = $this->generateTCAForTable($table);
300 ExtensionManagementUtility::addToAllTCAtypes($table, 'newA, newA, newB, fieldA', '', 'after:fieldX1');
301 // Checking typeA:
302 $this->assertEquals('fieldA, fieldB, fieldC;labelC, --palette--;;paletteC, newA, newB, fieldC1, fieldD, fieldD1', $GLOBALS['TCA'][$table]['types']['typeA']['showitem']);
303 }
304
305 /**
306 * Tests whether fields can be add to a TCA type before existing ones
307 *
308 * @test
309 * @see ExtensionManagementUtility::addToAllTCAtypes()
310 */
311 public function canAddFieldsToTCATypeBeforeExistingOnes()
312 {
313 $table = $this->getUniqueId('tx_coretest_table');
314 $GLOBALS['TCA'] = $this->generateTCAForTable($table);
315 ExtensionManagementUtility::addToAllTCAtypes($table, 'newA, newA, newB, fieldA', 'typeA', 'before:fieldD');
316 // Checking typeA:
317 $this->assertEquals('fieldA, fieldB, fieldC;labelC, --palette--;;paletteC, fieldC1, newA, newB, fieldD, fieldD1', $GLOBALS['TCA'][$table]['types']['typeA']['showitem']);
318 // Checking typeB:
319 $this->assertEquals('fieldA, fieldB, fieldC;labelC, --palette--;;paletteC, fieldC1, fieldD, fieldD1', $GLOBALS['TCA'][$table]['types']['typeB']['showitem']);
320 }
321
322 /**
323 * Tests whether fields can be add to a TCA type after existing ones
324 *
325 * @test
326 * @see ExtensionManagementUtility::addToAllTCAtypes()
327 */
328 public function canAddFieldsToTCATypeAfterExistingOnes()
329 {
330 $table = $this->getUniqueId('tx_coretest_table');
331 $GLOBALS['TCA'] = $this->generateTCAForTable($table);
332 ExtensionManagementUtility::addToAllTCAtypes($table, 'newA, newA, newB, fieldA', 'typeA', 'after:fieldC');
333 // Checking typeA:
334 $this->assertEquals('fieldA, fieldB, fieldC;labelC, newA, newB, --palette--;;paletteC, fieldC1, fieldD, fieldD1', $GLOBALS['TCA'][$table]['types']['typeA']['showitem']);
335 // Checking typeB:
336 $this->assertEquals('fieldA, fieldB, fieldC;labelC, --palette--;;paletteC, fieldC1, fieldD, fieldD1', $GLOBALS['TCA'][$table]['types']['typeB']['showitem']);
337 }
338
339 /**
340 * @test
341 */
342 public function canAddFieldWithPartOfAlreadyExistingFieldname()
343 {
344 $table = $this->getUniqueId('tx_coretest_table');
345 $GLOBALS['TCA'] = $this->generateTCAForTable($table);
346 ExtensionManagementUtility::addToAllTCAtypes($table, 'field', 'typeA', 'after:fieldD1');
347
348 $this->assertEquals('fieldA, fieldB, fieldC;labelC, --palette--;;paletteC, fieldC1, fieldD, fieldD1, field', $GLOBALS['TCA'][$table]['types']['typeA']['showitem']);
349 }
350
351 /**
352 * Test wheter replacing other TCA fields works as promissed
353 *
354 * @test
355 * @see ExtensionManagementUtility::addFieldsToAllPalettesOfField()
356 */
357 public function canAddFieldsToTCATypeAndReplaceExistingOnes()
358 {
359 $table = $this->getUniqueId('tx_coretest_table');
360 $GLOBALS['TCA'] = $this->generateTCAForTable($table);
361 $typesBefore = $GLOBALS['TCA'][$table]['types'];
362 ExtensionManagementUtility::addToAllTCAtypes($table, 'fieldZ', '', 'replace:fieldX');
363 $this->assertEquals($typesBefore, $GLOBALS['TCA'][$table]['types'], 'It\'s wrong that the "types" array changes here - the replaced field is only on palettes');
364 // unchanged because the palette is not used
365 $this->assertEquals('fieldX, fieldX1, fieldY', $GLOBALS['TCA'][$table]['palettes']['paletteA']['showitem']);
366 $this->assertEquals('fieldX, fieldX1, fieldY', $GLOBALS['TCA'][$table]['palettes']['paletteB']['showitem']);
367 // changed
368 $this->assertEquals('fieldZ, fieldX1, fieldY', $GLOBALS['TCA'][$table]['palettes']['paletteC']['showitem']);
369 $this->assertEquals('fieldZ, fieldX1, fieldY', $GLOBALS['TCA'][$table]['palettes']['paletteD']['showitem']);
370 }
371
372 /**
373 * @test
374 */
375 public function addToAllTCAtypesReplacesExistingOnes()
376 {
377 $table = $this->getUniqueId('tx_coretest_table');
378 $GLOBALS['TCA'] = $this->generateTCAForTable($table);
379 $typesBefore = $GLOBALS['TCA'][$table]['types'];
380 ExtensionManagementUtility::addToAllTCAtypes($table, 'fieldX, --palette--;;foo', '', 'replace:fieldX');
381 $this->assertEquals($typesBefore, $GLOBALS['TCA'][$table]['types'], 'It\'s wrong that the "types" array changes here - the replaced field is only on palettes');
382 // unchanged because the palette is not used
383 $this->assertEquals('fieldX, fieldX1, fieldY', $GLOBALS['TCA'][$table]['palettes']['paletteA']['showitem']);
384 $this->assertEquals('fieldX, fieldX1, fieldY', $GLOBALS['TCA'][$table]['palettes']['paletteB']['showitem']);
385 // changed
386 $this->assertEquals('fieldX, --palette--;;foo, fieldX1, fieldY', $GLOBALS['TCA'][$table]['palettes']['paletteC']['showitem']);
387 $this->assertEquals('fieldX, --palette--;;foo, fieldX1, fieldY', $GLOBALS['TCA'][$table]['palettes']['paletteD']['showitem']);
388 }
389
390 /**
391 * Tests whether fields can be added to a palette before existing elements.
392 *
393 * @test
394 * @see ExtensionManagementUtility::addFieldsToPalette()
395 */
396 public function canAddFieldsToPaletteBeforeExistingOnes()
397 {
398 $table = $this->getUniqueId('tx_coretest_table');
399 $GLOBALS['TCA'] = $this->generateTCAForTable($table);
400 ExtensionManagementUtility::addFieldsToPalette($table, 'paletteA', 'newA, newA, newB, fieldX', 'before:fieldY');
401 $this->assertEquals('fieldX, fieldX1, newA, newB, fieldY', $GLOBALS['TCA'][$table]['palettes']['paletteA']['showitem']);
402 }
403
404 /**
405 * Tests whether fields can be added to a palette after existing elements.
406 *
407 * @test
408 * @see ExtensionManagementUtility::addFieldsToPalette()
409 */
410 public function canAddFieldsToPaletteAfterExistingOnes()
411 {
412 $table = $this->getUniqueId('tx_coretest_table');
413 $GLOBALS['TCA'] = $this->generateTCAForTable($table);
414 ExtensionManagementUtility::addFieldsToPalette($table, 'paletteA', 'newA, newA, newB, fieldX', 'after:fieldX');
415 $this->assertEquals('fieldX, newA, newB, fieldX1, fieldY', $GLOBALS['TCA'][$table]['palettes']['paletteA']['showitem']);
416 }
417
418 /**
419 * Tests whether fields can be added to a palette after a not existing elements.
420 *
421 * @test
422 * @see ExtensionManagementUtility::addFieldsToPalette()
423 */
424 public function canAddFieldsToPaletteAfterNotExistingOnes()
425 {
426 $table = $this->getUniqueId('tx_coretest_table');
427 $GLOBALS['TCA'] = $this->generateTCAForTable($table);
428 ExtensionManagementUtility::addFieldsToPalette($table, 'paletteA', 'newA, newA, newB, fieldX', 'after:' . $this->getUniqueId('notExisting'));
429 $this->assertEquals('fieldX, fieldX1, fieldY, newA, newB', $GLOBALS['TCA'][$table]['palettes']['paletteA']['showitem']);
430 }
431
432 /**
433 * @return array
434 */
435 public function removeDuplicatesForInsertionRemovesDuplicatesDataProvider()
436 {
437 return [
438 'Simple' => [
439 'field_b, field_d, field_c',
440 'field_a, field_b, field_c',
441 'field_d'
442 ],
443 'with linebreaks' => [
444 'field_b, --linebreak--, field_d, --linebreak--, field_c',
445 'field_a, field_b, field_c',
446 '--linebreak--, field_d, --linebreak--'
447 ],
448 'with linebreaks in list and insertion list' => [
449 'field_b, --linebreak--, field_d, --linebreak--, field_c',
450 'field_a, field_b, --linebreak--, field_c',
451 '--linebreak--, field_d, --linebreak--'
452 ],
453 ];
454 }
455
456 /**
457 * @test
458 * @dataProvider removeDuplicatesForInsertionRemovesDuplicatesDataProvider
459 * @param $insertionList
460 * @param $list
461 * @param $expected
462 */
463 public function removeDuplicatesForInsertionRemovesDuplicates($insertionList, $list, $expected)
464 {
465 $result = ExtensionManagementUtilityAccessibleProxy::removeDuplicatesForInsertion($insertionList, $list);
466 $this->assertSame($expected, $result);
467 }
468
469 ///////////////////////////////////////////////////
470 // Tests concerning addFieldsToAllPalettesOfField
471 ///////////////////////////////////////////////////
472
473 /**
474 * @test
475 */
476 public function addFieldsToAllPalettesOfFieldDoesNotAddAnythingIfFieldIsNotRegisteredInColumns()
477 {
478 $GLOBALS['TCA'] = [
479 'aTable' => [
480 'types' => [
481 'typeA' => [
482 'showitem' => 'fieldA;labelA, --palette--;;paletteA',
483 ],
484 ],
485 'palettes' => [
486 'paletteA' => [
487 'showitem' => 'fieldX, fieldY',
488 ],
489 ],
490 ],
491 ];
492 $expected = $GLOBALS['TCA'];
493 ExtensionManagementUtility::addFieldsToAllPalettesOfField(
494 'aTable',
495 'fieldA',
496 'newA'
497 );
498 $this->assertEquals($expected, $GLOBALS['TCA']);
499 }
500
501 /**
502 * @test
503 */
504 public function addFieldsToAllPalettesOfFieldAddsFieldsToPaletteAndSuppressesDuplicates()
505 {
506 $GLOBALS['TCA'] = [
507 'aTable' => [
508 'columns' => [
509 'fieldA' => [],
510 ],
511 'types' => [
512 'typeA' => [
513 'showitem' => 'fieldA;labelA, --palette--;;paletteA',
514 ],
515 ],
516 'palettes' => [
517 'paletteA' => [
518 'showitem' => 'fieldX, fieldY',
519 ],
520 ],
521 ],
522 ];
523 $expected = [
524 'aTable' => [
525 'columns' => [
526 'fieldA' => [],
527 ],
528 'types' => [
529 'typeA' => [
530 'showitem' => 'fieldA;labelA, --palette--;;paletteA',
531 ],
532 ],
533 'palettes' => [
534 'paletteA' => [
535 'showitem' => 'fieldX, fieldY, dupeA',
536 ],
537 ],
538 ],
539 ];
540 ExtensionManagementUtility::addFieldsToAllPalettesOfField(
541 'aTable',
542 'fieldA',
543 'dupeA, dupeA' // Duplicate
544 );
545 $this->assertEquals($expected, $GLOBALS['TCA']);
546 }
547
548 /**
549 * @test
550 */
551 public function addFieldsToAllPalettesOfFieldDoesNotAddAFieldThatIsPartOfPaletteAlready()
552 {
553 $GLOBALS['TCA'] = [
554 'aTable' => [
555 'columns' => [
556 'fieldA' => [],
557 ],
558 'types' => [
559 'typeA' => [
560 'showitem' => 'fieldA;labelA, --palette--;;paletteA',
561 ],
562 ],
563 'palettes' => [
564 'paletteA' => [
565 'showitem' => 'existingA',
566 ],
567 ],
568 ],
569 ];
570 $expected = [
571 'aTable' => [
572 'columns' => [
573 'fieldA' => [],
574 ],
575 'types' => [
576 'typeA' => [
577 'showitem' => 'fieldA;labelA, --palette--;;paletteA',
578 ],
579 ],
580 'palettes' => [
581 'paletteA' => [
582 'showitem' => 'existingA',
583 ],
584 ],
585 ],
586 ];
587 ExtensionManagementUtility::addFieldsToAllPalettesOfField(
588 'aTable',
589 'fieldA',
590 'existingA'
591 );
592 $this->assertEquals($expected, $GLOBALS['TCA']);
593 }
594
595 /**
596 * @test
597 */
598 public function addFieldsToAllPalettesOfFieldAddsFieldsToMultiplePalettes()
599 {
600 $GLOBALS['TCA'] = [
601 'aTable' => [
602 'columns' => [
603 'fieldA' => [],
604 ],
605 'types' => [
606 'typeA' => [
607 'showitem' => 'fieldA, --palette--;;palette1',
608 ],
609 'typeB' => [
610 'showitem' => 'fieldA;aLabel, --palette--;;palette2',
611 ],
612 ],
613 'palettes' => [
614 'palette1' => [
615 'showitem' => 'fieldX',
616 ],
617 'palette2' => [
618 'showitem' => 'fieldY',
619 ],
620 ],
621 ],
622 ];
623 $expected = [
624 'aTable' => [
625 'columns' => [
626 'fieldA' => [],
627 ],
628 'types' => [
629 'typeA' => [
630 'showitem' => 'fieldA, --palette--;;palette1',
631 ],
632 'typeB' => [
633 'showitem' => 'fieldA;aLabel, --palette--;;palette2',
634 ],
635 ],
636 'palettes' => [
637 'palette1' => [
638 'showitem' => 'fieldX, newA',
639 ],
640 'palette2' => [
641 'showitem' => 'fieldY, newA',
642 ],
643 ],
644 ],
645 ];
646 ExtensionManagementUtility::addFieldsToAllPalettesOfField(
647 'aTable',
648 'fieldA',
649 'newA'
650 );
651 $this->assertEquals($expected, $GLOBALS['TCA']);
652 }
653
654 /**
655 * @test
656 */
657 public function addFieldsToAllPalettesOfFieldAddsMultipleFields()
658 {
659 $GLOBALS['TCA'] = [
660 'aTable' => [
661 'columns' => [
662 'fieldA' => [],
663 ],
664 'types' => [
665 'typeA' => [
666 'showitem' => 'fieldA, --palette--;;palette1',
667 ],
668 ],
669 'palettes' => [
670 'palette1' => [
671 'showitem' => 'fieldX',
672 ],
673 ],
674 ],
675 ];
676 $expected = [
677 'aTable' => [
678 'columns' => [
679 'fieldA' => [],
680 ],
681 'types' => [
682 'typeA' => [
683 'showitem' => 'fieldA, --palette--;;palette1',
684 ],
685 ],
686 'palettes' => [
687 'palette1' => [
688 'showitem' => 'fieldX, newA, newB',
689 ],
690 ],
691 ],
692 ];
693 ExtensionManagementUtility::addFieldsToAllPalettesOfField(
694 'aTable',
695 'fieldA',
696 'newA, newB'
697 );
698 $this->assertEquals($expected, $GLOBALS['TCA']);
699 }
700
701 /**
702 * @test
703 */
704 public function addFieldsToAllPalettesOfFieldAddsBeforeExistingIfRequested()
705 {
706 $GLOBALS['TCA'] = [
707 'aTable' => [
708 'columns' => [
709 'fieldA' => [],
710 ],
711 'types' => [
712 'typeA' => [
713 'showitem' => 'fieldA;labelA, --palette--;;paletteA',
714 ],
715 ],
716 'palettes' => [
717 'paletteA' => [
718 'showitem' => 'existingA, existingB',
719 ],
720 ],
721 ],
722 ];
723 $expected = [
724 'aTable' => [
725 'columns' => [
726 'fieldA' => [],
727 ],
728 'types' => [
729 'typeA' => [
730 'showitem' => 'fieldA;labelA, --palette--;;paletteA',
731 ],
732 ],
733 'palettes' => [
734 'paletteA' => [
735 'showitem' => 'existingA, newA, existingB',
736 ],
737 ],
738 ],
739 ];
740 ExtensionManagementUtility::addFieldsToAllPalettesOfField(
741 'aTable',
742 'fieldA',
743 'newA',
744 'before:existingB'
745 );
746 $this->assertEquals($expected, $GLOBALS['TCA']);
747 }
748
749 /**
750 * @test
751 */
752 public function addFieldsToAllPalettesOfFieldAddsFieldsAtEndIfBeforeRequestedDoesNotExist()
753 {
754 $GLOBALS['TCA'] = [
755 'aTable' => [
756 'columns' => [
757 'fieldA' => [],
758 ],
759 'types' => [
760 'typeA' => [
761 'showitem' => 'fieldA;labelA, --palette--;;paletteA',
762 ],
763 ],
764 'palettes' => [
765 'paletteA' => [
766 'showitem' => 'fieldX, fieldY',
767 ],
768 ],
769 ],
770 ];
771 $expected = [
772 'aTable' => [
773 'columns' => [
774 'fieldA' => [],
775 ],
776 'types' => [
777 'typeA' => [
778 'showitem' => 'fieldA;labelA, --palette--;;paletteA',
779 ],
780 ],
781 'palettes' => [
782 'paletteA' => [
783 'showitem' => 'fieldX, fieldY, newA, newB',
784 ],
785 ],
786 ],
787 ];
788 ExtensionManagementUtility::addFieldsToAllPalettesOfField(
789 'aTable',
790 'fieldA',
791 'newA, newB',
792 'before:notExisting'
793 );
794 $this->assertEquals($expected, $GLOBALS['TCA']);
795 }
796
797 /**
798 * @test
799 */
800 public function addFieldsToAllPalettesOfFieldAddsAfterExistingIfRequested()
801 {
802 $GLOBALS['TCA'] = [
803 'aTable' => [
804 'columns' => [
805 'fieldA' => [],
806 ],
807 'types' => [
808 'typeA' => [
809 'showitem' => 'fieldA;labelA, --palette--;;paletteA',
810 ],
811 ],
812 'palettes' => [
813 'paletteA' => [
814 'showitem' => 'existingA, existingB',
815 ],
816 ],
817 ],
818 ];
819 $expected = [
820 'aTable' => [
821 'columns' => [
822 'fieldA' => [],
823 ],
824 'types' => [
825 'typeA' => [
826 'showitem' => 'fieldA;labelA, --palette--;;paletteA',
827 ],
828 ],
829 'palettes' => [
830 'paletteA' => [
831 'showitem' => 'existingA, newA, existingB',
832 ],
833 ],
834 ],
835 ];
836 ExtensionManagementUtility::addFieldsToAllPalettesOfField(
837 'aTable',
838 'fieldA',
839 'newA',
840 'after:existingA'
841 );
842 $this->assertEquals($expected, $GLOBALS['TCA']);
843 }
844
845 /**
846 * @test
847 */
848 public function addFieldsToAllPalettesOfFieldAddsFieldsAtEndIfAfterRequestedDoesNotExist()
849 {
850 $GLOBALS['TCA'] = [
851 'aTable' => [
852 'columns' => [
853 'fieldA' => [],
854 ],
855 'types' => [
856 'typeA' => [
857 'showitem' => 'fieldA;labelA, --palette--;;paletteA',
858 ],
859 ],
860 'palettes' => [
861 'paletteA' => [
862 'showitem' => 'existingA, existingB',
863 ],
864 ],
865 ],
866 ];
867 $expected = [
868 'aTable' => [
869 'columns' => [
870 'fieldA' => [],
871 ],
872 'types' => [
873 'typeA' => [
874 'showitem' => 'fieldA;labelA, --palette--;;paletteA',
875 ],
876 ],
877 'palettes' => [
878 'paletteA' => [
879 'showitem' => 'existingA, existingB, newA, newB',
880 ],
881 ],
882 ],
883 ];
884 ExtensionManagementUtility::addFieldsToAllPalettesOfField(
885 'aTable',
886 'fieldA',
887 'newA, newB',
888 'after:notExistingA'
889 );
890 $this->assertEquals($expected, $GLOBALS['TCA']);
891 }
892
893 /**
894 * @test
895 */
896 public function addFieldsToAllPalettesOfFieldAddsNewPaletteIfFieldHasNoPaletteYet()
897 {
898 $GLOBALS['TCA'] = [
899 'aTable' => [
900 'columns' => [
901 'fieldA' => [],
902 ],
903 'types' => [
904 'typeA' => [
905 'showitem' => 'fieldA',
906 ],
907 ],
908 ],
909 ];
910 $expected = [
911 'aTable' => [
912 'columns' => [
913 'fieldA' => [],
914 ],
915 'types' => [
916 'typeA' => [
917 'showitem' => 'fieldA, --palette--;;generatedFor-fieldA',
918 ],
919 ],
920 'palettes' => [
921 'generatedFor-fieldA' => [
922 'showitem' => 'newA',
923 ],
924 ],
925 ],
926 ];
927 ExtensionManagementUtility::addFieldsToAllPalettesOfField(
928 'aTable',
929 'fieldA',
930 'newA'
931 );
932 $this->assertEquals($expected, $GLOBALS['TCA']);
933 }
934
935 /**
936 * @test
937 */
938 public function addFieldsToAllPalettesOfFieldAddsNewPaletteIfFieldHasNoPaletteYetAndKeepsExistingLabel()
939 {
940 $GLOBALS['TCA'] = [
941 'aTable' => [
942 'columns' => [
943 'fieldA' => [],
944 ],
945 'types' => [
946 'typeA' => [
947 'showitem' => 'fieldA;labelA',
948 ],
949 ],
950 ],
951 ];
952 $expected = [
953 'aTable' => [
954 'columns' => [
955 'fieldA' => [],
956 ],
957 'types' => [
958 'typeA' => [
959 'showitem' => 'fieldA;labelA, --palette--;;generatedFor-fieldA',
960 ],
961 ],
962 'palettes' => [
963 'generatedFor-fieldA' => [
964 'showitem' => 'newA',
965 ],
966 ],
967 ],
968 ];
969 ExtensionManagementUtility::addFieldsToAllPalettesOfField(
970 'aTable',
971 'fieldA',
972 'newA'
973 );
974 $this->assertEquals($expected, $GLOBALS['TCA']);
975 }
976
977 ///////////////////////////////////////////////////
978 // Tests concerning executePositionedStringInsertion
979 ///////////////////////////////////////////////////
980
981 /**
982 * Data provider for executePositionedStringInsertionTrimsCorrectCharacters
983 * @return array
984 */
985 public function executePositionedStringInsertionTrimsCorrectCharactersDataProvider()
986 {
987 return [
988 'normal characters' => [
989 'tr0',
990 'tr0',
991 ],
992 'newlines' => [
993 "test\n",
994 'test',
995 ],
996 'newlines with carriage return' => [
997 "test\r\n",
998 'test',
999 ],
1000 'tabs' => [
1001 "test\t",
1002 'test',
1003 ],
1004 'commas' => [
1005 'test,',
1006 'test',
1007 ],
1008 'multiple commas with trailing spaces' => [
1009 "test,,\t, \r\n",
1010 'test',
1011 ],
1012 ];
1013 }
1014
1015 /**
1016 * @test
1017 * @dataProvider executePositionedStringInsertionTrimsCorrectCharactersDataProvider
1018 * @param $string
1019 * @param $expectedResult
1020 */
1021 public function executePositionedStringInsertionTrimsCorrectCharacters($string, $expectedResult)
1022 {
1023 $extensionManagementUtility = $this->getAccessibleMock(ExtensionManagementUtility::class, ['dummy']);
1024 $string = $extensionManagementUtility->_call('executePositionedStringInsertion', $string, '');
1025 $this->assertEquals($expectedResult, $string);
1026 }
1027
1028 /////////////////////////////////////////
1029 // Tests concerning addTcaSelectItem
1030 /////////////////////////////////////////
1031 /**
1032 * @test
1033 */
1034 public function addTcaSelectItemThrowsExceptionIfTableIsNotOfTypeString()
1035 {
1036 $this->expectException(\InvalidArgumentException::class);
1037 $this->expectExceptionCode(1303236963);
1038
1039 ExtensionManagementUtility::addTcaSelectItem([], 'foo', []);
1040 }
1041
1042 /**
1043 * @test
1044 */
1045 public function addTcaSelectItemThrowsExceptionIfFieldIsNotOfTypeString()
1046 {
1047 $this->expectException(\InvalidArgumentException::class);
1048 $this->expectExceptionCode(1303236964);
1049
1050 ExtensionManagementUtility::addTcaSelectItem('foo', [], []);
1051 }
1052
1053 /**
1054 * @test
1055 */
1056 public function addTcaSelectItemThrowsExceptionIfRelativeToFieldIsNotOfTypeString()
1057 {
1058 $this->expectException(\InvalidArgumentException::class);
1059 $this->expectExceptionCode(1303236965);
1060
1061 ExtensionManagementUtility::addTcaSelectItem('foo', 'bar', [], []);
1062 }
1063
1064 /**
1065 * @test
1066 */
1067 public function addTcaSelectItemThrowsExceptionIfRelativePositionIsNotOfTypeString()
1068 {
1069 $this->expectException(\InvalidArgumentException::class);
1070 $this->expectExceptionCode(1303236966);
1071
1072 ExtensionManagementUtility::addTcaSelectItem('foo', 'bar', [], 'foo', []);
1073 }
1074
1075 /**
1076 * @test
1077 */
1078 public function addTcaSelectItemThrowsExceptionIfRelativePositionIsNotOneOfValidKeywords()
1079 {
1080 $this->expectException(\InvalidArgumentException::class);
1081 $this->expectExceptionCode(1303236967);
1082
1083 ExtensionManagementUtility::addTcaSelectItem('foo', 'bar', [], 'foo', 'not allowed keyword');
1084 }
1085
1086 /**
1087 * @test
1088 */
1089 public function addTcaSelectItemThrowsExceptionIfFieldIsNotFoundInTca()
1090 {
1091 $this->expectException(\RuntimeException::class);
1092 $this->expectExceptionCode(1303237468);
1093
1094 $GLOBALS['TCA'] = [];
1095 ExtensionManagementUtility::addTcaSelectItem('foo', 'bar', []);
1096 }
1097
1098 /**
1099 * Data provider for addTcaSelectItemInsertsItemAtSpecifiedPosition
1100 */
1101 public function addTcaSelectItemDataProvider()
1102 {
1103 // Every array splits into:
1104 // - relativeToField
1105 // - relativePosition
1106 // - expectedResultArray
1107 return [
1108 'add at end of array' => [
1109 '',
1110 '',
1111 [
1112 0 => ['firstElement'],
1113 1 => ['matchMe'],
1114 2 => ['thirdElement'],
1115 3 => ['insertedElement']
1116 ]
1117 ],
1118 'replace element' => [
1119 'matchMe',
1120 'replace',
1121 [
1122 0 => ['firstElement'],
1123 1 => ['insertedElement'],
1124 2 => ['thirdElement']
1125 ]
1126 ],
1127 'add element after' => [
1128 'matchMe',
1129 'after',
1130 [
1131 0 => ['firstElement'],
1132 1 => ['matchMe'],
1133 2 => ['insertedElement'],
1134 3 => ['thirdElement']
1135 ]
1136 ],
1137 'add element before' => [
1138 'matchMe',
1139 'before',
1140 [
1141 0 => ['firstElement'],
1142 1 => ['insertedElement'],
1143 2 => ['matchMe'],
1144 3 => ['thirdElement']
1145 ]
1146 ],
1147 'add at end if relative position was not found' => [
1148 'notExistingItem',
1149 'after',
1150 [
1151 0 => ['firstElement'],
1152 1 => ['matchMe'],
1153 2 => ['thirdElement'],
1154 3 => ['insertedElement']
1155 ]
1156 ]
1157 ];
1158 }
1159
1160 /**
1161 * @test
1162 * @dataProvider addTcaSelectItemDataProvider
1163 * @param $relativeToField
1164 * @param $relativePosition
1165 * @param $expectedResultArray
1166 */
1167 public function addTcaSelectItemInsertsItemAtSpecifiedPosition($relativeToField, $relativePosition, $expectedResultArray)
1168 {
1169 $GLOBALS['TCA'] = [
1170 'testTable' => [
1171 'columns' => [
1172 'testField' => [
1173 'config' => [
1174 'items' => [
1175 '0' => ['firstElement'],
1176 '1' => ['matchMe'],
1177 2 => ['thirdElement']
1178 ]
1179 ]
1180 ]
1181 ]
1182 ]
1183 ];
1184 ExtensionManagementUtility::addTcaSelectItem('testTable', 'testField', ['insertedElement'], $relativeToField, $relativePosition);
1185 $this->assertEquals($expectedResultArray, $GLOBALS['TCA']['testTable']['columns']['testField']['config']['items']);
1186 }
1187
1188 /////////////////////////////////////////
1189 // Tests concerning loadExtLocalconf
1190 /////////////////////////////////////////
1191 /**
1192 * @test
1193 */
1194 public function loadExtLocalconfDoesNotReadFromCacheIfCachingIsDenied()
1195 {
1196 /** @var CacheManager|\PHPUnit_Framework_MockObject_MockObject $mockCacheManager */
1197 $mockCacheManager = $this->getMockBuilder(CacheManager::class)
1198 ->setMethods(['getCache'])
1199 ->getMock();
1200 $mockCacheManager->expects($this->never())->method('getCache');
1201 ExtensionManagementUtilityAccessibleProxy::setCacheManager($mockCacheManager);
1202 $packageManager = $this->createMockPackageManagerWithMockPackage($this->getUniqueId());
1203 ExtensionManagementUtility::setPackageManager($packageManager);
1204 ExtensionManagementUtility::loadExtLocalconf(false);
1205 }
1206
1207 /**
1208 * @test
1209 */
1210 public function loadExtLocalconfRequiresCacheFileIfExistsAndCachingIsAllowed()
1211 {
1212 $mockCache = $this->getMockBuilder(PhpFrontend::class)
1213 ->setMethods(['getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove', 'flush', 'flushByTag', 'require'])
1214 ->disableOriginalConstructor()
1215 ->getMock();
1216
1217 /** @var CacheManager|\PHPUnit_Framework_MockObject_MockObject $mockCacheManager */
1218 $mockCacheManager = $this->getMockBuilder(CacheManager::class)
1219 ->setMethods(['getCache'])
1220 ->getMock();
1221 $mockCacheManager->expects($this->any())->method('getCache')->will($this->returnValue($mockCache));
1222 ExtensionManagementUtilityAccessibleProxy::setCacheManager($mockCacheManager);
1223 $mockCache->expects($this->any())->method('has')->will($this->returnValue(true));
1224 $mockCache->expects($this->once())->method('require');
1225 ExtensionManagementUtility::loadExtLocalconf(true);
1226 }
1227
1228 /////////////////////////////////////////
1229 // Tests concerning loadSingleExtLocalconfFiles
1230 /////////////////////////////////////////
1231 /**
1232 * @test
1233 */
1234 public function loadSingleExtLocalconfFilesRequiresExtLocalconfFileRegisteredInGlobalTypo3LoadedExt()
1235 {
1236 $this->expectException(\RuntimeException::class);
1237 $this->expectExceptionCode(1340559079);
1238
1239 $extensionName = $this->getUniqueId('foo');
1240 $packageManager = $this->createMockPackageManagerWithMockPackage($extensionName);
1241 $extLocalconfLocation = $packageManager->getPackage($extensionName)->getPackagePath() . 'ext_localconf.php';
1242 file_put_contents($extLocalconfLocation, "<?php\n\nthrow new RuntimeException('', 1340559079);\n\n?>");
1243 ExtensionManagementUtility::setPackageManager($packageManager);
1244 ExtensionManagementUtilityAccessibleProxy::loadSingleExtLocalconfFiles();
1245 }
1246
1247 /////////////////////////////////////////
1248 // Tests concerning addModule
1249 /////////////////////////////////////////
1250
1251 /**
1252 * Data provider for addModule tests
1253 * @return array
1254 */
1255 public function addModulePositionTestsDataProvider()
1256 {
1257 return [
1258 'can add new main module if none exists' => [
1259 'top',
1260 '',
1261 'newModule'
1262 ],
1263 'can add new sub module if no position specified' => [
1264 '',
1265 'some,modules',
1266 'some,modules,newModule'
1267 ],
1268 'can add new sub module to top of module' => [
1269 'top',
1270 'some,modules',
1271 'newModule,some,modules'
1272 ],
1273 'can add new sub module if bottom of module' => [
1274 'bottom',
1275 'some,modules',
1276 'some,modules,newModule'
1277 ],
1278 'can add new sub module before specified sub module' => [
1279 'before:modules',
1280 'some,modules',
1281 'some,newModule,modules'
1282 ],
1283 'can add new sub module after specified sub module' => [
1284 'after:some',
1285 'some,modules',
1286 'some,newModule,modules'
1287 ],
1288 'can add new sub module at the bottom if specified sub module to add before does not exist' => [
1289 'before:modules',
1290 'some,otherModules',
1291 'some,otherModules,newModule'
1292 ],
1293 'can add new sub module at the bottom if specified sub module to add after does not exist' => [
1294 'after:some',
1295 'someOther,modules',
1296 'someOther,modules,newModule'
1297 ],
1298 ];
1299 }
1300
1301 /**
1302 * @test
1303 * @dataProvider addModulePositionTestsDataProvider
1304 * @param $position
1305 * @param $existing
1306 * @param $expected
1307 */
1308 public function addModuleCanAddModule($position, $existing, $expected)
1309 {
1310 $mainModule = 'foobar';
1311 $subModule = 'newModule';
1312 if ($existing) {
1313 $GLOBALS['TBE_MODULES'][$mainModule] = $existing;
1314 }
1315
1316 ExtensionManagementUtility::addModule($mainModule, $subModule, $position);
1317
1318 $this->assertTrue(isset($GLOBALS['TBE_MODULES'][$mainModule]));
1319 $this->assertEquals($expected, $GLOBALS['TBE_MODULES'][$mainModule]);
1320 }
1321
1322 /////////////////////////////////////////
1323 // Tests concerning createExtLocalconfCacheEntry
1324 /////////////////////////////////////////
1325 /**
1326 * @test
1327 */
1328 public function createExtLocalconfCacheEntryWritesCacheEntryWithContentOfLoadedExtensionExtLocalconf()
1329 {
1330 $extensionName = $this->getUniqueId('foo');
1331 $packageManager = $this->createMockPackageManagerWithMockPackage($extensionName);
1332 $extLocalconfLocation = $packageManager->getPackage($extensionName)->getPackagePath() . 'ext_localconf.php';
1333 $uniqueStringInLocalconf = $this->getUniqueId('foo');
1334 file_put_contents($extLocalconfLocation, "<?php\n\n" . $uniqueStringInLocalconf . "\n\n?>");
1335 ExtensionManagementUtility::setPackageManager($packageManager);
1336 $mockCache = $this->getMockBuilder(PhpFrontend::class)
1337 ->setMethods(['getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove', 'flush', 'flushByTag', 'require'])
1338 ->disableOriginalConstructor()
1339 ->getMock();
1340
1341 /** @var CacheManager|\PHPUnit_Framework_MockObject_MockObject $mockCacheManager */
1342 $mockCacheManager = $this->getMockBuilder(CacheManager::class)
1343 ->setMethods(['getCache'])
1344 ->getMock();
1345 $mockCacheManager->expects($this->any())->method('getCache')->will($this->returnValue($mockCache));
1346 ExtensionManagementUtilityAccessibleProxy::setCacheManager($mockCacheManager);
1347 $mockCache->expects($this->once())->method('set')->with($this->anything(), $this->stringContains($uniqueStringInLocalconf), $this->anything());
1348 ExtensionManagementUtilityAccessibleProxy::createExtLocalconfCacheEntry();
1349 }
1350
1351 /**
1352 * @test
1353 */
1354 public function createExtLocalconfCacheEntryWritesCacheEntryWithExtensionContentOnlyIfExtLocalconfExists()
1355 {
1356 $extensionName = $this->getUniqueId('foo');
1357 $packageManager = $this->createMockPackageManagerWithMockPackage($extensionName);
1358 ExtensionManagementUtility::setPackageManager($packageManager);
1359 $mockCache = $this->getMockBuilder(PhpFrontend::class)
1360 ->setMethods(['getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove', 'flush', 'flushByTag', 'require'])
1361 ->disableOriginalConstructor()
1362 ->getMock();
1363
1364 /** @var CacheManager|\PHPUnit_Framework_MockObject_MockObject $mockCacheManager */
1365 $mockCacheManager = $this->getMockBuilder(CacheManager::class)
1366 ->setMethods(['getCache'])
1367 ->getMock();
1368 $mockCacheManager->expects($this->any())->method('getCache')->will($this->returnValue($mockCache));
1369 ExtensionManagementUtilityAccessibleProxy::setCacheManager($mockCacheManager);
1370 $mockCache->expects($this->once())
1371 ->method('set')
1372 ->with($this->anything(), $this->logicalNot($this->stringContains($extensionName)), $this->anything());
1373 ExtensionManagementUtilityAccessibleProxy::createExtLocalconfCacheEntry();
1374 }
1375
1376 /**
1377 * @test
1378 */
1379 public function createExtLocalconfCacheEntryWritesCacheEntryWithNoTags()
1380 {
1381 $mockCache = $this->getMockBuilder(PhpFrontend::class)
1382 ->setMethods(['getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove', 'flush', 'flushByTag', 'require'])
1383 ->disableOriginalConstructor()
1384 ->getMock();
1385
1386 /** @var CacheManager|\PHPUnit_Framework_MockObject_MockObject $mockCacheManager */
1387 $mockCacheManager = $this->getMockBuilder(CacheManager::class)
1388 ->setMethods(['getCache'])
1389 ->getMock();
1390 $mockCacheManager->expects($this->any())->method('getCache')->will($this->returnValue($mockCache));
1391 ExtensionManagementUtilityAccessibleProxy::setCacheManager($mockCacheManager);
1392 $mockCache->expects($this->once())->method('set')->with($this->anything(), $this->anything(), $this->equalTo([]));
1393 $packageManager = $this->createMockPackageManagerWithMockPackage($this->getUniqueId());
1394 ExtensionManagementUtility::setPackageManager($packageManager);
1395 ExtensionManagementUtilityAccessibleProxy::createExtLocalconfCacheEntry();
1396 }
1397
1398 /////////////////////////////////////////
1399 // Tests concerning getExtLocalconfCacheIdentifier
1400 /////////////////////////////////////////
1401 /**
1402 * @test
1403 */
1404 public function getExtLocalconfCacheIdentifierCreatesSha1WithFourtyCharactersAndPrefix()
1405 {
1406 $prefix = 'ext_localconf_';
1407 $identifier = ExtensionManagementUtilityAccessibleProxy::getExtLocalconfCacheIdentifier();
1408 $this->assertStringStartsWith($prefix, $identifier);
1409 $sha1 = str_replace($prefix, '', $identifier);
1410 $this->assertEquals(40, strlen($sha1));
1411 }
1412
1413 /////////////////////////////////////////
1414 // Tests concerning loadBaseTca
1415 /////////////////////////////////////////
1416
1417 /**
1418 * @test
1419 */
1420 public function loadBaseTcaDoesNotReadFromCacheIfCachingIsDenied()
1421 {
1422 /** @var CacheManager|\PHPUnit_Framework_MockObject_MockObject $mockCacheManager */
1423 $mockCacheManager = $this->getMockBuilder(CacheManager::class)
1424 ->setMethods(['getCache'])
1425 ->getMock();
1426 $mockCacheManager->expects($this->never())->method('getCache');
1427 ExtensionManagementUtilityAccessibleProxy::setCacheManager($mockCacheManager);
1428 ExtensionManagementUtilityAccessibleProxy::loadBaseTca(false);
1429 }
1430
1431 /**
1432 * @test
1433 */
1434 public function loadBaseTcaRequiresCacheFileIfExistsAndCachingIsAllowed()
1435 {
1436 $mockCache = $this->getMockBuilder(PhpFrontend::class)
1437 ->setMethods(['getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove', 'flush', 'flushByTag', 'require'])
1438 ->disableOriginalConstructor()
1439 ->getMock();
1440
1441 /** @var CacheManager|\PHPUnit_Framework_MockObject_MockObject $mockCacheManager */
1442 $mockCacheManager = $this->getMockBuilder(CacheManager::class)
1443 ->setMethods(['getCache'])
1444 ->getMock();
1445 $mockCacheManager->expects($this->any())->method('getCache')->will($this->returnValue($mockCache));
1446 ExtensionManagementUtilityAccessibleProxy::setCacheManager($mockCacheManager);
1447 $mockCache->expects($this->once())->method('require')->willReturn(['tca' => [], 'categoryRegistry' => \serialize(CategoryRegistry::getInstance())]);
1448 ExtensionManagementUtilityAccessibleProxy::loadBaseTca(true);
1449 }
1450
1451 /**
1452 * @test
1453 */
1454 public function loadBaseTcaCreatesCacheFileWithContentOfAnExtensionsConfigurationTcaPhpFile()
1455 {
1456 $extensionName = $this->getUniqueId('test_baseTca_');
1457 $packageManager = $this->createMockPackageManagerWithMockPackage($extensionName);
1458 $packagePath = $packageManager->getPackage($extensionName)->getPackagePath();
1459 GeneralUtility::mkdir($packagePath);
1460 GeneralUtility::mkdir($packagePath . 'Configuration/');
1461 GeneralUtility::mkdir($packagePath . 'Configuration/TCA/');
1462 ExtensionManagementUtility::setPackageManager($packageManager);
1463 $uniqueTableName = $this->getUniqueId('table_name_');
1464 $uniqueStringInTableConfiguration = $this->getUniqueId('table_configuration_');
1465 $tableConfiguration = '<?php return array(\'foo\' => \'' . $uniqueStringInTableConfiguration . '\'); ?>';
1466 file_put_contents($packagePath . 'Configuration/TCA/' . $uniqueTableName . '.php', $tableConfiguration);
1467 $mockCache = $this->getMockBuilder(PhpFrontend::class)
1468 ->setMethods(['getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove', 'flush', 'flushByTag', 'require'])
1469 ->disableOriginalConstructor()
1470 ->getMock();
1471
1472 /** @var CacheManager|\PHPUnit_Framework_MockObject_MockObject $mockCacheManager */
1473 $mockCacheManager = $this->getMockBuilder(CacheManager::class)
1474 ->setMethods(['getCache'])
1475 ->getMock();
1476 $mockCacheManager->expects($this->any())->method('getCache')->will($this->returnValue($mockCache));
1477 ExtensionManagementUtilityAccessibleProxy::setCacheManager($mockCacheManager);
1478 $mockCache->expects($this->once())->method('require')->will($this->returnValue(false));
1479 $mockCache->expects($this->once())->method('set')->with($this->anything(), $this->stringContains($uniqueStringInTableConfiguration), $this->anything());
1480 ExtensionManagementUtility::loadBaseTca(true);
1481 }
1482
1483 /**
1484 * @test
1485 */
1486 public function loadBaseTcaWritesCacheEntryWithNoTags()
1487 {
1488 $mockCache = $this->getMockBuilder(PhpFrontend::class)
1489 ->setMethods(['getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove', 'flush', 'flushByTag', 'require'])
1490 ->disableOriginalConstructor()
1491 ->getMock();
1492
1493 /** @var CacheManager|\PHPUnit_Framework_MockObject_MockObject $mockCacheManager */
1494 $mockCacheManager = $this->getMockBuilder(CacheManager::class)
1495 ->setMethods(['getCache'])
1496 ->getMock();
1497 $mockCacheManager->expects($this->any())->method('getCache')->will($this->returnValue($mockCache));
1498 ExtensionManagementUtilityAccessibleProxy::setCacheManager($mockCacheManager);
1499 $mockCache->expects($this->once())->method('require')->will($this->returnValue(false));
1500 $mockCache->expects($this->once())->method('set')->with($this->anything(), $this->anything(), $this->equalTo([]));
1501 ExtensionManagementUtilityAccessibleProxy::loadBaseTca();
1502 }
1503
1504 /////////////////////////////////////////
1505 // Tests concerning getBaseTcaCacheIdentifier
1506 /////////////////////////////////////////
1507
1508 /**
1509 * @test
1510 */
1511 public function getBaseTcaCacheIdentifierCreatesSha1WithFourtyCharactersAndPrefix()
1512 {
1513 $prefix = 'tca_base_';
1514 $identifier = ExtensionManagementUtilityAccessibleProxy::getBaseTcaCacheIdentifier();
1515 $this->assertStringStartsWith($prefix, $identifier);
1516 $sha1 = str_replace($prefix, '', $identifier);
1517 $this->assertEquals(40, strlen($sha1));
1518 }
1519
1520 /////////////////////////////////////////
1521 // Tests concerning loadExtTables
1522 /////////////////////////////////////////
1523 /**
1524 * @test
1525 */
1526 public function loadExtTablesDoesNotReadFromCacheIfCachingIsDenied()
1527 {
1528 /** @var CacheManager|\PHPUnit_Framework_MockObject_MockObject $mockCacheManager */
1529 $mockCacheManager = $this->getMockBuilder(CacheManager::class)
1530 ->setMethods(['getCache'])
1531 ->getMock();
1532 $mockCacheManager->expects($this->never())->method('getCache');
1533 ExtensionManagementUtilityAccessibleProxy::setCacheManager($mockCacheManager);
1534 $packageManager = $this->createMockPackageManagerWithMockPackage($this->getUniqueId());
1535 ExtensionManagementUtility::setPackageManager($packageManager);
1536 ExtensionManagementUtility::loadExtLocalconf(false);
1537 }
1538
1539 /**
1540 * @test
1541 */
1542 public function loadExtTablesRequiresCacheFileIfExistsAndCachingIsAllowed()
1543 {
1544 $mockCache = $this->getMockBuilder(PhpFrontend::class)
1545 ->setMethods(['getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove', 'flush', 'flushByTag', 'require'])
1546 ->disableOriginalConstructor()
1547 ->getMock();
1548
1549 /** @var CacheManager|\PHPUnit_Framework_MockObject_MockObject $mockCacheManager */
1550 $mockCacheManager = $this->getMockBuilder(CacheManager::class)
1551 ->setMethods(['getCache'])
1552 ->getMock();
1553 $mockCacheManager->expects($this->any())->method('getCache')->will($this->returnValue($mockCache));
1554 ExtensionManagementUtilityAccessibleProxy::setCacheManager($mockCacheManager);
1555 $mockCache->expects($this->any())->method('has')->will($this->returnValue(true));
1556 $mockCache->expects($this->once())->method('require');
1557 // Reset the internal cache access tracking variable of extMgm
1558 // This method is only in the ProxyClass!
1559 ExtensionManagementUtilityAccessibleProxy::resetExtTablesWasReadFromCacheOnceBoolean();
1560 ExtensionManagementUtility::loadExtTables(true);
1561 }
1562
1563 /////////////////////////////////////////
1564 // Tests concerning createExtTablesCacheEntry
1565 /////////////////////////////////////////
1566 /**
1567 * @test
1568 */
1569 public function createExtTablesCacheEntryWritesCacheEntryWithContentOfLoadedExtensionExtTables()
1570 {
1571 $extensionName = $this->getUniqueId('foo');
1572 $packageManager = $this->createMockPackageManagerWithMockPackage($extensionName);
1573 $extensionPath = $packageManager->getPackage($extensionName)->getPackagePath();
1574 $extTablesLocation = $extensionPath . 'ext_tables.php';
1575 $uniqueStringInTables = $this->getUniqueId('foo');
1576 file_put_contents($extTablesLocation, "<?php\n\n$uniqueStringInTables\n\n?>");
1577 ExtensionManagementUtility::setPackageManager($packageManager);
1578 $mockCache = $this->getMockBuilder(PhpFrontend::class)
1579 ->setMethods(['getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove', 'flush', 'flushByTag', 'require'])
1580 ->disableOriginalConstructor()
1581 ->getMock();
1582
1583 /** @var CacheManager|\PHPUnit_Framework_MockObject_MockObject $mockCacheManager */
1584 $mockCacheManager = $this->getMockBuilder(CacheManager::class)
1585 ->setMethods(['getCache'])
1586 ->getMock();
1587 $mockCacheManager->expects($this->any())->method('getCache')->will($this->returnValue($mockCache));
1588 ExtensionManagementUtilityAccessibleProxy::setCacheManager($mockCacheManager);
1589 $mockCache->expects($this->once())->method('set')->with($this->anything(), $this->stringContains($uniqueStringInTables), $this->anything());
1590 ExtensionManagementUtilityAccessibleProxy::createExtTablesCacheEntry();
1591 }
1592
1593 /**
1594 * @test
1595 */
1596 public function createExtTablesCacheEntryWritesCacheEntryWithExtensionContentOnlyIfExtTablesExists()
1597 {
1598 $extensionName = $this->getUniqueId('foo');
1599 $packageManager = $this->createMockPackageManagerWithMockPackage($extensionName);
1600 ExtensionManagementUtility::setPackageManager($packageManager);
1601 $mockCache = $this->getMockBuilder(PhpFrontend::class)
1602 ->setMethods(['getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove', 'flush', 'flushByTag', 'require'])
1603 ->disableOriginalConstructor()
1604 ->getMock();
1605
1606 /** @var CacheManager|\PHPUnit_Framework_MockObject_MockObject $mockCacheManager */
1607 $mockCacheManager = $this->getMockBuilder(CacheManager::class)
1608 ->setMethods(['getCache'])
1609 ->getMock();
1610 $mockCacheManager->expects($this->any())->method('getCache')->will($this->returnValue($mockCache));
1611 ExtensionManagementUtilityAccessibleProxy::setCacheManager($mockCacheManager);
1612 $mockCache->expects($this->once())
1613 ->method('set')
1614 ->with($this->anything(), $this->logicalNot($this->stringContains($extensionName)), $this->anything());
1615 ExtensionManagementUtilityAccessibleProxy::createExtTablesCacheEntry();
1616 }
1617
1618 /**
1619 * @test
1620 */
1621 public function createExtTablesCacheEntryWritesCacheEntryWithNoTags()
1622 {
1623 $mockCache = $this->getMockBuilder(PhpFrontend::class)
1624 ->setMethods(['getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove', 'flush', 'flushByTag', 'require'])
1625 ->disableOriginalConstructor()
1626 ->getMock();
1627
1628 /** @var CacheManager|\PHPUnit_Framework_MockObject_MockObject $mockCacheManager */
1629 $mockCacheManager = $this->getMockBuilder(CacheManager::class)
1630 ->setMethods(['getCache'])
1631 ->getMock();
1632 $mockCacheManager->expects($this->any())->method('getCache')->will($this->returnValue($mockCache));
1633 ExtensionManagementUtilityAccessibleProxy::setCacheManager($mockCacheManager);
1634 $mockCache->expects($this->once())->method('set')->with($this->anything(), $this->anything(), $this->equalTo([]));
1635 $packageManager = $this->createMockPackageManagerWithMockPackage($this->getUniqueId());
1636 ExtensionManagementUtility::setPackageManager($packageManager);
1637 ExtensionManagementUtilityAccessibleProxy::createExtTablesCacheEntry();
1638 }
1639
1640 /////////////////////////////////////////
1641 // Tests concerning getExtTablesCacheIdentifier
1642 /////////////////////////////////////////
1643 /**
1644 * @test
1645 */
1646 public function getExtTablesCacheIdentifierCreatesSha1WithFourtyCharactersAndPrefix()
1647 {
1648 $prefix = 'ext_tables_';
1649 $identifier = ExtensionManagementUtilityAccessibleProxy::getExtTablesCacheIdentifier();
1650 $this->assertStringStartsWith($prefix, $identifier);
1651 $sha1 = str_replace($prefix, '', $identifier);
1652 $this->assertEquals(40, strlen($sha1));
1653 }
1654
1655 /////////////////////////////////////////
1656 // Tests concerning getExtensionVersion
1657 /////////////////////////////////////////
1658 /**
1659 * Data provider for negative getExtensionVersion() tests.
1660 *
1661 * @return array
1662 */
1663 public function getExtensionVersionFaultyDataProvider()
1664 {
1665 return [
1666 [''],
1667 [0],
1668 [new \stdClass()],
1669 [true]
1670 ];
1671 }
1672
1673 /**
1674 * @test
1675 * @dataProvider getExtensionVersionFaultyDataProvider
1676 * @param $key
1677 * @throws \TYPO3\CMS\Core\Package\Exception
1678 */
1679 public function getExtensionVersionForFaultyExtensionKeyThrowsException($key)
1680 {
1681 $this->expectException(\InvalidArgumentException::class);
1682 $this->expectExceptionCode(1294586096);
1683
1684 ExtensionManagementUtility::getExtensionVersion($key);
1685 }
1686
1687 /**
1688 * @test
1689 */
1690 public function getExtensionVersionForNotLoadedExtensionReturnsEmptyString()
1691 {
1692 ExtensionManagementUtility::clearExtensionKeyMap();
1693 $uniqueSuffix = $this->getUniqueId('test');
1694 $extensionKey = 'unloadedextension' . $uniqueSuffix;
1695 $this->assertEquals('', ExtensionManagementUtility::getExtensionVersion($extensionKey));
1696 }
1697
1698 /**
1699 * @test
1700 */
1701 public function getExtensionVersionForLoadedExtensionReturnsExtensionVersion()
1702 {
1703 ExtensionManagementUtility::clearExtensionKeyMap();
1704 $uniqueSuffix = $this->getUniqueId('test');
1705 $extensionKey = 'unloadedextension' . $uniqueSuffix;
1706 $packageMetaData = $this->getMockBuilder(MetaData::class)
1707 ->setMethods(['getVersion'])
1708 ->setConstructorArgs([$extensionKey])
1709 ->getMock();
1710 $packageMetaData->expects($this->any())->method('getVersion')->will($this->returnValue('1.2.3'));
1711 $packageManager = $this->createMockPackageManagerWithMockPackage($extensionKey, ['getPackagePath', 'getPackageKey', 'getPackageMetaData']);
1712 /** @var \PHPUnit_Framework_MockObject_MockObject $package */
1713 $package = $packageManager->getPackage($extensionKey);
1714 $package->expects($this->any())
1715 ->method('getPackageMetaData')
1716 ->will($this->returnValue($packageMetaData));
1717 ExtensionManagementUtility::setPackageManager($packageManager);
1718 $this->assertEquals('1.2.3', ExtensionManagementUtility::getExtensionVersion($extensionKey));
1719 }
1720
1721 /////////////////////////////////////////
1722 // Tests concerning loadExtension
1723 /////////////////////////////////////////
1724 /**
1725 * @test
1726 */
1727 public function loadExtensionThrowsExceptionIfExtensionIsLoaded()
1728 {
1729 $this->expectException(\RuntimeException::class);
1730 $this->expectExceptionCode(1342345486);
1731
1732 $extensionKey = $this->getUniqueId('test');
1733 $packageManager = $this->createMockPackageManagerWithMockPackage($extensionKey);
1734 ExtensionManagementUtility::setPackageManager($packageManager);
1735 ExtensionManagementUtility::loadExtension($extensionKey);
1736 }
1737
1738 /////////////////////////////////////////
1739 // Tests concerning unloadExtension
1740 /////////////////////////////////////////
1741 /**
1742 * @test
1743 */
1744 public function unloadExtensionThrowsExceptionIfExtensionIsNotLoaded()
1745 {
1746 $this->expectException(\RuntimeException::class);
1747 $this->expectExceptionCode(1342345487);
1748
1749 $packageName = $this->getUniqueId('foo');
1750 /** @var PackageManager|\PHPUnit_Framework_MockObject_MockObject $packageManager */
1751 $packageManager = $this->getMockBuilder(PackageManager::class)
1752 ->setMethods(['isPackageActive'])
1753 ->disableOriginalConstructor()
1754 ->getMock();
1755 $packageManager->expects($this->once())
1756 ->method('isPackageActive')
1757 ->with($this->equalTo($packageName))
1758 ->will($this->returnValue(false));
1759 ExtensionManagementUtility::setPackageManager($packageManager);
1760 ExtensionManagementUtility::unloadExtension($packageName);
1761 }
1762
1763 /**
1764 * @test
1765 */
1766 public function unloadExtensionCallsPackageManagerToDeactivatePackage()
1767 {
1768 $packageName = $this->getUniqueId('foo');
1769 /** @var PackageManager|\PHPUnit_Framework_MockObject_MockObject $packageManager */
1770 $packageManager = $this->getMockBuilder(PackageManager::class)
1771 ->setMethods(['isPackageActive', 'deactivatePackage'])
1772 ->disableOriginalConstructor()
1773 ->getMock();
1774 $packageManager->expects($this->any())
1775 ->method('isPackageActive')
1776 ->will($this->returnValue(true));
1777 $packageManager->expects($this->once())
1778 ->method('deactivatePackage')
1779 ->with($packageName);
1780 ExtensionManagementUtility::setPackageManager($packageManager);
1781 ExtensionManagementUtility::unloadExtension($packageName);
1782 }
1783
1784 /////////////////////////////////////////
1785 // Tests concerning makeCategorizable
1786 /////////////////////////////////////////
1787 /**
1788 * @test
1789 */
1790 public function doesMakeCategorizableCallsTheCategoryRegistryWithDefaultFieldName()
1791 {
1792 $extensionKey = $this->getUniqueId('extension');
1793 $tableName = $this->getUniqueId('table');
1794
1795 /** @var CategoryRegistry|\PHPUnit_Framework_MockObject_MockObject $registryMock */
1796 $registryMock = $this->getMockBuilder(CategoryRegistry::class)->getMock();
1797 $registryMock->expects($this->once())->method('add')->with($extensionKey, $tableName, 'categories', []);
1798 GeneralUtility::setSingletonInstance(CategoryRegistry::class, $registryMock);
1799 ExtensionManagementUtility::makeCategorizable($extensionKey, $tableName);
1800 }
1801
1802 /**
1803 * @test
1804 */
1805 public function doesMakeCategorizableCallsTheCategoryRegistryWithFieldName()
1806 {
1807 $extensionKey = $this->getUniqueId('extension');
1808 $tableName = $this->getUniqueId('table');
1809 $fieldName = $this->getUniqueId('field');
1810
1811 /** @var CategoryRegistry|\PHPUnit_Framework_MockObject_MockObject $registryMock */
1812 $registryMock = $this->getMockBuilder(CategoryRegistry::class)->getMock();
1813 $registryMock->expects($this->once())->method('add')->with($extensionKey, $tableName, $fieldName, []);
1814 GeneralUtility::setSingletonInstance(CategoryRegistry::class, $registryMock);
1815 ExtensionManagementUtility::makeCategorizable($extensionKey, $tableName, $fieldName);
1816 }
1817
1818 ///////////////////////////////
1819 // Tests concerning addPlugin
1820 ///////////////////////////////
1821
1822 /**
1823 * @test
1824 */
1825 public function addPluginSetsTcaCorrectlyForGivenExtKeyAsParameter()
1826 {
1827 $extKey = 'indexed_search';
1828 $expectedTCA = [
1829 [
1830 'label',
1831 $extKey,
1832 'EXT:' . $extKey . '/Resources/Public/Icons/Extension.png'
1833 ]
1834 ];
1835 $GLOBALS['TCA']['tt_content']['columns']['list_type']['config']['items'] = [];
1836 ExtensionManagementUtility::addPlugin(['label', $extKey], 'list_type', $extKey);
1837 $this->assertEquals($expectedTCA, $GLOBALS['TCA']['tt_content']['columns']['list_type']['config']['items']);
1838 }
1839
1840 /**
1841 * @test
1842 */
1843 public function addPluginThrowsExceptionForMissingExtkey()
1844 {
1845 $this->expectException(\InvalidArgumentException::class);
1846 $this->expectExceptionCode(1404068038);
1847
1848 ExtensionManagementUtility::addPlugin('test');
1849 }
1850 }