TYPO3 CMS  TYPO3_8-7
ExtensionManagementUtilityTest.php
Go to the documentation of this file.
1 <?php
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 
28 
32 class ExtensionManagementUtilityTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
33 {
37  protected $singletonInstances = [];
38 
43 
44  protected function setUp()
45  {
46  $this->singletonInstances = GeneralUtility::getSingletonInstances();
48  $this->singletonInstances = GeneralUtility::getSingletonInstances();
49  }
50 
51  protected function tearDown()
52  {
56  $GLOBALS['TYPO3_LOADED_EXT'] = new LoadedExtensionsArray($this->backUpPackageManager);
57  GeneralUtility::resetSingletonInstances($this->singletonInstances);
58  parent::tearDown();
59  }
60 
66  protected function createMockPackageManagerWithMockPackage($packageKey, $packageMethods = ['getPackagePath', 'getPackageKey'])
67  {
68  $packagePath = PATH_site . 'typo3temp/var/tests/' . $packageKey . '/';
69  GeneralUtility::mkdir_deep($packagePath);
70  $this->testFilesToDelete[] = $packagePath;
71  $package = $this->getMockBuilder(Package::class)
72  ->disableOriginalConstructor()
73  ->setMethods($packageMethods)
74  ->getMock();
75  $packageManager = $this->getMockBuilder(PackageManager::class)
76  ->setMethods(['isPackageActive', 'getPackage', 'getActivePackages'])
77  ->getMock();
78  $package->expects($this->any())
79  ->method('getPackagePath')
80  ->will($this->returnValue($packagePath));
81  $package->expects($this->any())
82  ->method('getPackageKey')
83  ->will($this->returnValue($packageKey));
84  $packageManager->expects($this->any())
85  ->method('isPackageActive')
86  ->will($this->returnValueMap([
87  [null, false],
88  [$packageKey, true]
89  ]));
90  $packageManager->expects($this->any())
91  ->method('getPackage')
92  ->with($this->equalTo($packageKey))
93  ->will($this->returnValue($package));
94  $packageManager->expects($this->any())
95  ->method('getActivePackages')
96  ->will($this->returnValue([$packageKey => $package]));
97  return $packageManager;
98  }
99 
101  // Tests concerning isLoaded
103 
107  {
108  $this->assertFalse(ExtensionManagementUtility::isLoaded($this->getUniqueId('foobar'), false));
109  }
110 
115  {
116  $this->expectException(\BadFunctionCallException::class);
117  $this->expectExceptionCode(1270853910);
118 
119  $this->assertFalse(ExtensionManagementUtility::isLoaded($this->getUniqueId('foobar'), true));
120  }
121 
123  // Tests concerning extPath
125 
128  public function extPathThrowsExceptionIfExtensionIsNotLoaded()
129  {
130  $this->expectException(\BadFunctionCallException::class);
131  $this->expectExceptionCode(1365429656);
132 
133  $packageName = $this->getUniqueId('foo');
135  $packageManager = $this->getMockBuilder(PackageManager::class)
136  ->setMethods(['isPackageActive'])
137  ->getMock();
138  $packageManager->expects($this->once())
139  ->method('isPackageActive')
140  ->with($this->equalTo($packageName))
141  ->will($this->returnValue(false));
144  }
145 
149  public function extPathAppendsScriptNameToPath()
150  {
151  $package = $this->getMockBuilder(Package::class)
152  ->disableOriginalConstructor()
153  ->setMethods(['getPackagePath'])
154  ->getMock();
156  $packageManager = $this->getMockBuilder(PackageManager::class)
157  ->setMethods(['isPackageActive', 'getPackage'])
158  ->getMock();
159  $package->expects($this->once())
160  ->method('getPackagePath')
161  ->will($this->returnValue(PATH_site . 'foo/'));
162  $packageManager->expects($this->once())
163  ->method('isPackageActive')
164  ->with($this->equalTo('foo'))
165  ->will($this->returnValue(true));
166  $packageManager->expects($this->once())
167  ->method('getPackage')
168  ->with('foo')
169  ->will($this->returnValue($package));
171  $this->assertSame(PATH_site . 'foo/bar.txt', ExtensionManagementUtility::extPath('foo', 'bar.txt'));
172  }
173 
175  // Utility functions
177 
183  private function generateTCAForTable($table)
184  {
185  $tca = [];
186  $tca[$table] = [];
187  $tca[$table]['columns'] = [
188  'fieldA' => [],
189  'fieldC' => []
190  ];
191  $tca[$table]['types'] = [
192  'typeA' => ['showitem' => 'fieldA, fieldB, fieldC;labelC, --palette--;;paletteC, fieldC1, fieldD, fieldD1'],
193  'typeB' => ['showitem' => 'fieldA, fieldB, fieldC;labelC, --palette--;;paletteC, fieldC1, fieldD, fieldD1'],
194  'typeC' => ['showitem' => 'fieldC;;paletteD']
195  ];
196  $tca[$table]['palettes'] = [
197  'paletteA' => ['showitem' => 'fieldX, fieldX1, fieldY'],
198  'paletteB' => ['showitem' => 'fieldX, fieldX1, fieldY'],
199  'paletteC' => ['showitem' => 'fieldX, fieldX1, fieldY'],
200  'paletteD' => ['showitem' => 'fieldX, fieldX1, fieldY']
201  ];
202  return $tca;
203  }
204 
210  public function extensionKeyDataProvider()
211  {
212  return [
213  'Without underscores' => [
214  'testkey',
215  'tx_testkey'
216  ],
217  'With underscores' => [
218  'this_is_a_test_extension',
219  'tx_thisisatestextension'
220  ],
221  'With user prefix and without underscores' => [
222  'user_testkey',
223  'user_testkey'
224  ],
225  'With user prefix and with underscores' => [
226  'user_test_key',
227  'user_testkey'
228  ],
229  ];
230  }
231 
238  public function getClassNamePrefixForExtensionKey($extensionName, $expectedPrefix)
239  {
240  $this->assertSame($expectedPrefix, ExtensionManagementUtility::getCN($extensionName));
241  }
242 
244  // Tests concerning getExtensionKeyByPrefix
246 
250  public function getExtensionKeyByPrefixForLoadedExtensionWithUnderscoresReturnsExtensionKey()
251  {
253  $uniqueSuffix = $this->getUniqueId('test');
254  $extensionKey = 'tt_news' . $uniqueSuffix;
255  $extensionPrefix = 'tx_ttnews' . $uniqueSuffix;
256  $package = $this->getMockBuilder(Package::class)
257  ->disableOriginalConstructor()
258  ->setMethods(['getPackageKey'])
259  ->getMock();
260  $package->expects($this->exactly(2))
261  ->method('getPackageKey')
262  ->will($this->returnValue($extensionKey));
264  $packageManager = $this->getMockBuilder(PackageManager::class)
265  ->setMethods(['getActivePackages'])
266  ->getMock();
267  $packageManager->expects($this->once())
268  ->method('getActivePackages')
269  ->will($this->returnValue([$extensionKey => $package]));
271  $this->assertEquals($extensionKey, ExtensionManagementUtility::getExtensionKeyByPrefix($extensionPrefix));
272  }
273 
278  public function getExtensionKeyByPrefixForLoadedExtensionWithoutUnderscoresReturnsExtensionKey()
279  {
281  $uniqueSuffix = $this->getUniqueId('test');
282  $extensionKey = 'kickstarter' . $uniqueSuffix;
283  $extensionPrefix = 'tx_kickstarter' . $uniqueSuffix;
284  $package = $this->getMockBuilder(Package::class)
285  ->disableOriginalConstructor()
286  ->setMethods(['getPackageKey'])
287  ->getMock();
288  $package->expects($this->exactly(2))
289  ->method('getPackageKey')
290  ->will($this->returnValue($extensionKey));
292  $packageManager = $this->getMockBuilder(PackageManager::class)
293  ->setMethods(['getActivePackages'])
294  ->getMock();
295  $packageManager->expects($this->once())
296  ->method('getActivePackages')
297  ->will($this->returnValue([$extensionKey => $package]));
299  $this->assertEquals($extensionKey, ExtensionManagementUtility::getExtensionKeyByPrefix($extensionPrefix));
300  }
301 
307  {
309  $uniqueSuffix = $this->getUniqueId('test');
310  $extensionPrefix = 'tx_unloadedextension' . $uniqueSuffix;
311  $this->assertFalse(ExtensionManagementUtility::getExtensionKeyByPrefix($extensionPrefix));
312  }
313 
315  // Tests concerning addToAllTCAtypes
317 
324  {
325  $table = $this->getUniqueId('tx_coretest_table');
326  $GLOBALS['TCA'] = $this->generateTCAForTable($table);
327  ExtensionManagementUtility::addToAllTCAtypes($table, 'newA, newA, newB, fieldA', '', 'before:fieldD');
328  // Checking typeA:
329  $this->assertEquals('fieldA, fieldB, fieldC;labelC, --palette--;;paletteC, fieldC1, newA, newB, fieldD, fieldD1', $GLOBALS['TCA'][$table]['types']['typeA']['showitem']);
330  // Checking typeB:
331  $this->assertEquals('fieldA, fieldB, fieldC;labelC, --palette--;;paletteC, fieldC1, newA, newB, fieldD, fieldD1', $GLOBALS['TCA'][$table]['types']['typeB']['showitem']);
332  }
333 
341  {
342  $table = $this->getUniqueId('tx_coretest_table');
343  $GLOBALS['TCA'] = $this->generateTCAForTable($table);
344  ExtensionManagementUtility::addToAllTCAtypes($table, 'newA, newA, newB, fieldA', '', 'after:fieldC');
345  // Checking typeA:
346  $this->assertEquals('fieldA, fieldB, fieldC;labelC, newA, newB, --palette--;;paletteC, fieldC1, fieldD, fieldD1', $GLOBALS['TCA'][$table]['types']['typeA']['showitem']);
347  // Checking typeB:
348  $this->assertEquals('fieldA, fieldB, fieldC;labelC, newA, newB, --palette--;;paletteC, fieldC1, fieldD, fieldD1', $GLOBALS['TCA'][$table]['types']['typeB']['showitem']);
349  }
350 
358  {
359  $table = $this->getUniqueId('tx_coretest_table');
360  $GLOBALS['TCA'] = $this->generateTCAForTable($table);
361  $GLOBALS['TCA'][$table]['types']['typeD'] = ['showitem' => 'fieldY, --palette--;LLL:EXT:frontend/Resources/Private/Language/locallang_tca.xlf:pages.palettes.standard;standard, fieldZ'];
362  ExtensionManagementUtility::addToAllTCAtypes($table, 'newA, newA, newB, fieldA', '', 'after:--palette--;LLL:EXT:frontend/Resources/Private/Language/locallang_tca.xlf:pages.palettes.standard;standard');
363  // Checking typeD:
364  $this->assertEquals('fieldY, --palette--;LLL:EXT:frontend/Resources/Private/Language/locallang_tca.xlf:pages.palettes.standard;standard, newA, newB, fieldA, fieldZ', $GLOBALS['TCA'][$table]['types']['typeD']['showitem']);
365  }
366 
374  {
375  $table = $this->getUniqueId('tx_coretest_table');
376  $GLOBALS['TCA'] = $this->generateTCAForTable($table);
377  ExtensionManagementUtility::addToAllTCAtypes($table, 'newA, newA, newB, fieldA', '', 'after:fieldX1');
378  // Checking typeA:
379  $this->assertEquals('fieldA, fieldB, fieldC;labelC, --palette--;;paletteC, newA, newB, fieldC1, fieldD, fieldD1', $GLOBALS['TCA'][$table]['types']['typeA']['showitem']);
380  }
381 
389  {
390  $table = $this->getUniqueId('tx_coretest_table');
391  $GLOBALS['TCA'] = $this->generateTCAForTable($table);
392  ExtensionManagementUtility::addToAllTCAtypes($table, 'newA, newA, newB, fieldA', 'typeA', 'before:fieldD');
393  // Checking typeA:
394  $this->assertEquals('fieldA, fieldB, fieldC;labelC, --palette--;;paletteC, fieldC1, newA, newB, fieldD, fieldD1', $GLOBALS['TCA'][$table]['types']['typeA']['showitem']);
395  // Checking typeB:
396  $this->assertEquals('fieldA, fieldB, fieldC;labelC, --palette--;;paletteC, fieldC1, fieldD, fieldD1', $GLOBALS['TCA'][$table]['types']['typeB']['showitem']);
397  }
398 
406  {
407  $table = $this->getUniqueId('tx_coretest_table');
408  $GLOBALS['TCA'] = $this->generateTCAForTable($table);
409  ExtensionManagementUtility::addToAllTCAtypes($table, 'newA, newA, newB, fieldA', 'typeA', 'after:fieldC');
410  // Checking typeA:
411  $this->assertEquals('fieldA, fieldB, fieldC;labelC, newA, newB, --palette--;;paletteC, fieldC1, fieldD, fieldD1', $GLOBALS['TCA'][$table]['types']['typeA']['showitem']);
412  // Checking typeB:
413  $this->assertEquals('fieldA, fieldB, fieldC;labelC, --palette--;;paletteC, fieldC1, fieldD, fieldD1', $GLOBALS['TCA'][$table]['types']['typeB']['showitem']);
414  }
415 
420  {
421  $table = $this->getUniqueId('tx_coretest_table');
422  $GLOBALS['TCA'] = $this->generateTCAForTable($table);
423  ExtensionManagementUtility::addToAllTCAtypes($table, 'field', 'typeA', 'after:fieldD1');
424 
425  $this->assertEquals('fieldA, fieldB, fieldC;labelC, --palette--;;paletteC, fieldC1, fieldD, fieldD1, field', $GLOBALS['TCA'][$table]['types']['typeA']['showitem']);
426  }
427 
435  {
436  $table = $this->getUniqueId('tx_coretest_table');
437  $GLOBALS['TCA'] = $this->generateTCAForTable($table);
438  $typesBefore = $GLOBALS['TCA'][$table]['types'];
439  ExtensionManagementUtility::addToAllTCAtypes($table, 'fieldZ', '', 'replace:fieldX');
440  $this->assertEquals($typesBefore, $GLOBALS['TCA'][$table]['types'], 'It\'s wrong that the "types" array changes here - the replaced field is only on palettes');
441  // unchanged because the palette is not used
442  $this->assertEquals('fieldX, fieldX1, fieldY', $GLOBALS['TCA'][$table]['palettes']['paletteA']['showitem']);
443  $this->assertEquals('fieldX, fieldX1, fieldY', $GLOBALS['TCA'][$table]['palettes']['paletteB']['showitem']);
444  // changed
445  $this->assertEquals('fieldZ, fieldX1, fieldY', $GLOBALS['TCA'][$table]['palettes']['paletteC']['showitem']);
446  $this->assertEquals('fieldZ, fieldX1, fieldY', $GLOBALS['TCA'][$table]['palettes']['paletteD']['showitem']);
447  }
448 
453  {
454  $table = $this->getUniqueId('tx_coretest_table');
455  $GLOBALS['TCA'] = $this->generateTCAForTable($table);
456  $typesBefore = $GLOBALS['TCA'][$table]['types'];
457  ExtensionManagementUtility::addToAllTCAtypes($table, 'fieldX, --palette--;;foo', '', 'replace:fieldX');
458  $this->assertEquals($typesBefore, $GLOBALS['TCA'][$table]['types'], 'It\'s wrong that the "types" array changes here - the replaced field is only on palettes');
459  // unchanged because the palette is not used
460  $this->assertEquals('fieldX, fieldX1, fieldY', $GLOBALS['TCA'][$table]['palettes']['paletteA']['showitem']);
461  $this->assertEquals('fieldX, fieldX1, fieldY', $GLOBALS['TCA'][$table]['palettes']['paletteB']['showitem']);
462  // changed
463  $this->assertEquals('fieldX, --palette--;;foo, fieldX1, fieldY', $GLOBALS['TCA'][$table]['palettes']['paletteC']['showitem']);
464  $this->assertEquals('fieldX, --palette--;;foo, fieldX1, fieldY', $GLOBALS['TCA'][$table]['palettes']['paletteD']['showitem']);
465  }
466 
474  {
475  $table = $this->getUniqueId('tx_coretest_table');
476  $GLOBALS['TCA'] = $this->generateTCAForTable($table);
477  ExtensionManagementUtility::addFieldsToPalette($table, 'paletteA', 'newA, newA, newB, fieldX', 'before:fieldY');
478  $this->assertEquals('fieldX, fieldX1, newA, newB, fieldY', $GLOBALS['TCA'][$table]['palettes']['paletteA']['showitem']);
479  }
480 
488  {
489  $table = $this->getUniqueId('tx_coretest_table');
490  $GLOBALS['TCA'] = $this->generateTCAForTable($table);
491  ExtensionManagementUtility::addFieldsToPalette($table, 'paletteA', 'newA, newA, newB, fieldX', 'after:fieldX');
492  $this->assertEquals('fieldX, newA, newB, fieldX1, fieldY', $GLOBALS['TCA'][$table]['palettes']['paletteA']['showitem']);
493  }
494 
502  {
503  $table = $this->getUniqueId('tx_coretest_table');
504  $GLOBALS['TCA'] = $this->generateTCAForTable($table);
505  ExtensionManagementUtility::addFieldsToPalette($table, 'paletteA', 'newA, newA, newB, fieldX', 'after:' . $this->getUniqueId('notExisting'));
506  $this->assertEquals('fieldX, fieldX1, fieldY, newA, newB', $GLOBALS['TCA'][$table]['palettes']['paletteA']['showitem']);
507  }
508 
513  {
514  return [
515  'Simple' => [
516  'field_b, field_d, field_c',
517  'field_a, field_b, field_c',
518  'field_d'
519  ],
520  'with linebreaks' => [
521  'field_b, --linebreak--, field_d, --linebreak--, field_c',
522  'field_a, field_b, field_c',
523  '--linebreak--, field_d, --linebreak--'
524  ],
525  'with linebreaks in list and insertion list' => [
526  'field_b, --linebreak--, field_d, --linebreak--, field_c',
527  'field_a, field_b, --linebreak--, field_c',
528  '--linebreak--, field_d, --linebreak--'
529  ],
530  ];
531  }
532 
540  public function removeDuplicatesForInsertionRemovesDuplicates($insertionList, $list, $expected)
541  {
543  $this->assertSame($expected, $result);
544  }
545 
547  // Tests concerning addFieldsToAllPalettesOfField
549 
554  {
555  $GLOBALS['TCA'] = [
556  'aTable' => [
557  'types' => [
558  'typeA' => [
559  'showitem' => 'fieldA;labelA, --palette--;;paletteA',
560  ],
561  ],
562  'palettes' => [
563  'paletteA' => [
564  'showitem' => 'fieldX, fieldY',
565  ],
566  ],
567  ],
568  ];
569  $expected = $GLOBALS['TCA'];
571  'aTable',
572  'fieldA',
573  'newA'
574  );
575  $this->assertEquals($expected, $GLOBALS['TCA']);
576  }
577 
582  {
583  $GLOBALS['TCA'] = [
584  'aTable' => [
585  'columns' => [
586  'fieldA' => [],
587  ],
588  'types' => [
589  'typeA' => [
590  'showitem' => 'fieldA;labelA, --palette--;;paletteA',
591  ],
592  ],
593  'palettes' => [
594  'paletteA' => [
595  'showitem' => 'fieldX, fieldY',
596  ],
597  ],
598  ],
599  ];
600  $expected = [
601  'aTable' => [
602  'columns' => [
603  'fieldA' => [],
604  ],
605  'types' => [
606  'typeA' => [
607  'showitem' => 'fieldA;labelA, --palette--;;paletteA',
608  ],
609  ],
610  'palettes' => [
611  'paletteA' => [
612  'showitem' => 'fieldX, fieldY, dupeA',
613  ],
614  ],
615  ],
616  ];
618  'aTable',
619  'fieldA',
620  'dupeA, dupeA' // Duplicate
621  );
622  $this->assertEquals($expected, $GLOBALS['TCA']);
623  }
624 
629  {
630  $GLOBALS['TCA'] = [
631  'aTable' => [
632  'columns' => [
633  'fieldA' => [],
634  ],
635  'types' => [
636  'typeA' => [
637  'showitem' => 'fieldA;labelA, --palette--;;paletteA',
638  ],
639  ],
640  'palettes' => [
641  'paletteA' => [
642  'showitem' => 'existingA',
643  ],
644  ],
645  ],
646  ];
647  $expected = [
648  'aTable' => [
649  'columns' => [
650  'fieldA' => [],
651  ],
652  'types' => [
653  'typeA' => [
654  'showitem' => 'fieldA;labelA, --palette--;;paletteA',
655  ],
656  ],
657  'palettes' => [
658  'paletteA' => [
659  'showitem' => 'existingA',
660  ],
661  ],
662  ],
663  ];
665  'aTable',
666  'fieldA',
667  'existingA'
668  );
669  $this->assertEquals($expected, $GLOBALS['TCA']);
670  }
671 
676  {
677  $GLOBALS['TCA'] = [
678  'aTable' => [
679  'columns' => [
680  'fieldA' => [],
681  ],
682  'types' => [
683  'typeA' => [
684  'showitem' => 'fieldA, --palette--;;palette1',
685  ],
686  'typeB' => [
687  'showitem' => 'fieldA;aLabel, --palette--;;palette2',
688  ],
689  ],
690  'palettes' => [
691  'palette1' => [
692  'showitem' => 'fieldX',
693  ],
694  'palette2' => [
695  'showitem' => 'fieldY',
696  ],
697  ],
698  ],
699  ];
700  $expected = [
701  'aTable' => [
702  'columns' => [
703  'fieldA' => [],
704  ],
705  'types' => [
706  'typeA' => [
707  'showitem' => 'fieldA, --palette--;;palette1',
708  ],
709  'typeB' => [
710  'showitem' => 'fieldA;aLabel, --palette--;;palette2',
711  ],
712  ],
713  'palettes' => [
714  'palette1' => [
715  'showitem' => 'fieldX, newA',
716  ],
717  'palette2' => [
718  'showitem' => 'fieldY, newA',
719  ],
720  ],
721  ],
722  ];
724  'aTable',
725  'fieldA',
726  'newA'
727  );
728  $this->assertEquals($expected, $GLOBALS['TCA']);
729  }
730 
735  {
736  $GLOBALS['TCA'] = [
737  'aTable' => [
738  'columns' => [
739  'fieldA' => [],
740  ],
741  'types' => [
742  'typeA' => [
743  'showitem' => 'fieldA, --palette--;;palette1',
744  ],
745  ],
746  'palettes' => [
747  'palette1' => [
748  'showitem' => 'fieldX',
749  ],
750  ],
751  ],
752  ];
753  $expected = [
754  'aTable' => [
755  'columns' => [
756  'fieldA' => [],
757  ],
758  'types' => [
759  'typeA' => [
760  'showitem' => 'fieldA, --palette--;;palette1',
761  ],
762  ],
763  'palettes' => [
764  'palette1' => [
765  'showitem' => 'fieldX, newA, newB',
766  ],
767  ],
768  ],
769  ];
771  'aTable',
772  'fieldA',
773  'newA, newB'
774  );
775  $this->assertEquals($expected, $GLOBALS['TCA']);
776  }
777 
782  {
783  $GLOBALS['TCA'] = [
784  'aTable' => [
785  'columns' => [
786  'fieldA' => [],
787  ],
788  'types' => [
789  'typeA' => [
790  'showitem' => 'fieldA;labelA, --palette--;;paletteA',
791  ],
792  ],
793  'palettes' => [
794  'paletteA' => [
795  'showitem' => 'existingA, existingB',
796  ],
797  ],
798  ],
799  ];
800  $expected = [
801  'aTable' => [
802  'columns' => [
803  'fieldA' => [],
804  ],
805  'types' => [
806  'typeA' => [
807  'showitem' => 'fieldA;labelA, --palette--;;paletteA',
808  ],
809  ],
810  'palettes' => [
811  'paletteA' => [
812  'showitem' => 'existingA, newA, existingB',
813  ],
814  ],
815  ],
816  ];
818  'aTable',
819  'fieldA',
820  'newA',
821  'before:existingB'
822  );
823  $this->assertEquals($expected, $GLOBALS['TCA']);
824  }
825 
830  {
831  $GLOBALS['TCA'] = [
832  'aTable' => [
833  'columns' => [
834  'fieldA' => [],
835  ],
836  'types' => [
837  'typeA' => [
838  'showitem' => 'fieldA;labelA, --palette--;;paletteA',
839  ],
840  ],
841  'palettes' => [
842  'paletteA' => [
843  'showitem' => 'fieldX, fieldY',
844  ],
845  ],
846  ],
847  ];
848  $expected = [
849  'aTable' => [
850  'columns' => [
851  'fieldA' => [],
852  ],
853  'types' => [
854  'typeA' => [
855  'showitem' => 'fieldA;labelA, --palette--;;paletteA',
856  ],
857  ],
858  'palettes' => [
859  'paletteA' => [
860  'showitem' => 'fieldX, fieldY, newA, newB',
861  ],
862  ],
863  ],
864  ];
866  'aTable',
867  'fieldA',
868  'newA, newB',
869  'before:notExisting'
870  );
871  $this->assertEquals($expected, $GLOBALS['TCA']);
872  }
873 
878  {
879  $GLOBALS['TCA'] = [
880  'aTable' => [
881  'columns' => [
882  'fieldA' => [],
883  ],
884  'types' => [
885  'typeA' => [
886  'showitem' => 'fieldA;labelA, --palette--;;paletteA',
887  ],
888  ],
889  'palettes' => [
890  'paletteA' => [
891  'showitem' => 'existingA, existingB',
892  ],
893  ],
894  ],
895  ];
896  $expected = [
897  'aTable' => [
898  'columns' => [
899  'fieldA' => [],
900  ],
901  'types' => [
902  'typeA' => [
903  'showitem' => 'fieldA;labelA, --palette--;;paletteA',
904  ],
905  ],
906  'palettes' => [
907  'paletteA' => [
908  'showitem' => 'existingA, newA, existingB',
909  ],
910  ],
911  ],
912  ];
914  'aTable',
915  'fieldA',
916  'newA',
917  'after:existingA'
918  );
919  $this->assertEquals($expected, $GLOBALS['TCA']);
920  }
921 
926  {
927  $GLOBALS['TCA'] = [
928  'aTable' => [
929  'columns' => [
930  'fieldA' => [],
931  ],
932  'types' => [
933  'typeA' => [
934  'showitem' => 'fieldA;labelA, --palette--;;paletteA',
935  ],
936  ],
937  'palettes' => [
938  'paletteA' => [
939  'showitem' => 'existingA, existingB',
940  ],
941  ],
942  ],
943  ];
944  $expected = [
945  'aTable' => [
946  'columns' => [
947  'fieldA' => [],
948  ],
949  'types' => [
950  'typeA' => [
951  'showitem' => 'fieldA;labelA, --palette--;;paletteA',
952  ],
953  ],
954  'palettes' => [
955  'paletteA' => [
956  'showitem' => 'existingA, existingB, newA, newB',
957  ],
958  ],
959  ],
960  ];
962  'aTable',
963  'fieldA',
964  'newA, newB',
965  'after:notExistingA'
966  );
967  $this->assertEquals($expected, $GLOBALS['TCA']);
968  }
969 
974  {
975  $GLOBALS['TCA'] = [
976  'aTable' => [
977  'columns' => [
978  'fieldA' => [],
979  ],
980  'types' => [
981  'typeA' => [
982  'showitem' => 'fieldA',
983  ],
984  ],
985  ],
986  ];
987  $expected = [
988  'aTable' => [
989  'columns' => [
990  'fieldA' => [],
991  ],
992  'types' => [
993  'typeA' => [
994  'showitem' => 'fieldA, --palette--;;generatedFor-fieldA',
995  ],
996  ],
997  'palettes' => [
998  'generatedFor-fieldA' => [
999  'showitem' => 'newA',
1000  ],
1001  ],
1002  ],
1003  ];
1005  'aTable',
1006  'fieldA',
1007  'newA'
1008  );
1009  $this->assertEquals($expected, $GLOBALS['TCA']);
1010  }
1011 
1016  {
1017  $GLOBALS['TCA'] = [
1018  'aTable' => [
1019  'columns' => [
1020  'fieldA' => [],
1021  ],
1022  'types' => [
1023  'typeA' => [
1024  'showitem' => 'fieldA;labelA',
1025  ],
1026  ],
1027  ],
1028  ];
1029  $expected = [
1030  'aTable' => [
1031  'columns' => [
1032  'fieldA' => [],
1033  ],
1034  'types' => [
1035  'typeA' => [
1036  'showitem' => 'fieldA;labelA, --palette--;;generatedFor-fieldA',
1037  ],
1038  ],
1039  'palettes' => [
1040  'generatedFor-fieldA' => [
1041  'showitem' => 'newA',
1042  ],
1043  ],
1044  ],
1045  ];
1047  'aTable',
1048  'fieldA',
1049  'newA'
1050  );
1051  $this->assertEquals($expected, $GLOBALS['TCA']);
1052  }
1053 
1055  // Tests concerning executePositionedStringInsertion
1057 
1063  {
1064  return [
1065  'normal characters' => [
1066  'tr0',
1067  'tr0',
1068  ],
1069  'newlines' => [
1070  "test\n",
1071  'test',
1072  ],
1073  'newlines with carriage return' => [
1074  "test\r\n",
1075  'test',
1076  ],
1077  'tabs' => [
1078  "test\t",
1079  'test',
1080  ],
1081  'commas' => [
1082  'test,',
1083  'test',
1084  ],
1085  'multiple commas with trailing spaces' => [
1086  "test,,\t, \r\n",
1087  'test',
1088  ],
1089  ];
1090  }
1091 
1098  public function executePositionedStringInsertionTrimsCorrectCharacters($string, $expectedResult)
1099  {
1100  $extensionManagementUtility = $this->getAccessibleMock(ExtensionManagementUtility::class, ['dummy']);
1101  $string = $extensionManagementUtility->_call('executePositionedStringInsertion', $string, '');
1102  $this->assertEquals($expectedResult, $string);
1103  }
1104 
1106  // Tests concerning addTcaSelectItem
1108 
1112  {
1113  $this->expectException(\InvalidArgumentException::class);
1114  $this->expectExceptionCode(1303236963);
1115 
1117  }
1118 
1123  {
1124  $this->expectException(\InvalidArgumentException::class);
1125  $this->expectExceptionCode(1303236964);
1126 
1128  }
1129 
1134  {
1135  $this->expectException(\InvalidArgumentException::class);
1136  $this->expectExceptionCode(1303236965);
1137 
1138  ExtensionManagementUtility::addTcaSelectItem('foo', 'bar', [], []);
1139  }
1140 
1145  {
1146  $this->expectException(\InvalidArgumentException::class);
1147  $this->expectExceptionCode(1303236966);
1148 
1149  ExtensionManagementUtility::addTcaSelectItem('foo', 'bar', [], 'foo', []);
1150  }
1151 
1156  {
1157  $this->expectException(\InvalidArgumentException::class);
1158  $this->expectExceptionCode(1303236967);
1159 
1160  ExtensionManagementUtility::addTcaSelectItem('foo', 'bar', [], 'foo', 'not allowed keyword');
1161  }
1162 
1167  {
1168  $this->expectException(\RuntimeException::class);
1169  $this->expectExceptionCode(1303237468);
1170 
1171  $GLOBALS['TCA'] = [];
1173  }
1174 
1179  {
1180  // Every array splits into:
1181  // - relativeToField
1182  // - relativePosition
1183  // - expectedResultArray
1184  return [
1185  'add at end of array' => [
1186  '',
1187  '',
1188  [
1189  0 => ['firstElement'],
1190  1 => ['matchMe'],
1191  2 => ['thirdElement'],
1192  3 => ['insertedElement']
1193  ]
1194  ],
1195  'replace element' => [
1196  'matchMe',
1197  'replace',
1198  [
1199  0 => ['firstElement'],
1200  1 => ['insertedElement'],
1201  2 => ['thirdElement']
1202  ]
1203  ],
1204  'add element after' => [
1205  'matchMe',
1206  'after',
1207  [
1208  0 => ['firstElement'],
1209  1 => ['matchMe'],
1210  2 => ['insertedElement'],
1211  3 => ['thirdElement']
1212  ]
1213  ],
1214  'add element before' => [
1215  'matchMe',
1216  'before',
1217  [
1218  0 => ['firstElement'],
1219  1 => ['insertedElement'],
1220  2 => ['matchMe'],
1221  3 => ['thirdElement']
1222  ]
1223  ],
1224  'add at end if relative position was not found' => [
1225  'notExistingItem',
1226  'after',
1227  [
1228  0 => ['firstElement'],
1229  1 => ['matchMe'],
1230  2 => ['thirdElement'],
1231  3 => ['insertedElement']
1232  ]
1233  ]
1234  ];
1235  }
1236 
1244  public function addTcaSelectItemInsertsItemAtSpecifiedPosition($relativeToField, $relativePosition, $expectedResultArray)
1245  {
1246  $GLOBALS['TCA'] = [
1247  'testTable' => [
1248  'columns' => [
1249  'testField' => [
1250  'config' => [
1251  'items' => [
1252  '0' => ['firstElement'],
1253  '1' => ['matchMe'],
1254  2 => ['thirdElement']
1255  ]
1256  ]
1257  ]
1258  ]
1259  ]
1260  ];
1261  ExtensionManagementUtility::addTcaSelectItem('testTable', 'testField', ['insertedElement'], $relativeToField, $relativePosition);
1262  $this->assertEquals($expectedResultArray, $GLOBALS['TCA']['testTable']['columns']['testField']['config']['items']);
1263  }
1264 
1266  // Tests concerning loadExtLocalconf
1268 
1271  public function loadExtLocalconfDoesNotReadFromCacheIfCachingIsDenied()
1272  {
1274  $mockCacheManager = $this->getMockBuilder(CacheManager::class)
1275  ->setMethods(['getCache'])
1276  ->getMock();
1277  $mockCacheManager->expects($this->never())->method('getCache');
1279  $GLOBALS['TYPO3_LOADED_EXT'] = new LoadedExtensionsArray($this->createMockPackageManagerWithMockPackage($this->getUniqueId()));
1280  ExtensionManagementUtility::loadExtLocalconf(false);
1281  }
1282 
1286  public function loadExtLocalconfRequiresCacheFileIfExistsAndCachingIsAllowed()
1287  {
1288  $mockCache = $this->getMockBuilder(PhpFrontend::class)
1289  ->setMethods(['getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove', 'flush', 'flushByTag', 'requireOnce'])
1290  ->disableOriginalConstructor()
1291  ->getMock();
1292 
1294  $mockCacheManager = $this->getMockBuilder(CacheManager::class)
1295  ->setMethods(['getCache'])
1296  ->getMock();
1297  $mockCacheManager->expects($this->any())->method('getCache')->will($this->returnValue($mockCache));
1299  $mockCache->expects($this->any())->method('has')->will($this->returnValue(true));
1300  $mockCache->expects($this->once())->method('requireOnce');
1301  ExtensionManagementUtility::loadExtLocalconf(true);
1302  }
1303 
1305  // Tests concerning loadSingleExtLocalconfFiles
1307 
1311  {
1312  $this->expectException(\RuntimeException::class);
1313  $this->expectExceptionCode(1340559079);
1314 
1315  $extensionName = $this->getUniqueId('foo');
1316  $packageManager = $this->createMockPackageManagerWithMockPackage($extensionName);
1317  $extLocalconfLocation = $packageManager->getPackage($extensionName)->getPackagePath() . 'ext_localconf.php';
1318  file_put_contents($extLocalconfLocation, "<?php\n\nthrow new RuntimeException('', 1340559079);\n\n?>");
1319  $GLOBALS['TYPO3_LOADED_EXT'] = new LoadedExtensionsArray($packageManager);
1321  }
1322 
1324  // Tests concerning addModule
1326 
1332  {
1333  return [
1334  'can add new main module if none exists' => [
1335  'top',
1336  '',
1337  'newModule'
1338  ],
1339  'can add new sub module if no position specified' => [
1340  '',
1341  'some,modules',
1342  'some,modules,newModule'
1343  ],
1344  'can add new sub module to top of module' => [
1345  'top',
1346  'some,modules',
1347  'newModule,some,modules'
1348  ],
1349  'can add new sub module if bottom of module' => [
1350  'bottom',
1351  'some,modules',
1352  'some,modules,newModule'
1353  ],
1354  'can add new sub module before specified sub module' => [
1355  'before:modules',
1356  'some,modules',
1357  'some,newModule,modules'
1358  ],
1359  'can add new sub module after specified sub module' => [
1360  'after:some',
1361  'some,modules',
1362  'some,newModule,modules'
1363  ],
1364  'can add new sub module at the bottom if specified sub module to add before does not exist' => [
1365  'before:modules',
1366  'some,otherModules',
1367  'some,otherModules,newModule'
1368  ],
1369  'can add new sub module at the bottom if specified sub module to add after does not exist' => [
1370  'after:some',
1371  'someOther,modules',
1372  'someOther,modules,newModule'
1373  ],
1374  ];
1375  }
1376 
1384  public function addModuleCanAddModule($position, $existing, $expected)
1385  {
1386  $mainModule = 'foobar';
1387  $subModule = 'newModule';
1388  if ($existing) {
1389  $GLOBALS['TBE_MODULES'][$mainModule] = $existing;
1390  }
1391 
1392  ExtensionManagementUtility::addModule($mainModule, $subModule, $position);
1393 
1394  $this->assertTrue(isset($GLOBALS['TBE_MODULES'][$mainModule]));
1395  $this->assertEquals($expected, $GLOBALS['TBE_MODULES'][$mainModule]);
1396  }
1397 
1399  // Tests concerning createExtLocalconfCacheEntry
1401 
1404  public function createExtLocalconfCacheEntryWritesCacheEntryWithContentOfLoadedExtensionExtLocalconf()
1405  {
1406  $extensionName = $this->getUniqueId('foo');
1407  $packageManager = $this->createMockPackageManagerWithMockPackage($extensionName);
1408  $extLocalconfLocation = $packageManager->getPackage($extensionName)->getPackagePath() . 'ext_localconf.php';
1409  $uniqueStringInLocalconf = $this->getUniqueId('foo');
1410  file_put_contents($extLocalconfLocation, "<?php\n\n" . $uniqueStringInLocalconf . "\n\n?>");
1411  $GLOBALS['TYPO3_LOADED_EXT'] = new LoadedExtensionsArray($packageManager);
1412  $mockCache = $this->getMockBuilder(PhpFrontend::class)
1413  ->setMethods(['getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove', 'flush', 'flushByTag', 'requireOnce'])
1414  ->disableOriginalConstructor()
1415  ->getMock();
1416 
1418  $mockCacheManager = $this->getMockBuilder(CacheManager::class)
1419  ->setMethods(['getCache'])
1420  ->getMock();
1421  $mockCacheManager->expects($this->any())->method('getCache')->will($this->returnValue($mockCache));
1423  $mockCache->expects($this->once())->method('set')->with($this->anything(), $this->stringContains($uniqueStringInLocalconf), $this->anything());
1425  }
1426 
1430  public function createExtLocalconfCacheEntryWritesCacheEntryWithExtensionContentOnlyIfExtLocalconfExists()
1431  {
1432  $extensionName = $this->getUniqueId('foo');
1433  $packageManager = $this->createMockPackageManagerWithMockPackage($extensionName);
1434  $GLOBALS['TYPO3_LOADED_EXT'] = new LoadedExtensionsArray($packageManager);
1435  $mockCache = $this->getMockBuilder(PhpFrontend::class)
1436  ->setMethods(['getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove', 'flush', 'flushByTag', 'requireOnce'])
1437  ->disableOriginalConstructor()
1438  ->getMock();
1439 
1441  $mockCacheManager = $this->getMockBuilder(CacheManager::class)
1442  ->setMethods(['getCache'])
1443  ->getMock();
1444  $mockCacheManager->expects($this->any())->method('getCache')->will($this->returnValue($mockCache));
1446  $mockCache->expects($this->once())
1447  ->method('set')
1448  ->with($this->anything(), $this->logicalNot($this->stringContains($extensionName)), $this->anything());
1450  }
1451 
1455  public function createExtLocalconfCacheEntryWritesCacheEntryWithNoTags()
1456  {
1457  $mockCache = $this->getMockBuilder(PhpFrontend::class)
1458  ->setMethods(['getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove', 'flush', 'flushByTag', 'requireOnce'])
1459  ->disableOriginalConstructor()
1460  ->getMock();
1461 
1463  $mockCacheManager = $this->getMockBuilder(CacheManager::class)
1464  ->setMethods(['getCache'])
1465  ->getMock();
1466  $mockCacheManager->expects($this->any())->method('getCache')->will($this->returnValue($mockCache));
1468  $mockCache->expects($this->once())->method('set')->with($this->anything(), $this->anything(), $this->equalTo([]));
1469  $GLOBALS['TYPO3_LOADED_EXT'] = new LoadedExtensionsArray($this->createMockPackageManagerWithMockPackage($this->getUniqueId()));
1471  }
1472 
1474  // Tests concerning getExtLocalconfCacheIdentifier
1476 
1480  {
1481  $prefix = 'ext_localconf_';
1483  $this->assertStringStartsWith($prefix, $identifier);
1484  $sha1 = str_replace($prefix, '', $identifier);
1485  $this->assertEquals(40, strlen($sha1));
1486  }
1487 
1489  // Tests concerning loadBaseTca
1491 
1495  public function loadBaseTcaDoesNotReadFromCacheIfCachingIsDenied()
1496  {
1498  $mockCacheManager = $this->getMockBuilder(CacheManager::class)
1499  ->setMethods(['getCache'])
1500  ->getMock();
1501  $mockCacheManager->expects($this->never())->method('getCache');
1503  ExtensionManagementUtilityAccessibleProxy::loadBaseTca(false);
1504  }
1505 
1509  public function loadBaseTcaRequiresCacheFileIfExistsAndCachingIsAllowed()
1510  {
1511  $mockCache = $this->getMockBuilder(PhpFrontend::class)
1512  ->setMethods(['getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove', 'flush', 'flushByTag', 'requireOnce'])
1513  ->disableOriginalConstructor()
1514  ->getMock();
1515 
1517  $mockCacheManager = $this->getMockBuilder(CacheManager::class)
1518  ->setMethods(['getCache'])
1519  ->getMock();
1520  $mockCacheManager->expects($this->any())->method('getCache')->will($this->returnValue($mockCache));
1522  $mockCache->expects($this->once())->method('requireOnce')->willReturn(['tca' => [], 'categoryRegistry' => \serialize(CategoryRegistry::getInstance())]);
1523  ExtensionManagementUtilityAccessibleProxy::loadBaseTca(true);
1524  }
1525 
1529  public function loadBaseTcaCreatesCacheFileWithContentOfAnExtensionsConfigurationTcaPhpFile()
1530  {
1531  $extensionName = $this->getUniqueId('test_baseTca_');
1532  $packageManager = $this->createMockPackageManagerWithMockPackage($extensionName);
1533  $packagePath = $packageManager->getPackage($extensionName)->getPackagePath();
1534  GeneralUtility::mkdir($packagePath);
1535  GeneralUtility::mkdir($packagePath . 'Configuration/');
1536  GeneralUtility::mkdir($packagePath . 'Configuration/TCA/');
1537  $GLOBALS['TYPO3_LOADED_EXT'] = new LoadedExtensionsArray($packageManager);
1539  $uniqueTableName = $this->getUniqueId('table_name_');
1540  $uniqueStringInTableConfiguration = $this->getUniqueId('table_configuration_');
1541  $tableConfiguration = '<?php return array(\'foo\' => \'' . $uniqueStringInTableConfiguration . '\'); ?>';
1542  file_put_contents($packagePath . 'Configuration/TCA/' . $uniqueTableName . '.php', $tableConfiguration);
1543  $mockCache = $this->getMockBuilder(PhpFrontend::class)
1544  ->setMethods(['getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove', 'flush', 'flushByTag', 'requireOnce'])
1545  ->disableOriginalConstructor()
1546  ->getMock();
1547 
1549  $mockCacheManager = $this->getMockBuilder(CacheManager::class)
1550  ->setMethods(['getCache'])
1551  ->getMock();
1552  $mockCacheManager->expects($this->any())->method('getCache')->will($this->returnValue($mockCache));
1553  ExtensionManagementUtilityAccessibleProxy::setCacheManager($mockCacheManager);
1554  $mockCache->expects($this->once())->method('requireOnce')->will($this->returnValue(false));
1555  $mockCache->expects($this->once())->method('set')->with($this->anything(), $this->stringContains($uniqueStringInTableConfiguration), $this->anything());
1556  ExtensionManagementUtility::loadBaseTca(true);
1557  }
1558 
1562  public function loadBaseTcaWritesCacheEntryWithNoTags()
1563  {
1564  $mockCache = $this->getMockBuilder(PhpFrontend::class)
1565  ->setMethods(['getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove', 'flush', 'flushByTag', 'requireOnce'])
1566  ->disableOriginalConstructor()
1567  ->getMock();
1568 
1570  $mockCacheManager = $this->getMockBuilder(CacheManager::class)
1571  ->setMethods(['getCache'])
1572  ->getMock();
1573  $mockCacheManager->expects($this->any())->method('getCache')->will($this->returnValue($mockCache));
1574  ExtensionManagementUtilityAccessibleProxy::setCacheManager($mockCacheManager);
1575  $mockCache->expects($this->once())->method('requireOnce')->will($this->returnValue(false));
1576  $mockCache->expects($this->once())->method('set')->with($this->anything(), $this->anything(), $this->equalTo([]));
1577  ExtensionManagementUtilityAccessibleProxy::loadBaseTca();
1578  }
1579 
1583  public function loadBaseTcaCanBeCalledMultipleTimesWithoutError()
1584  {
1585  $tcaCache = [
1586  'tca' => [
1587  'pages' => [],
1588  ],
1589  'categoryRegistry' => serialize(new CategoryRegistry()),
1590  ];
1591  $mockCache = $this->getMockBuilder(PhpFrontend::class)
1592  ->setMethods(['getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove', 'flush', 'flushByTag', 'requireOnce'])
1593  ->disableOriginalConstructor()
1594  ->getMock();
1595  $mockCache->expects($this->at(0))->method('requireOnce')->willReturn($tcaCache);
1596  $mockCache->expects($this->at(1))->method('requireOnce')->willReturn(true);
1597 
1599  $mockCacheManager = $this->getMockBuilder(CacheManager::class)
1600  ->setMethods(['getCache'])
1601  ->getMock();
1602  $mockCacheManager->expects($this->any())->method('getCache')->will($this->returnValue($mockCache));
1603  ExtensionManagementUtilityAccessibleProxy::setCacheManager($mockCacheManager);
1604 
1605  EidUtility::initTCA();
1606  ExtensionManagementUtilityAccessibleProxy::loadBaseTca();
1607 
1608  $this->assertSame($tcaCache['tca'], $GLOBALS['TCA']);
1609  }
1610 
1612  // Tests concerning getBaseTcaCacheIdentifier
1614 
1618  public function getBaseTcaCacheIdentifierCreatesSha1WithFourtyCharactersAndPrefix()
1619  {
1620  $prefix = 'tca_base_';
1621  $identifier = ExtensionManagementUtilityAccessibleProxy::getBaseTcaCacheIdentifier();
1622  $this->assertStringStartsWith($prefix, $identifier);
1623  $sha1 = str_replace($prefix, '', $identifier);
1624  $this->assertEquals(40, strlen($sha1));
1625  }
1626 
1628  // Tests concerning loadExtTables
1630 
1633  public function loadExtTablesDoesNotReadFromCacheIfCachingIsDenied()
1634  {
1636  $mockCacheManager = $this->getMockBuilder(CacheManager::class)
1637  ->setMethods(['getCache'])
1638  ->getMock();
1639  $mockCacheManager->expects($this->never())->method('getCache');
1640  ExtensionManagementUtilityAccessibleProxy::setCacheManager($mockCacheManager);
1641  $GLOBALS['TYPO3_LOADED_EXT'] = new LoadedExtensionsArray($this->createMockPackageManagerWithMockPackage($this->getUniqueId()));
1642  ExtensionManagementUtility::loadExtLocalconf(false);
1643  }
1644 
1648  public function loadExtTablesRequiresCacheFileIfExistsAndCachingIsAllowed()
1649  {
1650  $mockCache = $this->getMockBuilder(PhpFrontend::class)
1651  ->setMethods(['getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove', 'flush', 'flushByTag', 'requireOnce'])
1652  ->disableOriginalConstructor()
1653  ->getMock();
1654 
1656  $mockCacheManager = $this->getMockBuilder(CacheManager::class)
1657  ->setMethods(['getCache'])
1658  ->getMock();
1659  $mockCacheManager->expects($this->any())->method('getCache')->will($this->returnValue($mockCache));
1660  ExtensionManagementUtilityAccessibleProxy::setCacheManager($mockCacheManager);
1661  $mockCache->expects($this->any())->method('has')->will($this->returnValue(true));
1662  $mockCache->expects($this->once())->method('requireOnce');
1663  // Reset the internal cache access tracking variable of extMgm
1664  // This method is only in the ProxyClass!
1665  ExtensionManagementUtilityAccessibleProxy::resetExtTablesWasReadFromCacheOnceBoolean();
1666  ExtensionManagementUtility::loadExtTables(true);
1667  }
1668 
1670  // Tests concerning createExtTablesCacheEntry
1672 
1675  public function createExtTablesCacheEntryWritesCacheEntryWithContentOfLoadedExtensionExtTables()
1676  {
1677  $extensionName = $this->getUniqueId('foo');
1678  $extTablesLocation = PATH_site . 'typo3temp/var/tests/' . $this->getUniqueId('test_ext_tables') . '.php';
1679  $this->testFilesToDelete[] = $extTablesLocation;
1680  $uniqueStringInTables = $this->getUniqueId('foo');
1681  file_put_contents($extTablesLocation, "<?php\n\n$uniqueStringInTables\n\n?>");
1682  $GLOBALS['TYPO3_LOADED_EXT'] = [
1683  $extensionName => [
1684  'ext_tables.php' => $extTablesLocation
1685  ]
1686  ];
1687  $mockCache = $this->getMockBuilder(PhpFrontend::class)
1688  ->setMethods(['getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove', 'flush', 'flushByTag', 'requireOnce'])
1689  ->disableOriginalConstructor()
1690  ->getMock();
1691 
1693  $mockCacheManager = $this->getMockBuilder(CacheManager::class)
1694  ->setMethods(['getCache'])
1695  ->getMock();
1696  $mockCacheManager->expects($this->any())->method('getCache')->will($this->returnValue($mockCache));
1697  ExtensionManagementUtilityAccessibleProxy::setCacheManager($mockCacheManager);
1698  $mockCache->expects($this->once())->method('set')->with($this->anything(), $this->stringContains($uniqueStringInTables), $this->anything());
1699  ExtensionManagementUtilityAccessibleProxy::createExtTablesCacheEntry();
1700  }
1701 
1705  public function createExtTablesCacheEntryWritesCacheEntryWithExtensionContentOnlyIfExtTablesExists()
1706  {
1707  $extensionName = $this->getUniqueId('foo');
1708  $GLOBALS['TYPO3_LOADED_EXT'] = [
1709  $extensionName => [],
1710  ];
1711  $mockCache = $this->getMockBuilder(PhpFrontend::class)
1712  ->setMethods(['getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove', 'flush', 'flushByTag', 'requireOnce'])
1713  ->disableOriginalConstructor()
1714  ->getMock();
1715 
1717  $mockCacheManager = $this->getMockBuilder(CacheManager::class)
1718  ->setMethods(['getCache'])
1719  ->getMock();
1720  $mockCacheManager->expects($this->any())->method('getCache')->will($this->returnValue($mockCache));
1721  ExtensionManagementUtilityAccessibleProxy::setCacheManager($mockCacheManager);
1722  $mockCache->expects($this->once())
1723  ->method('set')
1724  ->with($this->anything(), $this->logicalNot($this->stringContains($extensionName)), $this->anything());
1725  ExtensionManagementUtilityAccessibleProxy::createExtTablesCacheEntry();
1726  }
1727 
1731  public function createExtTablesCacheEntryWritesCacheEntryWithNoTags()
1732  {
1733  $mockCache = $this->getMockBuilder(PhpFrontend::class)
1734  ->setMethods(['getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove', 'flush', 'flushByTag', 'requireOnce'])
1735  ->disableOriginalConstructor()
1736  ->getMock();
1737 
1739  $mockCacheManager = $this->getMockBuilder(CacheManager::class)
1740  ->setMethods(['getCache'])
1741  ->getMock();
1742  $mockCacheManager->expects($this->any())->method('getCache')->will($this->returnValue($mockCache));
1743  ExtensionManagementUtilityAccessibleProxy::setCacheManager($mockCacheManager);
1744  $mockCache->expects($this->once())->method('set')->with($this->anything(), $this->anything(), $this->equalTo([]));
1745  $GLOBALS['TYPO3_LOADED_EXT'] = new LoadedExtensionsArray($this->createMockPackageManagerWithMockPackage($this->getUniqueId()));
1746  ExtensionManagementUtilityAccessibleProxy::createExtTablesCacheEntry();
1747  }
1748 
1750  // Tests concerning getExtTablesCacheIdentifier
1752 
1755  public function getExtTablesCacheIdentifierCreatesSha1WithFourtyCharactersAndPrefix()
1756  {
1757  $prefix = 'ext_tables_';
1758  $identifier = ExtensionManagementUtilityAccessibleProxy::getExtTablesCacheIdentifier();
1759  $this->assertStringStartsWith($prefix, $identifier);
1760  $sha1 = str_replace($prefix, '', $identifier);
1761  $this->assertEquals(40, strlen($sha1));
1762  }
1763 
1765  // Tests concerning removeCacheFiles
1767 
1770  public function removeCacheFilesFlushesSystemCaches()
1771  {
1773  $mockCacheManager = $this->getMockBuilder(CacheManager::class)
1774  ->setMethods(['flushCachesInGroup'])
1775  ->getMock();
1776  $mockCacheManager->expects($this->once())->method('flushCachesInGroup')->with('system');
1777  ExtensionManagementUtilityAccessibleProxy::setCacheManager($mockCacheManager);
1778  ExtensionManagementUtility::removeCacheFiles();
1779  }
1780 
1782  // Tests concerning getExtensionVersion
1784 
1789  public function getExtensionVersionFaultyDataProvider()
1790  {
1791  return [
1792  [''],
1793  [0],
1794  [new \stdClass()],
1795  [true]
1796  ];
1797  }
1798 
1805  public function getExtensionVersionForFaultyExtensionKeyThrowsException($key)
1806  {
1807  $this->expectException(\InvalidArgumentException::class);
1808  $this->expectExceptionCode(1294586096);
1809 
1810  ExtensionManagementUtility::getExtensionVersion($key);
1811  }
1812 
1816  public function getExtensionVersionForNotLoadedExtensionReturnsEmptyString()
1817  {
1818  ExtensionManagementUtility::clearExtensionKeyMap();
1819  $uniqueSuffix = $this->getUniqueId('test');
1820  $extensionKey = 'unloadedextension' . $uniqueSuffix;
1821  $this->assertEquals('', ExtensionManagementUtility::getExtensionVersion($extensionKey));
1822  }
1823 
1827  public function getExtensionVersionForLoadedExtensionReturnsExtensionVersion()
1828  {
1829  ExtensionManagementUtility::clearExtensionKeyMap();
1830  $uniqueSuffix = $this->getUniqueId('test');
1831  $extensionKey = 'unloadedextension' . $uniqueSuffix;
1832  $packageMetaData = $this->getMockBuilder(MetaData::class)
1833  ->setMethods(['getVersion'])
1834  ->setConstructorArgs([$extensionKey])
1835  ->getMock();
1836  $packageMetaData->expects($this->any())->method('getVersion')->will($this->returnValue('1.2.3'));
1837  $packageManager = $this->createMockPackageManagerWithMockPackage($extensionKey, ['getPackagePath', 'getPackageKey', 'getPackageMetaData']);
1839  $package = $packageManager->getPackage($extensionKey);
1840  $package->expects($this->any())
1841  ->method('getPackageMetaData')
1842  ->will($this->returnValue($packageMetaData));
1843  ExtensionManagementUtility::setPackageManager($packageManager);
1844  $this->assertEquals('1.2.3', ExtensionManagementUtility::getExtensionVersion($extensionKey));
1845  }
1846 
1848  // Tests concerning loadExtension
1850 
1853  public function loadExtensionThrowsExceptionIfExtensionIsLoaded()
1854  {
1855  $this->expectException(\RuntimeException::class);
1856  $this->expectExceptionCode(1342345486);
1857 
1858  $extensionKey = $this->getUniqueId('test');
1859  $packageManager = $this->createMockPackageManagerWithMockPackage($extensionKey);
1860  ExtensionManagementUtility::setPackageManager($packageManager);
1861  ExtensionManagementUtility::loadExtension($extensionKey);
1862  }
1863 
1865  // Tests concerning unloadExtension
1867 
1870  public function unloadExtensionThrowsExceptionIfExtensionIsNotLoaded()
1871  {
1872  $this->expectException(\RuntimeException::class);
1873  $this->expectExceptionCode(1342345487);
1874 
1875  $packageName = $this->getUniqueId('foo');
1877  $packageManager = $this->getMockBuilder(PackageManager::class)
1878  ->setMethods(['isPackageActive'])
1879  ->getMock();
1880  $packageManager->expects($this->once())
1881  ->method('isPackageActive')
1882  ->with($this->equalTo($packageName))
1883  ->will($this->returnValue(false));
1884  ExtensionManagementUtility::setPackageManager($packageManager);
1885  ExtensionManagementUtility::unloadExtension($packageName);
1886  }
1887 
1891  public function unloadExtensionCallsPackageManagerToDeactivatePackage()
1892  {
1893  $packageName = $this->getUniqueId('foo');
1895  $packageManager = $this->getMockBuilder(PackageManager::class)
1896  ->setMethods(['isPackageActive', 'deactivatePackage'])
1897  ->getMock();
1898  $packageManager->expects($this->any())
1899  ->method('isPackageActive')
1900  ->will($this->returnValue(true));
1901  $packageManager->expects($this->once())
1902  ->method('deactivatePackage')
1903  ->with($packageName);
1904  ExtensionManagementUtility::setPackageManager($packageManager);
1905  ExtensionManagementUtility::unloadExtension($packageName);
1906  }
1907 
1909  // Tests concerning makeCategorizable
1911 
1914  public function doesMakeCategorizableCallsTheCategoryRegistryWithDefaultFieldName()
1915  {
1916  $extensionKey = $this->getUniqueId('extension');
1917  $tableName = $this->getUniqueId('table');
1918 
1920  $registryMock = $this->getMockBuilder(CategoryRegistry::class)->getMock();
1921  $registryMock->expects($this->once())->method('add')->with($extensionKey, $tableName, 'categories', []);
1922  GeneralUtility::setSingletonInstance(CategoryRegistry::class, $registryMock);
1923  ExtensionManagementUtility::makeCategorizable($extensionKey, $tableName);
1924  }
1925 
1929  public function doesMakeCategorizableCallsTheCategoryRegistryWithFieldName()
1930  {
1931  $extensionKey = $this->getUniqueId('extension');
1932  $tableName = $this->getUniqueId('table');
1933  $fieldName = $this->getUniqueId('field');
1934 
1936  $registryMock = $this->getMockBuilder(CategoryRegistry::class)->getMock();
1937  $registryMock->expects($this->once())->method('add')->with($extensionKey, $tableName, $fieldName, []);
1938  GeneralUtility::setSingletonInstance(CategoryRegistry::class, $registryMock);
1939  ExtensionManagementUtility::makeCategorizable($extensionKey, $tableName, $fieldName);
1940  }
1941 
1943  // Tests concerning addPlugin
1945 
1949  public function addPluginSetsTcaCorrectlyForGivenExtKeyAsParameter()
1950  {
1951  $extKey = 'indexed_search';
1952  $GLOBALS['TYPO3_LOADED_EXT'] = [];
1953  $GLOBALS['TYPO3_LOADED_EXT'][$extKey]['ext_icon'] = 'foo.gif';
1954  $expectedTCA = [
1955  [
1956  'label',
1957  $extKey,
1958  'EXT:' . $extKey . '/foo.gif'
1959  ]
1960  ];
1961  $GLOBALS['TCA']['tt_content']['columns']['list_type']['config']['items'] = [];
1962  ExtensionManagementUtility::addPlugin(['label', $extKey], 'list_type', $extKey);
1963  $this->assertEquals($expectedTCA, $GLOBALS['TCA']['tt_content']['columns']['list_type']['config']['items']);
1964  }
1965 
1969  public function addPluginSetsTcaCorrectlyForGivenExtKeyAsGlobal()
1970  {
1971  $extKey = 'indexed_search';
1972  $GLOBALS['TYPO3_LOADED_EXT'] = [];
1973  $GLOBALS['TYPO3_LOADED_EXT'][$extKey]['ext_icon'] = 'foo.gif';
1974  $GLOBALS['_EXTKEY'] = $extKey;
1975  $expectedTCA = [
1976  [
1977  'label',
1978  $extKey,
1979  'EXT:' . $extKey . '/foo.gif'
1980  ]
1981  ];
1982  $GLOBALS['TCA']['tt_content']['columns']['list_type']['config']['items'] = [];
1983  ExtensionManagementUtility::addPlugin(['label', $extKey]);
1984 
1985  $this->assertEquals($expectedTCA, $GLOBALS['TCA']['tt_content']['columns']['list_type']['config']['items']);
1986  }
1987 
1991  public function addPluginThrowsExceptionForMissingExtkey()
1992  {
1993  $this->expectException(\RuntimeException::class);
1994  $this->expectExceptionCode(1404068038);
1995 
1996  ExtensionManagementUtility::addPlugin('test');
1997  }
1998 }
static addFieldsToAllPalettesOfField($table, $field, $addFields, $insertionPosition='')
static mkdir_deep($directory, $deepDirectory='')
static resetSingletonInstances(array $newSingletonInstances)
static addToAllTCAtypes($table, $newFieldsString, $typeList='', $position='')
static addTcaSelectItem($table, $field, array $item, $relativeToField='', $relativePosition='')
createMockPackageManagerWithMockPackage($packageKey, $packageMethods=['getPackagePath', 'getPackageKey'])
static setPackageManager(PackageManager $packageManager)
if(TYPO3_MODE==='BE') $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tsfebeuserauth.php']['frontendEditingController']['default']
static addModule($main, $sub='', $position='', $path=null, $moduleConfiguration=[])
addTcaSelectItemInsertsItemAtSpecifiedPosition($relativeToField, $relativePosition, $expectedResultArray)
static addFieldsToPalette($table, $palette, $addFields, $insertionPosition='')