TYPO3CMS  8
 All Classes Namespaces Files Functions Variables Pages
ExtensionManagementUtilityTest.php
Go to the documentation of this file.
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 
28 
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(AbstractFrontend::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(AbstractFrontend::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(AbstractFrontend::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(AbstractFrontend::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(AbstractFrontend::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->any())->method('has')->will($this->returnValue(true));
1523  $mockCache->expects($this->once())->method('get')->willReturn('<?php ' . serialize(['tca' => [], 'categoryRegistry' => CategoryRegistry::getInstance()]) . '?>');
1524  ExtensionManagementUtilityAccessibleProxy::loadBaseTca(true);
1525  }
1526 
1530  public function loadBaseTcaCreatesCacheFileWithContentOfAnExtensionsConfigurationTcaPhpFile()
1531  {
1532  $extensionName = $this->getUniqueId('test_baseTca_');
1533  $packageManager = $this->createMockPackageManagerWithMockPackage($extensionName);
1534  $packagePath = $packageManager->getPackage($extensionName)->getPackagePath();
1535  GeneralUtility::mkdir($packagePath);
1536  GeneralUtility::mkdir($packagePath . 'Configuration/');
1537  GeneralUtility::mkdir($packagePath . 'Configuration/TCA/');
1538  $GLOBALS['TYPO3_LOADED_EXT'] = new LoadedExtensionsArray($packageManager);
1540  $uniqueTableName = $this->getUniqueId('table_name_');
1541  $uniqueStringInTableConfiguration = $this->getUniqueId('table_configuration_');
1542  $tableConfiguration = '<?php return array(\'foo\' => \'' . $uniqueStringInTableConfiguration . '\'); ?>';
1543  file_put_contents($packagePath . 'Configuration/TCA/' . $uniqueTableName . '.php', $tableConfiguration);
1544  $mockCache = $this->getMockBuilder(AbstractFrontend::class)
1545  ->setMethods(['getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove', 'flush', 'flushByTag', 'requireOnce'])
1546  ->disableOriginalConstructor()
1547  ->getMock();
1548 
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->once())->method('has')->will($this->returnValue(false));
1556  $mockCache->expects($this->once())->method('set')->with($this->anything(), $this->stringContains($uniqueStringInTableConfiguration), $this->anything());
1557  ExtensionManagementUtility::loadBaseTca(true);
1558  }
1559 
1563  public function loadBaseTcaWritesCacheEntryWithNoTags()
1564  {
1565  $mockCache = $this->getMockBuilder(AbstractFrontend::class)
1566  ->setMethods(['getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove', 'flush', 'flushByTag', 'requireOnce'])
1567  ->disableOriginalConstructor()
1568  ->getMock();
1569 
1571  $mockCacheManager = $this->getMockBuilder(CacheManager::class)
1572  ->setMethods(['getCache'])
1573  ->getMock();
1574  $mockCacheManager->expects($this->any())->method('getCache')->will($this->returnValue($mockCache));
1575  ExtensionManagementUtilityAccessibleProxy::setCacheManager($mockCacheManager);
1576  $mockCache->expects($this->once())->method('has')->will($this->returnValue(false));
1577  $mockCache->expects($this->once())->method('set')->with($this->anything(), $this->anything(), $this->equalTo([]));
1578  ExtensionManagementUtilityAccessibleProxy::loadBaseTca();
1579  }
1580 
1582  // Tests concerning getBaseTcaCacheIdentifier
1584 
1588  public function getBaseTcaCacheIdentifierCreatesSha1WithFourtyCharactersAndPrefix()
1589  {
1590  $prefix = 'tca_base_';
1591  $identifier = ExtensionManagementUtilityAccessibleProxy::getBaseTcaCacheIdentifier();
1592  $this->assertStringStartsWith($prefix, $identifier);
1593  $sha1 = str_replace($prefix, '', $identifier);
1594  $this->assertEquals(40, strlen($sha1));
1595  }
1596 
1598  // Tests concerning loadExtTables
1600 
1603  public function loadExtTablesDoesNotReadFromCacheIfCachingIsDenied()
1604  {
1606  $mockCacheManager = $this->getMockBuilder(CacheManager::class)
1607  ->setMethods(['getCache'])
1608  ->getMock();
1609  $mockCacheManager->expects($this->never())->method('getCache');
1610  ExtensionManagementUtilityAccessibleProxy::setCacheManager($mockCacheManager);
1611  $GLOBALS['TYPO3_LOADED_EXT'] = new LoadedExtensionsArray($this->createMockPackageManagerWithMockPackage($this->getUniqueId()));
1612  ExtensionManagementUtility::loadExtLocalconf(false);
1613  }
1614 
1618  public function loadExtTablesRequiresCacheFileIfExistsAndCachingIsAllowed()
1619  {
1620  $mockCache = $this->getMockBuilder(AbstractFrontend::class)
1621  ->setMethods(['getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove', 'flush', 'flushByTag', 'requireOnce'])
1622  ->disableOriginalConstructor()
1623  ->getMock();
1624 
1626  $mockCacheManager = $this->getMockBuilder(CacheManager::class)
1627  ->setMethods(['getCache'])
1628  ->getMock();
1629  $mockCacheManager->expects($this->any())->method('getCache')->will($this->returnValue($mockCache));
1630  ExtensionManagementUtilityAccessibleProxy::setCacheManager($mockCacheManager);
1631  $mockCache->expects($this->any())->method('has')->will($this->returnValue(true));
1632  $mockCache->expects($this->once())->method('requireOnce');
1633  // Reset the internal cache access tracking variable of extMgm
1634  // This method is only in the ProxyClass!
1635  ExtensionManagementUtilityAccessibleProxy::resetExtTablesWasReadFromCacheOnceBoolean();
1636  ExtensionManagementUtility::loadExtTables(true);
1637  }
1638 
1640  // Tests concerning createExtTablesCacheEntry
1642 
1645  public function createExtTablesCacheEntryWritesCacheEntryWithContentOfLoadedExtensionExtTables()
1646  {
1647  $extensionName = $this->getUniqueId('foo');
1648  $extTablesLocation = PATH_site . 'typo3temp/var/tests/' . $this->getUniqueId('test_ext_tables') . '.php';
1649  $this->testFilesToDelete[] = $extTablesLocation;
1650  $uniqueStringInTables = $this->getUniqueId('foo');
1651  file_put_contents($extTablesLocation, "<?php\n\n$uniqueStringInTables\n\n?>");
1652  $GLOBALS['TYPO3_LOADED_EXT'] = [
1653  $extensionName => [
1654  'ext_tables.php' => $extTablesLocation
1655  ]
1656  ];
1657  $mockCache = $this->getMockBuilder(AbstractFrontend::class)
1658  ->setMethods(['getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove', 'flush', 'flushByTag', 'requireOnce'])
1659  ->disableOriginalConstructor()
1660  ->getMock();
1661 
1663  $mockCacheManager = $this->getMockBuilder(CacheManager::class)
1664  ->setMethods(['getCache'])
1665  ->getMock();
1666  $mockCacheManager->expects($this->any())->method('getCache')->will($this->returnValue($mockCache));
1667  ExtensionManagementUtilityAccessibleProxy::setCacheManager($mockCacheManager);
1668  $mockCache->expects($this->once())->method('set')->with($this->anything(), $this->stringContains($uniqueStringInTables), $this->anything());
1669  ExtensionManagementUtilityAccessibleProxy::createExtTablesCacheEntry();
1670  }
1671 
1675  public function createExtTablesCacheEntryWritesCacheEntryWithExtensionContentOnlyIfExtTablesExists()
1676  {
1677  $extensionName = $this->getUniqueId('foo');
1678  $GLOBALS['TYPO3_LOADED_EXT'] = [
1679  $extensionName => [],
1680  ];
1681  $mockCache = $this->getMockBuilder(AbstractFrontend::class)
1682  ->setMethods(['getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove', 'flush', 'flushByTag', 'requireOnce'])
1683  ->disableOriginalConstructor()
1684  ->getMock();
1685 
1687  $mockCacheManager = $this->getMockBuilder(CacheManager::class)
1688  ->setMethods(['getCache'])
1689  ->getMock();
1690  $mockCacheManager->expects($this->any())->method('getCache')->will($this->returnValue($mockCache));
1691  ExtensionManagementUtilityAccessibleProxy::setCacheManager($mockCacheManager);
1692  $mockCache->expects($this->once())
1693  ->method('set')
1694  ->with($this->anything(), $this->logicalNot($this->stringContains($extensionName)), $this->anything());
1695  ExtensionManagementUtilityAccessibleProxy::createExtTablesCacheEntry();
1696  }
1697 
1701  public function createExtTablesCacheEntryWritesCacheEntryWithNoTags()
1702  {
1703  $mockCache = $this->getMockBuilder(AbstractFrontend::class)
1704  ->setMethods(['getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove', 'flush', 'flushByTag', 'requireOnce'])
1705  ->disableOriginalConstructor()
1706  ->getMock();
1707 
1709  $mockCacheManager = $this->getMockBuilder(CacheManager::class)
1710  ->setMethods(['getCache'])
1711  ->getMock();
1712  $mockCacheManager->expects($this->any())->method('getCache')->will($this->returnValue($mockCache));
1713  ExtensionManagementUtilityAccessibleProxy::setCacheManager($mockCacheManager);
1714  $mockCache->expects($this->once())->method('set')->with($this->anything(), $this->anything(), $this->equalTo([]));
1715  $GLOBALS['TYPO3_LOADED_EXT'] = new LoadedExtensionsArray($this->createMockPackageManagerWithMockPackage($this->getUniqueId()));
1716  ExtensionManagementUtilityAccessibleProxy::createExtTablesCacheEntry();
1717  }
1718 
1720  // Tests concerning getExtTablesCacheIdentifier
1722 
1725  public function getExtTablesCacheIdentifierCreatesSha1WithFourtyCharactersAndPrefix()
1726  {
1727  $prefix = 'ext_tables_';
1728  $identifier = ExtensionManagementUtilityAccessibleProxy::getExtTablesCacheIdentifier();
1729  $this->assertStringStartsWith($prefix, $identifier);
1730  $sha1 = str_replace($prefix, '', $identifier);
1731  $this->assertEquals(40, strlen($sha1));
1732  }
1733 
1735  // Tests concerning removeCacheFiles
1737 
1740  public function removeCacheFilesFlushesSystemCaches()
1741  {
1743  $mockCacheManager = $this->getMockBuilder(CacheManager::class)
1744  ->setMethods(['flushCachesInGroup'])
1745  ->getMock();
1746  $mockCacheManager->expects($this->once())->method('flushCachesInGroup')->with('system');
1747  ExtensionManagementUtilityAccessibleProxy::setCacheManager($mockCacheManager);
1748  ExtensionManagementUtility::removeCacheFiles();
1749  }
1750 
1752  // Tests concerning getExtensionVersion
1754 
1759  public function getExtensionVersionFaultyDataProvider()
1760  {
1761  return [
1762  [''],
1763  [0],
1764  [new \stdClass()],
1765  [true]
1766  ];
1767  }
1768 
1775  public function getExtensionVersionForFaultyExtensionKeyThrowsException($key)
1776  {
1777  $this->expectException(\InvalidArgumentException::class);
1778  $this->expectExceptionCode(1294586096);
1779 
1780  ExtensionManagementUtility::getExtensionVersion($key);
1781  }
1782 
1786  public function getExtensionVersionForNotLoadedExtensionReturnsEmptyString()
1787  {
1788  ExtensionManagementUtility::clearExtensionKeyMap();
1789  $uniqueSuffix = $this->getUniqueId('test');
1790  $extensionKey = 'unloadedextension' . $uniqueSuffix;
1791  $this->assertEquals('', ExtensionManagementUtility::getExtensionVersion($extensionKey));
1792  }
1793 
1797  public function getExtensionVersionForLoadedExtensionReturnsExtensionVersion()
1798  {
1799  ExtensionManagementUtility::clearExtensionKeyMap();
1800  $uniqueSuffix = $this->getUniqueId('test');
1801  $extensionKey = 'unloadedextension' . $uniqueSuffix;
1802  $packageMetaData = $this->getMockBuilder(MetaData::class)
1803  ->setMethods(['getVersion'])
1804  ->setConstructorArgs([$extensionKey])
1805  ->getMock();
1806  $packageMetaData->expects($this->any())->method('getVersion')->will($this->returnValue('1.2.3'));
1807  $packageManager = $this->createMockPackageManagerWithMockPackage($extensionKey, ['getPackagePath', 'getPackageKey', 'getPackageMetaData']);
1809  $package = $packageManager->getPackage($extensionKey);
1810  $package->expects($this->any())
1811  ->method('getPackageMetaData')
1812  ->will($this->returnValue($packageMetaData));
1813  ExtensionManagementUtility::setPackageManager($packageManager);
1814  $this->assertEquals('1.2.3', ExtensionManagementUtility::getExtensionVersion($extensionKey));
1815  }
1816 
1818  // Tests concerning loadExtension
1820 
1823  public function loadExtensionThrowsExceptionIfExtensionIsLoaded()
1824  {
1825  $this->expectException(\RuntimeException::class);
1826  $this->expectExceptionCode(1342345486);
1827 
1828  $extensionKey = $this->getUniqueId('test');
1829  $packageManager = $this->createMockPackageManagerWithMockPackage($extensionKey);
1830  ExtensionManagementUtility::setPackageManager($packageManager);
1831  ExtensionManagementUtility::loadExtension($extensionKey);
1832  }
1833 
1835  // Tests concerning unloadExtension
1837 
1840  public function unloadExtensionThrowsExceptionIfExtensionIsNotLoaded()
1841  {
1842  $this->expectException(\RuntimeException::class);
1843  $this->expectExceptionCode(1342345487);
1844 
1845  $packageName = $this->getUniqueId('foo');
1847  $packageManager = $this->getMockBuilder(PackageManager::class)
1848  ->setMethods(['isPackageActive'])
1849  ->getMock();
1850  $packageManager->expects($this->once())
1851  ->method('isPackageActive')
1852  ->with($this->equalTo($packageName))
1853  ->will($this->returnValue(false));
1854  ExtensionManagementUtility::setPackageManager($packageManager);
1855  ExtensionManagementUtility::unloadExtension($packageName);
1856  }
1857 
1861  public function unloadExtensionCallsPackageManagerToDeactivatePackage()
1862  {
1863  $packageName = $this->getUniqueId('foo');
1865  $packageManager = $this->getMockBuilder(PackageManager::class)
1866  ->setMethods(['isPackageActive', 'deactivatePackage'])
1867  ->getMock();
1868  $packageManager->expects($this->any())
1869  ->method('isPackageActive')
1870  ->will($this->returnValue(true));
1871  $packageManager->expects($this->once())
1872  ->method('deactivatePackage')
1873  ->with($packageName);
1874  ExtensionManagementUtility::setPackageManager($packageManager);
1875  ExtensionManagementUtility::unloadExtension($packageName);
1876  }
1877 
1879  // Tests concerning makeCategorizable
1881 
1884  public function doesMakeCategorizableCallsTheCategoryRegistryWithDefaultFieldName()
1885  {
1886  $extensionKey = $this->getUniqueId('extension');
1887  $tableName = $this->getUniqueId('table');
1888 
1890  $registryMock = $this->getMockBuilder(CategoryRegistry::class)->getMock();
1891  $registryMock->expects($this->once())->method('add')->with($extensionKey, $tableName, 'categories', []);
1892  GeneralUtility::setSingletonInstance(CategoryRegistry::class, $registryMock);
1893  ExtensionManagementUtility::makeCategorizable($extensionKey, $tableName);
1894  }
1895 
1899  public function doesMakeCategorizableCallsTheCategoryRegistryWithFieldName()
1900  {
1901  $extensionKey = $this->getUniqueId('extension');
1902  $tableName = $this->getUniqueId('table');
1903  $fieldName = $this->getUniqueId('field');
1904 
1906  $registryMock = $this->getMockBuilder(CategoryRegistry::class)->getMock();
1907  $registryMock->expects($this->once())->method('add')->with($extensionKey, $tableName, $fieldName, []);
1908  GeneralUtility::setSingletonInstance(CategoryRegistry::class, $registryMock);
1909  ExtensionManagementUtility::makeCategorizable($extensionKey, $tableName, $fieldName);
1910  }
1911 
1913  // Tests concerning addPlugin
1915 
1919  public function addPluginSetsTcaCorrectlyForGivenExtKeyAsParameter()
1920  {
1921  $extKey = 'indexed_search';
1922  $GLOBALS['TYPO3_LOADED_EXT'] = [];
1923  $GLOBALS['TYPO3_LOADED_EXT'][$extKey]['ext_icon'] = 'foo.gif';
1924  $expectedTCA = [
1925  [
1926  'label',
1927  $extKey,
1928  'EXT:' . $extKey . '/foo.gif'
1929  ]
1930  ];
1931  $GLOBALS['TCA']['tt_content']['columns']['list_type']['config']['items'] = [];
1932  ExtensionManagementUtility::addPlugin(['label', $extKey], 'list_type', $extKey);
1933  $this->assertEquals($expectedTCA, $GLOBALS['TCA']['tt_content']['columns']['list_type']['config']['items']);
1934  }
1935 
1939  public function addPluginSetsTcaCorrectlyForGivenExtKeyAsGlobal()
1940  {
1941  $extKey = 'indexed_search';
1942  $GLOBALS['TYPO3_LOADED_EXT'] = [];
1943  $GLOBALS['TYPO3_LOADED_EXT'][$extKey]['ext_icon'] = 'foo.gif';
1944  $GLOBALS['_EXTKEY'] = $extKey;
1945  $expectedTCA = [
1946  [
1947  'label',
1948  $extKey,
1949  'EXT:' . $extKey . '/foo.gif'
1950  ]
1951  ];
1952  $GLOBALS['TCA']['tt_content']['columns']['list_type']['config']['items'] = [];
1953  ExtensionManagementUtility::addPlugin(['label', $extKey]);
1954 
1955  $this->assertEquals($expectedTCA, $GLOBALS['TCA']['tt_content']['columns']['list_type']['config']['items']);
1956  }
1957 
1961  public function addPluginThrowsExceptionForMissingExtkey()
1962  {
1963  $this->expectException(\RuntimeException::class);
1964  $this->expectExceptionCode(1404068038);
1965 
1966  ExtensionManagementUtility::addPlugin('test');
1967  }
1968 }
static setPackageManager(PackageManager $packageManager)
static addModule($main, $sub= '', $position= '', $path=null, $moduleConfiguration=[])
static addToAllTCAtypes($table, $newFieldsString, $typeList= '', $position= '')
static mkdir_deep($directory, $deepDirectory= '')
static addTcaSelectItem($table, $field, array $item, $relativeToField= '', $relativePosition= '')
static addFieldsToAllPalettesOfField($table, $field, $addFields, $insertionPosition= '')
createMockPackageManagerWithMockPackage($packageKey, $packageMethods=['getPackagePath', 'getPackageKey'])
static resetSingletonInstances(array $newSingletonInstances)
if(TYPO3_MODE=== 'BE') $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tsfebeuserauth.php']['frontendEditingController']['default']
addTcaSelectItemInsertsItemAtSpecifiedPosition($relativeToField, $relativePosition, $expectedResultArray)
getAccessibleMock($originalClassName, $methods=[], array $arguments=[], $mockClassName= '', $callOriginalConstructor=true, $callOriginalClone=true, $callAutoload=true)
static addFieldsToPalette($table, $palette, $addFields, $insertionPosition= '')