‪TYPO3CMS  9.5
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 
23 use TYPO3\CMS\Core\Package\PackageManager;
27 use ‪TYPO3\CMS\Extbase\SignalSlot\Dispatcher as SignalSlotDispatcher;
28 use TYPO3\TestingFramework\Core\Unit\UnitTestCase;
29 
33 class ExtensionManagementUtilityTest extends UnitTestCase
34 {
38  protected $resetSingletonInstances = true;
39 
43  protected $backUpPackageManager;
44 
48  protected function setUp()
49  {
51  }
52 
56  protected function tearDown()
57  {
62  parent::tearDown();
63  }
64 
70  protected function createMockPackageManagerWithMockPackage($packageKey, $packageMethods = ['getPackagePath', 'getPackageKey'])
71  {
72  $packagePath = ‪Environment::getVarPath() . '/tests/' . $packageKey . '/';
73  GeneralUtility::mkdir_deep($packagePath);
74  $this->testFilesToDelete[] = $packagePath;
75  $package = $this->getMockBuilder(Package::class)
76  ->disableOriginalConstructor()
77  ->setMethods($packageMethods)
78  ->getMock();
79  $packageManager = $this->getMockBuilder(PackageManager::class)
80  ->setMethods(['isPackageActive', 'getPackage', 'getActivePackages'])
81  ->disableOriginalConstructor()
82  ->getMock();
83  $package->expects($this->any())
84  ->method('getPackagePath')
85  ->will($this->returnValue($packagePath));
86  $package->expects($this->any())
87  ->method('getPackageKey')
88  ->will($this->returnValue($packageKey));
89  $packageManager->expects($this->any())
90  ->method('isPackageActive')
91  ->will($this->returnValueMap([
92  [null, false],
93  [$packageKey, true]
94  ]));
95  $packageManager->expects($this->any())
96  ->method('getPackage')
97  ->with($this->equalTo($packageKey))
98  ->will($this->returnValue($package));
99  $packageManager->expects($this->any())
100  ->method('getActivePackages')
101  ->will($this->returnValue([$packageKey => $package]));
102  return $packageManager;
103  }
104 
106  // Tests concerning isLoaded
108 
111  public function isLoadedReturnsFalseIfExtensionIsNotLoaded()
112  {
113  $this->assertFalse(‪ExtensionManagementUtility::isLoaded($this->getUniqueId('foobar')));
114  }
115 
117  // Tests concerning extPath
119 
122  public function extPathThrowsExceptionIfExtensionIsNotLoaded()
123  {
124  $this->expectException(\BadFunctionCallException::class);
125  $this->expectExceptionCode(1365429656);
126 
127  $packageName = $this->getUniqueId('foo');
129  $packageManager = $this->getMockBuilder(PackageManager::class)
130  ->setMethods(['isPackageActive'])
131  ->disableOriginalConstructor()
132  ->getMock();
133  $packageManager->expects($this->once())
134  ->method('isPackageActive')
135  ->with($this->equalTo($packageName))
136  ->will($this->returnValue(false));
139  }
140 
144  public function extPathAppendsScriptNameToPath()
145  {
146  $package = $this->getMockBuilder(Package::class)
147  ->disableOriginalConstructor()
148  ->setMethods(['getPackagePath'])
149  ->getMock();
151  $packageManager = $this->getMockBuilder(PackageManager::class)
152  ->setMethods(['isPackageActive', 'getPackage'])
153  ->disableOriginalConstructor()
154  ->getMock();
155  $package->expects($this->once())
156  ->method('getPackagePath')
157  ->will($this->returnValue(‪Environment::getPublicPath() . '/foo/'));
158  $packageManager->expects($this->once())
159  ->method('isPackageActive')
160  ->with($this->equalTo('foo'))
161  ->will($this->returnValue(true));
162  $packageManager->expects($this->once())
163  ->method('getPackage')
164  ->with('foo')
165  ->will($this->returnValue($package));
167  $this->assertSame(‪Environment::getPublicPath() . '/foo/bar.txt', ‪ExtensionManagementUtility::extPath('foo', 'bar.txt'));
168  }
169 
171  // Utility functions
173 
179  private function generateTCAForTable($table)
180  {
181  ‪$tca = [];
182  ‪$tca[$table] = [];
183  ‪$tca[$table]['columns'] = [
184  'fieldA' => [],
185  'fieldC' => []
186  ];
187  ‪$tca[$table]['types'] = [
188  'typeA' => ['showitem' => 'fieldA, fieldB, fieldC;labelC, --palette--;;paletteC, fieldC1, fieldD, fieldD1'],
189  'typeB' => ['showitem' => 'fieldA, fieldB, fieldC;labelC, --palette--;;paletteC, fieldC1, fieldD, fieldD1'],
190  'typeC' => ['showitem' => 'fieldC;;paletteD']
191  ];
192  ‪$tca[$table]['palettes'] = [
193  'paletteA' => ['showitem' => 'fieldX, fieldX1, fieldY'],
194  'paletteB' => ['showitem' => 'fieldX, fieldX1, fieldY'],
195  'paletteC' => ['showitem' => 'fieldX, fieldX1, fieldY'],
196  'paletteD' => ['showitem' => 'fieldX, fieldX1, fieldY']
197  ];
198  return ‪$tca;
199  }
200 
206  public function extensionKeyDataProvider()
207  {
208  return [
209  'Without underscores' => [
210  'testkey',
211  'tx_testkey'
212  ],
213  'With underscores' => [
214  'this_is_a_test_extension',
215  'tx_thisisatestextension'
216  ],
217  'With user prefix and without underscores' => [
218  'user_testkey',
219  'user_testkey'
220  ],
221  'With user prefix and with underscores' => [
222  'user_test_key',
223  'user_testkey'
224  ],
225  ];
226  }
227 
234  public function getClassNamePrefixForExtensionKey($extensionName, $expectedPrefix)
235  {
236  $this->assertSame($expectedPrefix, ‪ExtensionManagementUtility::getCN($extensionName));
237  }
238 
240  // Tests concerning addToAllTCAtypes
242 
248  public function canAddFieldsToAllTCATypesBeforeExistingOnes()
249  {
250  $table = $this->getUniqueId('tx_coretest_table');
251  ‪$GLOBALS['TCA'] = $this->generateTCAForTable($table);
252  ‪ExtensionManagementUtility::addToAllTCAtypes($table, 'newA, newA, newB, fieldA', '', 'before:fieldD');
253  // Checking typeA:
254  $this->assertEquals('fieldA, fieldB, fieldC;labelC, --palette--;;paletteC, fieldC1, newA, newB, fieldD, fieldD1', ‪$GLOBALS['TCA'][$table]['types']['typeA']['showitem']);
255  // Checking typeB:
256  $this->assertEquals('fieldA, fieldB, fieldC;labelC, --palette--;;paletteC, fieldC1, newA, newB, fieldD, fieldD1', ‪$GLOBALS['TCA'][$table]['types']['typeB']['showitem']);
257  }
258 
265  public function canAddFieldsToAllTCATypesAfterExistingOnes()
266  {
267  $table = $this->getUniqueId('tx_coretest_table');
268  ‪$GLOBALS['TCA'] = $this->generateTCAForTable($table);
269  ‪ExtensionManagementUtility::addToAllTCAtypes($table, 'newA, newA, newB, fieldA', '', 'after:fieldC');
270  // Checking typeA:
271  $this->assertEquals('fieldA, fieldB, fieldC;labelC, newA, newB, --palette--;;paletteC, fieldC1, fieldD, fieldD1', ‪$GLOBALS['TCA'][$table]['types']['typeA']['showitem']);
272  // Checking typeB:
273  $this->assertEquals('fieldA, fieldB, fieldC;labelC, newA, newB, --palette--;;paletteC, fieldC1, fieldD, fieldD1', ‪$GLOBALS['TCA'][$table]['types']['typeB']['showitem']);
274  }
275 
282  public function canAddFieldsToAllTCATypesRespectsPalettes()
283  {
284  $table = $this->getUniqueId('tx_coretest_table');
285  ‪$GLOBALS['TCA'] = $this->generateTCAForTable($table);
286  ‪$GLOBALS['TCA'][$table]['types']['typeD'] = ['showitem' => 'fieldY, --palette--;;standard, fieldZ'];
287  ‪ExtensionManagementUtility::addToAllTCAtypes($table, 'newA, newA, newB, fieldA', '', 'after:--palette--;;standard');
288  // Checking typeD:
289  $this->assertEquals('fieldY, --palette--;;standard, newA, newB, fieldA, fieldZ', ‪$GLOBALS['TCA'][$table]['types']['typeD']['showitem']);
290  }
291 
298  public function canAddFieldsToAllTCATypesRespectsPositionFieldInPalette()
299  {
300  $table = $this->getUniqueId('tx_coretest_table');
301  ‪$GLOBALS['TCA'] = $this->generateTCAForTable($table);
302  ‪ExtensionManagementUtility::addToAllTCAtypes($table, 'newA, newA, newB, fieldA', '', 'after:fieldX1');
303  // Checking typeA:
304  $this->assertEquals('fieldA, fieldB, fieldC;labelC, --palette--;;paletteC, newA, newB, fieldC1, fieldD, fieldD1', ‪$GLOBALS['TCA'][$table]['types']['typeA']['showitem']);
305  }
306 
313  public function canAddFieldsToTCATypeBeforeExistingOnes()
314  {
315  $table = $this->getUniqueId('tx_coretest_table');
316  ‪$GLOBALS['TCA'] = $this->generateTCAForTable($table);
317  ‪ExtensionManagementUtility::addToAllTCAtypes($table, 'newA, newA, newB, fieldA', 'typeA', 'before:fieldD');
318  // Checking typeA:
319  $this->assertEquals('fieldA, fieldB, fieldC;labelC, --palette--;;paletteC, fieldC1, newA, newB, fieldD, fieldD1', ‪$GLOBALS['TCA'][$table]['types']['typeA']['showitem']);
320  // Checking typeB:
321  $this->assertEquals('fieldA, fieldB, fieldC;labelC, --palette--;;paletteC, fieldC1, fieldD, fieldD1', ‪$GLOBALS['TCA'][$table]['types']['typeB']['showitem']);
322  }
323 
330  public function canAddFieldsToTCATypeAfterExistingOnes()
331  {
332  $table = $this->getUniqueId('tx_coretest_table');
333  ‪$GLOBALS['TCA'] = $this->generateTCAForTable($table);
334  ‪ExtensionManagementUtility::addToAllTCAtypes($table, 'newA, newA, newB, fieldA', 'typeA', 'after:fieldC');
335  // Checking typeA:
336  $this->assertEquals('fieldA, fieldB, fieldC;labelC, newA, newB, --palette--;;paletteC, fieldC1, fieldD, fieldD1', ‪$GLOBALS['TCA'][$table]['types']['typeA']['showitem']);
337  // Checking typeB:
338  $this->assertEquals('fieldA, fieldB, fieldC;labelC, --palette--;;paletteC, fieldC1, fieldD, fieldD1', ‪$GLOBALS['TCA'][$table]['types']['typeB']['showitem']);
339  }
340 
344  public function canAddFieldWithPartOfAlreadyExistingFieldname()
345  {
346  $table = $this->getUniqueId('tx_coretest_table');
347  ‪$GLOBALS['TCA'] = $this->generateTCAForTable($table);
348  ‪ExtensionManagementUtility::addToAllTCAtypes($table, 'field', 'typeA', 'after:fieldD1');
349 
350  $this->assertEquals('fieldA, fieldB, fieldC;labelC, --palette--;;paletteC, fieldC1, fieldD, fieldD1, field', ‪$GLOBALS['TCA'][$table]['types']['typeA']['showitem']);
351  }
352 
359  public function canAddFieldsToTCATypeAndReplaceExistingOnes()
360  {
361  $table = $this->getUniqueId('tx_coretest_table');
362  ‪$GLOBALS['TCA'] = $this->generateTCAForTable($table);
363  $typesBefore = ‪$GLOBALS['TCA'][$table]['types'];
364  ‪ExtensionManagementUtility::addToAllTCAtypes($table, 'fieldZ', '', 'replace:fieldX');
365  $this->assertEquals($typesBefore, ‪$GLOBALS['TCA'][$table]['types'], 'It\'s wrong that the "types" array changes here - the replaced field is only on palettes');
366  // unchanged because the palette is not used
367  $this->assertEquals('fieldX, fieldX1, fieldY', ‪$GLOBALS['TCA'][$table]['palettes']['paletteA']['showitem']);
368  $this->assertEquals('fieldX, fieldX1, fieldY', ‪$GLOBALS['TCA'][$table]['palettes']['paletteB']['showitem']);
369  // changed
370  $this->assertEquals('fieldZ, fieldX1, fieldY', ‪$GLOBALS['TCA'][$table]['palettes']['paletteC']['showitem']);
371  $this->assertEquals('fieldZ, fieldX1, fieldY', ‪$GLOBALS['TCA'][$table]['palettes']['paletteD']['showitem']);
372  }
373 
377  public function addToAllTCAtypesReplacesExistingOnes()
378  {
379  $table = $this->getUniqueId('tx_coretest_table');
380  ‪$GLOBALS['TCA'] = $this->generateTCAForTable($table);
381  $typesBefore = ‪$GLOBALS['TCA'][$table]['types'];
382  ‪ExtensionManagementUtility::addToAllTCAtypes($table, 'fieldX, --palette--;;foo', '', 'replace:fieldX');
383  $this->assertEquals($typesBefore, ‪$GLOBALS['TCA'][$table]['types'], 'It\'s wrong that the "types" array changes here - the replaced field is only on palettes');
384  // unchanged because the palette is not used
385  $this->assertEquals('fieldX, fieldX1, fieldY', ‪$GLOBALS['TCA'][$table]['palettes']['paletteA']['showitem']);
386  $this->assertEquals('fieldX, fieldX1, fieldY', ‪$GLOBALS['TCA'][$table]['palettes']['paletteB']['showitem']);
387  // changed
388  $this->assertEquals('fieldX, --palette--;;foo, fieldX1, fieldY', ‪$GLOBALS['TCA'][$table]['palettes']['paletteC']['showitem']);
389  $this->assertEquals('fieldX, --palette--;;foo, fieldX1, fieldY', ‪$GLOBALS['TCA'][$table]['palettes']['paletteD']['showitem']);
390  }
391 
398  public function canAddFieldsToPaletteBeforeExistingOnes()
399  {
400  $table = $this->getUniqueId('tx_coretest_table');
401  ‪$GLOBALS['TCA'] = $this->generateTCAForTable($table);
402  ‪ExtensionManagementUtility::addFieldsToPalette($table, 'paletteA', 'newA, newA, newB, fieldX', 'before:fieldY');
403  $this->assertEquals('fieldX, fieldX1, newA, newB, fieldY', ‪$GLOBALS['TCA'][$table]['palettes']['paletteA']['showitem']);
404  }
405 
412  public function canAddFieldsToPaletteAfterExistingOnes()
413  {
414  $table = $this->getUniqueId('tx_coretest_table');
415  ‪$GLOBALS['TCA'] = $this->generateTCAForTable($table);
416  ‪ExtensionManagementUtility::addFieldsToPalette($table, 'paletteA', 'newA, newA, newB, fieldX', 'after:fieldX');
417  $this->assertEquals('fieldX, newA, newB, fieldX1, fieldY', ‪$GLOBALS['TCA'][$table]['palettes']['paletteA']['showitem']);
418  }
419 
426  public function canAddFieldsToPaletteAfterNotExistingOnes()
427  {
428  $table = $this->getUniqueId('tx_coretest_table');
429  ‪$GLOBALS['TCA'] = $this->generateTCAForTable($table);
430  ‪ExtensionManagementUtility::addFieldsToPalette($table, 'paletteA', 'newA, newA, newB, fieldX', 'after:' . $this->getUniqueId('notExisting'));
431  $this->assertEquals('fieldX, fieldX1, fieldY, newA, newB', ‪$GLOBALS['TCA'][$table]['palettes']['paletteA']['showitem']);
432  }
433 
437  public function removeDuplicatesForInsertionRemovesDuplicatesDataProvider()
438  {
439  return [
440  'Simple' => [
441  'field_b, field_d, field_c',
442  'field_a, field_b, field_c',
443  'field_d'
444  ],
445  'with linebreaks' => [
446  'field_b, --linebreak--, field_d, --linebreak--, field_c',
447  'field_a, field_b, field_c',
448  '--linebreak--, field_d, --linebreak--'
449  ],
450  'with linebreaks in list and insertion list' => [
451  'field_b, --linebreak--, field_d, --linebreak--, field_c',
452  'field_a, field_b, --linebreak--, field_c',
453  '--linebreak--, field_d, --linebreak--'
454  ],
455  ];
456  }
457 
465  public function removeDuplicatesForInsertionRemovesDuplicates($insertionList, $list, $expected)
466  {
468  $this->assertSame($expected, $result);
469  }
470 
472  // Tests concerning addFieldsToAllPalettesOfField
474 
478  public function addFieldsToAllPalettesOfFieldDoesNotAddAnythingIfFieldIsNotRegisteredInColumns()
479  {
480  ‪$GLOBALS['TCA'] = [
481  'aTable' => [
482  'types' => [
483  'typeA' => [
484  'showitem' => 'fieldA;labelA, --palette--;;paletteA',
485  ],
486  ],
487  'palettes' => [
488  'paletteA' => [
489  'showitem' => 'fieldX, fieldY',
490  ],
491  ],
492  ],
493  ];
494  $expected = ‪$GLOBALS['TCA'];
496  'aTable',
497  'fieldA',
498  'newA'
499  );
500  $this->assertEquals($expected, ‪$GLOBALS['TCA']);
501  }
502 
506  public function addFieldsToAllPalettesOfFieldAddsFieldsToPaletteAndSuppressesDuplicates()
507  {
508  ‪$GLOBALS['TCA'] = [
509  'aTable' => [
510  'columns' => [
511  'fieldA' => [],
512  ],
513  'types' => [
514  'typeA' => [
515  'showitem' => 'fieldA;labelA, --palette--;;paletteA',
516  ],
517  ],
518  'palettes' => [
519  'paletteA' => [
520  'showitem' => 'fieldX, fieldY',
521  ],
522  ],
523  ],
524  ];
525  $expected = [
526  'aTable' => [
527  'columns' => [
528  'fieldA' => [],
529  ],
530  'types' => [
531  'typeA' => [
532  'showitem' => 'fieldA;labelA, --palette--;;paletteA',
533  ],
534  ],
535  'palettes' => [
536  'paletteA' => [
537  'showitem' => 'fieldX, fieldY, dupeA',
538  ],
539  ],
540  ],
541  ];
543  'aTable',
544  'fieldA',
545  'dupeA, dupeA' // Duplicate
546  );
547  $this->assertEquals($expected, ‪$GLOBALS['TCA']);
548  }
549 
553  public function addFieldsToAllPalettesOfFieldDoesNotAddAFieldThatIsPartOfPaletteAlready()
554  {
555  ‪$GLOBALS['TCA'] = [
556  'aTable' => [
557  'columns' => [
558  'fieldA' => [],
559  ],
560  'types' => [
561  'typeA' => [
562  'showitem' => 'fieldA;labelA, --palette--;;paletteA',
563  ],
564  ],
565  'palettes' => [
566  'paletteA' => [
567  'showitem' => 'existingA',
568  ],
569  ],
570  ],
571  ];
572  $expected = [
573  'aTable' => [
574  'columns' => [
575  'fieldA' => [],
576  ],
577  'types' => [
578  'typeA' => [
579  'showitem' => 'fieldA;labelA, --palette--;;paletteA',
580  ],
581  ],
582  'palettes' => [
583  'paletteA' => [
584  'showitem' => 'existingA',
585  ],
586  ],
587  ],
588  ];
590  'aTable',
591  'fieldA',
592  'existingA'
593  );
594  $this->assertEquals($expected, ‪$GLOBALS['TCA']);
595  }
596 
600  public function addFieldsToAllPalettesOfFieldAddsFieldsToMultiplePalettes()
601  {
602  ‪$GLOBALS['TCA'] = [
603  'aTable' => [
604  'columns' => [
605  'fieldA' => [],
606  ],
607  'types' => [
608  'typeA' => [
609  'showitem' => 'fieldA, --palette--;;palette1',
610  ],
611  'typeB' => [
612  'showitem' => 'fieldA;aLabel, --palette--;;palette2',
613  ],
614  ],
615  'palettes' => [
616  'palette1' => [
617  'showitem' => 'fieldX',
618  ],
619  'palette2' => [
620  'showitem' => 'fieldY',
621  ],
622  ],
623  ],
624  ];
625  $expected = [
626  'aTable' => [
627  'columns' => [
628  'fieldA' => [],
629  ],
630  'types' => [
631  'typeA' => [
632  'showitem' => 'fieldA, --palette--;;palette1',
633  ],
634  'typeB' => [
635  'showitem' => 'fieldA;aLabel, --palette--;;palette2',
636  ],
637  ],
638  'palettes' => [
639  'palette1' => [
640  'showitem' => 'fieldX, newA',
641  ],
642  'palette2' => [
643  'showitem' => 'fieldY, newA',
644  ],
645  ],
646  ],
647  ];
649  'aTable',
650  'fieldA',
651  'newA'
652  );
653  $this->assertEquals($expected, ‪$GLOBALS['TCA']);
654  }
655 
659  public function addFieldsToAllPalettesOfFieldAddsMultipleFields()
660  {
661  ‪$GLOBALS['TCA'] = [
662  'aTable' => [
663  'columns' => [
664  'fieldA' => [],
665  ],
666  'types' => [
667  'typeA' => [
668  'showitem' => 'fieldA, --palette--;;palette1',
669  ],
670  ],
671  'palettes' => [
672  'palette1' => [
673  'showitem' => 'fieldX',
674  ],
675  ],
676  ],
677  ];
678  $expected = [
679  'aTable' => [
680  'columns' => [
681  'fieldA' => [],
682  ],
683  'types' => [
684  'typeA' => [
685  'showitem' => 'fieldA, --palette--;;palette1',
686  ],
687  ],
688  'palettes' => [
689  'palette1' => [
690  'showitem' => 'fieldX, newA, newB',
691  ],
692  ],
693  ],
694  ];
696  'aTable',
697  'fieldA',
698  'newA, newB'
699  );
700  $this->assertEquals($expected, ‪$GLOBALS['TCA']);
701  }
702 
706  public function addFieldsToAllPalettesOfFieldAddsBeforeExistingIfRequested()
707  {
708  ‪$GLOBALS['TCA'] = [
709  'aTable' => [
710  'columns' => [
711  'fieldA' => [],
712  ],
713  'types' => [
714  'typeA' => [
715  'showitem' => 'fieldA;labelA, --palette--;;paletteA',
716  ],
717  ],
718  'palettes' => [
719  'paletteA' => [
720  'showitem' => 'existingA, existingB',
721  ],
722  ],
723  ],
724  ];
725  $expected = [
726  'aTable' => [
727  'columns' => [
728  'fieldA' => [],
729  ],
730  'types' => [
731  'typeA' => [
732  'showitem' => 'fieldA;labelA, --palette--;;paletteA',
733  ],
734  ],
735  'palettes' => [
736  'paletteA' => [
737  'showitem' => 'existingA, newA, existingB',
738  ],
739  ],
740  ],
741  ];
743  'aTable',
744  'fieldA',
745  'newA',
746  'before:existingB'
747  );
748  $this->assertEquals($expected, ‪$GLOBALS['TCA']);
749  }
750 
754  public function addFieldsToAllPalettesOfFieldAddsFieldsAtEndIfBeforeRequestedDoesNotExist()
755  {
756  ‪$GLOBALS['TCA'] = [
757  'aTable' => [
758  'columns' => [
759  'fieldA' => [],
760  ],
761  'types' => [
762  'typeA' => [
763  'showitem' => 'fieldA;labelA, --palette--;;paletteA',
764  ],
765  ],
766  'palettes' => [
767  'paletteA' => [
768  'showitem' => 'fieldX, fieldY',
769  ],
770  ],
771  ],
772  ];
773  $expected = [
774  'aTable' => [
775  'columns' => [
776  'fieldA' => [],
777  ],
778  'types' => [
779  'typeA' => [
780  'showitem' => 'fieldA;labelA, --palette--;;paletteA',
781  ],
782  ],
783  'palettes' => [
784  'paletteA' => [
785  'showitem' => 'fieldX, fieldY, newA, newB',
786  ],
787  ],
788  ],
789  ];
791  'aTable',
792  'fieldA',
793  'newA, newB',
794  'before:notExisting'
795  );
796  $this->assertEquals($expected, ‪$GLOBALS['TCA']);
797  }
798 
802  public function addFieldsToAllPalettesOfFieldAddsAfterExistingIfRequested()
803  {
804  ‪$GLOBALS['TCA'] = [
805  'aTable' => [
806  'columns' => [
807  'fieldA' => [],
808  ],
809  'types' => [
810  'typeA' => [
811  'showitem' => 'fieldA;labelA, --palette--;;paletteA',
812  ],
813  ],
814  'palettes' => [
815  'paletteA' => [
816  'showitem' => 'existingA, existingB',
817  ],
818  ],
819  ],
820  ];
821  $expected = [
822  'aTable' => [
823  'columns' => [
824  'fieldA' => [],
825  ],
826  'types' => [
827  'typeA' => [
828  'showitem' => 'fieldA;labelA, --palette--;;paletteA',
829  ],
830  ],
831  'palettes' => [
832  'paletteA' => [
833  'showitem' => 'existingA, newA, existingB',
834  ],
835  ],
836  ],
837  ];
839  'aTable',
840  'fieldA',
841  'newA',
842  'after:existingA'
843  );
844  $this->assertEquals($expected, ‪$GLOBALS['TCA']);
845  }
846 
850  public function addFieldsToAllPalettesOfFieldAddsFieldsAtEndIfAfterRequestedDoesNotExist()
851  {
852  ‪$GLOBALS['TCA'] = [
853  'aTable' => [
854  'columns' => [
855  'fieldA' => [],
856  ],
857  'types' => [
858  'typeA' => [
859  'showitem' => 'fieldA;labelA, --palette--;;paletteA',
860  ],
861  ],
862  'palettes' => [
863  'paletteA' => [
864  'showitem' => 'existingA, existingB',
865  ],
866  ],
867  ],
868  ];
869  $expected = [
870  'aTable' => [
871  'columns' => [
872  'fieldA' => [],
873  ],
874  'types' => [
875  'typeA' => [
876  'showitem' => 'fieldA;labelA, --palette--;;paletteA',
877  ],
878  ],
879  'palettes' => [
880  'paletteA' => [
881  'showitem' => 'existingA, existingB, newA, newB',
882  ],
883  ],
884  ],
885  ];
887  'aTable',
888  'fieldA',
889  'newA, newB',
890  'after:notExistingA'
891  );
892  $this->assertEquals($expected, ‪$GLOBALS['TCA']);
893  }
894 
898  public function addFieldsToAllPalettesOfFieldAddsNewPaletteIfFieldHasNoPaletteYet()
899  {
900  ‪$GLOBALS['TCA'] = [
901  'aTable' => [
902  'columns' => [
903  'fieldA' => [],
904  ],
905  'types' => [
906  'typeA' => [
907  'showitem' => 'fieldA',
908  ],
909  ],
910  ],
911  ];
912  $expected = [
913  'aTable' => [
914  'columns' => [
915  'fieldA' => [],
916  ],
917  'types' => [
918  'typeA' => [
919  'showitem' => 'fieldA, --palette--;;generatedFor-fieldA',
920  ],
921  ],
922  'palettes' => [
923  'generatedFor-fieldA' => [
924  'showitem' => 'newA',
925  ],
926  ],
927  ],
928  ];
930  'aTable',
931  'fieldA',
932  'newA'
933  );
934  $this->assertEquals($expected, ‪$GLOBALS['TCA']);
935  }
936 
940  public function addFieldsToAllPalettesOfFieldAddsNewPaletteIfFieldHasNoPaletteYetAndKeepsExistingLabel()
941  {
942  ‪$GLOBALS['TCA'] = [
943  'aTable' => [
944  'columns' => [
945  'fieldA' => [],
946  ],
947  'types' => [
948  'typeA' => [
949  'showitem' => 'fieldA;labelA',
950  ],
951  ],
952  ],
953  ];
954  $expected = [
955  'aTable' => [
956  'columns' => [
957  'fieldA' => [],
958  ],
959  'types' => [
960  'typeA' => [
961  'showitem' => 'fieldA;labelA, --palette--;;generatedFor-fieldA',
962  ],
963  ],
964  'palettes' => [
965  'generatedFor-fieldA' => [
966  'showitem' => 'newA',
967  ],
968  ],
969  ],
970  ];
972  'aTable',
973  'fieldA',
974  'newA'
975  );
976  $this->assertEquals($expected, ‪$GLOBALS['TCA']);
977  }
978 
980  // Tests concerning executePositionedStringInsertion
982 
987  public function executePositionedStringInsertionTrimsCorrectCharactersDataProvider()
988  {
989  return [
990  'normal characters' => [
991  'tr0',
992  'tr0',
993  ],
994  'newlines' => [
995  "test\n",
996  'test',
997  ],
998  'newlines with carriage return' => [
999  "test\r\n",
1000  'test',
1001  ],
1002  'tabs' => [
1003  "test\t",
1004  'test',
1005  ],
1006  'commas' => [
1007  'test,',
1008  'test',
1009  ],
1010  'multiple commas with trailing spaces' => [
1011  "test,,\t, \r\n",
1012  'test',
1013  ],
1014  ];
1015  }
1016 
1023  public function executePositionedStringInsertionTrimsCorrectCharacters($string, $expectedResult)
1024  {
1025  $extensionManagementUtility = $this->getAccessibleMock(ExtensionManagementUtility::class, ['dummy']);
1026  $string = $extensionManagementUtility->_call('executePositionedStringInsertion', $string, '');
1027  $this->assertEquals($expectedResult, $string);
1028  }
1029 
1031  // Tests concerning addTcaSelectItem
1033 
1036  public function addTcaSelectItemThrowsExceptionIfTableIsNotOfTypeString()
1037  {
1038  $this->expectException(\InvalidArgumentException::class);
1039  $this->expectExceptionCode(1303236963);
1040 
1042  }
1043 
1047  public function addTcaSelectItemThrowsExceptionIfFieldIsNotOfTypeString()
1048  {
1049  $this->expectException(\InvalidArgumentException::class);
1050  $this->expectExceptionCode(1303236964);
1051 
1053  }
1054 
1058  public function addTcaSelectItemThrowsExceptionIfRelativeToFieldIsNotOfTypeString()
1059  {
1060  $this->expectException(\InvalidArgumentException::class);
1061  $this->expectExceptionCode(1303236965);
1062 
1064  }
1065 
1069  public function addTcaSelectItemThrowsExceptionIfRelativePositionIsNotOfTypeString()
1070  {
1071  $this->expectException(\InvalidArgumentException::class);
1072  $this->expectExceptionCode(1303236966);
1073 
1074  ‪ExtensionManagementUtility::addTcaSelectItem('foo', 'bar', [], 'foo', []);
1075  }
1076 
1080  public function addTcaSelectItemThrowsExceptionIfRelativePositionIsNotOneOfValidKeywords()
1081  {
1082  $this->expectException(\InvalidArgumentException::class);
1083  $this->expectExceptionCode(1303236967);
1084 
1085  ‪ExtensionManagementUtility::addTcaSelectItem('foo', 'bar', [], 'foo', 'not allowed keyword');
1086  }
1087 
1091  public function addTcaSelectItemThrowsExceptionIfFieldIsNotFoundInTca()
1092  {
1093  $this->expectException(\RuntimeException::class);
1094  $this->expectExceptionCode(1303237468);
1095 
1096  ‪$GLOBALS['TCA'] = [];
1098  }
1099 
1103  public function addTcaSelectItemDataProvider()
1104  {
1105  // Every array splits into:
1106  // - relativeToField
1107  // - relativePosition
1108  // - expectedResultArray
1109  return [
1110  'add at end of array' => [
1111  '',
1112  '',
1113  [
1114  0 => ['firstElement'],
1115  1 => ['matchMe'],
1116  2 => ['thirdElement'],
1117  3 => ['insertedElement']
1118  ]
1119  ],
1120  'replace element' => [
1121  'matchMe',
1122  'replace',
1123  [
1124  0 => ['firstElement'],
1125  1 => ['insertedElement'],
1126  2 => ['thirdElement']
1127  ]
1128  ],
1129  'add element after' => [
1130  'matchMe',
1131  'after',
1132  [
1133  0 => ['firstElement'],
1134  1 => ['matchMe'],
1135  2 => ['insertedElement'],
1136  3 => ['thirdElement']
1137  ]
1138  ],
1139  'add element before' => [
1140  'matchMe',
1141  'before',
1142  [
1143  0 => ['firstElement'],
1144  1 => ['insertedElement'],
1145  2 => ['matchMe'],
1146  3 => ['thirdElement']
1147  ]
1148  ],
1149  'add at end if relative position was not found' => [
1150  'notExistingItem',
1151  'after',
1152  [
1153  0 => ['firstElement'],
1154  1 => ['matchMe'],
1155  2 => ['thirdElement'],
1156  3 => ['insertedElement']
1157  ]
1158  ]
1159  ];
1160  }
1161 
1169  public function addTcaSelectItemInsertsItemAtSpecifiedPosition($relativeToField, $relativePosition, $expectedResultArray)
1170  {
1171  ‪$GLOBALS['TCA'] = [
1172  'testTable' => [
1173  'columns' => [
1174  'testField' => [
1175  'config' => [
1176  'items' => [
1177  '0' => ['firstElement'],
1178  '1' => ['matchMe'],
1179  2 => ['thirdElement']
1180  ]
1181  ]
1182  ]
1183  ]
1184  ]
1185  ];
1186  ‪ExtensionManagementUtility::addTcaSelectItem('testTable', 'testField', ['insertedElement'], $relativeToField, $relativePosition);
1187  $this->assertEquals($expectedResultArray, ‪$GLOBALS['TCA']['testTable']['columns']['testField']['config']['items']);
1188  }
1189 
1191  // Tests concerning loadExtLocalconf
1193 
1196  public function loadExtLocalconfDoesNotReadFromCacheIfCachingIsDenied()
1197  {
1199  $mockCacheManager = $this->getMockBuilder(CacheManager::class)
1200  ->setMethods(['getCache'])
1201  ->getMock();
1202  $mockCacheManager->expects($this->never())->method('getCache');
1204  $packageManager = $this->createMockPackageManagerWithMockPackage($this->getUniqueId());
1207  }
1208 
1212  public function loadExtLocalconfRequiresCacheFileIfExistsAndCachingIsAllowed()
1213  {
1214  $mockCache = $this->getMockBuilder(PhpFrontend::class)
1215  ->setMethods(['getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove', 'flush', 'flushByTag', 'require'])
1216  ->disableOriginalConstructor()
1217  ->getMock();
1218 
1220  $mockCacheManager = $this->getMockBuilder(CacheManager::class)
1221  ->setMethods(['getCache'])
1222  ->getMock();
1223  $mockCacheManager->expects($this->any())->method('getCache')->will($this->returnValue($mockCache));
1225  $mockCache->expects($this->any())->method('has')->will($this->returnValue(true));
1226  $mockCache->expects($this->once())->method('require');
1228  }
1229 
1231  // Tests concerning loadSingleExtLocalconfFiles
1233 
1236  public function loadSingleExtLocalconfFilesRequiresExtLocalconfFileRegisteredInGlobalTypo3LoadedExt()
1237  {
1238  $this->expectException(\RuntimeException::class);
1239  $this->expectExceptionCode(1340559079);
1240 
1241  $extensionName = $this->getUniqueId('foo');
1242  $packageManager = $this->createMockPackageManagerWithMockPackage($extensionName);
1243  $extLocalconfLocation = $packageManager->getPackage($extensionName)->getPackagePath() . 'ext_localconf.php';
1244  file_put_contents($extLocalconfLocation, "<?php\n\nthrow new RuntimeException('', 1340559079);\n\n?>");
1247  }
1248 
1250  // Tests concerning addModule
1252 
1257  public function addModulePositionTestsDataProvider()
1258  {
1259  return [
1260  'can add new main module if none exists' => [
1261  'top',
1262  '',
1263  'newModule'
1264  ],
1265  'can add new sub module if no position specified' => [
1266  '',
1267  'some,modules',
1268  'some,modules,newModule'
1269  ],
1270  'can add new sub module to top of module' => [
1271  'top',
1272  'some,modules',
1273  'newModule,some,modules'
1274  ],
1275  'can add new sub module if bottom of module' => [
1276  'bottom',
1277  'some,modules',
1278  'some,modules,newModule'
1279  ],
1280  'can add new sub module before specified sub module' => [
1281  'before:modules',
1282  'some,modules',
1283  'some,newModule,modules'
1284  ],
1285  'can add new sub module after specified sub module' => [
1286  'after:some',
1287  'some,modules',
1288  'some,newModule,modules'
1289  ],
1290  'can add new sub module at the bottom if specified sub module to add before does not exist' => [
1291  'before:modules',
1292  'some,otherModules',
1293  'some,otherModules,newModule'
1294  ],
1295  'can add new sub module at the bottom if specified sub module to add after does not exist' => [
1296  'after:some',
1297  'someOther,modules',
1298  'someOther,modules,newModule'
1299  ],
1300  ];
1301  }
1302 
1310  public function addModuleCanAddModule($position, $existing, $expected)
1311  {
1312  $mainModule = 'foobar';
1313  $subModule = 'newModule';
1314  if ($existing) {
1315  ‪$GLOBALS['TBE_MODULES'][$mainModule] = $existing;
1316  }
1317 
1318  ‪ExtensionManagementUtility::addModule($mainModule, $subModule, $position);
1319 
1320  $this->assertTrue(isset(‪$GLOBALS['TBE_MODULES'][$mainModule]));
1321  $this->assertEquals($expected, ‪$GLOBALS['TBE_MODULES'][$mainModule]);
1322  }
1323 
1325  // Tests concerning createExtLocalconfCacheEntry
1327 
1330  public function createExtLocalconfCacheEntryWritesCacheEntryWithContentOfLoadedExtensionExtLocalconf()
1331  {
1332  $extensionName = $this->getUniqueId('foo');
1333  $packageManager = $this->createMockPackageManagerWithMockPackage($extensionName);
1334  $extLocalconfLocation = $packageManager->getPackage($extensionName)->getPackagePath() . 'ext_localconf.php';
1335  $uniqueStringInLocalconf = $this->getUniqueId('foo');
1336  file_put_contents($extLocalconfLocation, "<?php\n\n" . $uniqueStringInLocalconf . "\n\n?>");
1338  $mockCache = $this->getMockBuilder(PhpFrontend::class)
1339  ->setMethods(['getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove', 'flush', 'flushByTag', 'require'])
1340  ->disableOriginalConstructor()
1341  ->getMock();
1342 
1343  $mockCache->expects($this->once())->method('set')->with($this->anything(), $this->stringContains($uniqueStringInLocalconf), $this->anything());
1345  }
1346 
1350  public function createExtLocalconfCacheEntryWritesCacheEntryWithExtensionContentOnlyIfExtLocalconfExists()
1351  {
1352  $extensionName = $this->getUniqueId('foo');
1353  $packageManager = $this->createMockPackageManagerWithMockPackage($extensionName);
1355  $mockCache = $this->getMockBuilder(PhpFrontend::class)
1356  ->setMethods(['getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove', 'flush', 'flushByTag', 'require'])
1357  ->disableOriginalConstructor()
1358  ->getMock();
1359 
1360  $mockCache->expects($this->once())
1361  ->method('set')
1362  ->with($this->anything(), $this->logicalNot($this->stringContains($extensionName)), $this->anything());
1364  }
1365 
1369  public function createExtLocalconfCacheEntryWritesCacheEntryWithNoTags()
1370  {
1371  $mockCache = $this->getMockBuilder(PhpFrontend::class)
1372  ->setMethods(['getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove', 'flush', 'flushByTag', 'require'])
1373  ->disableOriginalConstructor()
1374  ->getMock();
1375  $mockCache->expects($this->once())->method('set')->with($this->anything(), $this->anything(), $this->equalTo([]));
1376  $packageManager = $this->createMockPackageManagerWithMockPackage($this->getUniqueId());
1379  }
1380 
1382  // Tests concerning getExtLocalconfCacheIdentifier
1384 
1387  public function getExtLocalconfCacheIdentifierCreatesSha1WithFourtyCharactersAndPrefix()
1388  {
1389  $prefix = 'ext_localconf_';
1391  $this->assertStringStartsWith($prefix, $identifier);
1392  $sha1 = str_replace($prefix, '', $identifier);
1393  $this->assertEquals(40, strlen($sha1));
1394  }
1395 
1397  // Tests concerning loadBaseTca
1399 
1403  public function loadBaseTcaDoesNotReadFromCacheIfCachingIsDenied()
1404  {
1406  $mockCacheManager = $this->getMockBuilder(CacheManager::class)
1407  ->setMethods(['getCache'])
1408  ->getMock();
1409  $mockCacheManager->expects($this->never())->method('getCache');
1412  }
1413 
1417  public function loadBaseTcaRequiresCacheFileIfExistsAndCachingIsAllowed()
1418  {
1419  $mockCache = $this->getMockBuilder(PhpFrontend::class)
1420  ->setMethods(['getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove', 'flush', 'flushByTag', 'require'])
1421  ->disableOriginalConstructor()
1422  ->getMock();
1423 
1424  $mockCache->expects($this->once())->method('require')->willReturn(['tca' => [], 'categoryRegistry' => \serialize(‪CategoryRegistry::getInstance())]);
1426  }
1427 
1431  public function loadBaseTcaCreatesCacheFileWithContentOfAnExtensionsConfigurationTcaPhpFile()
1432  {
1433  $extensionName = $this->getUniqueId('test_baseTca_');
1434  $packageManager = $this->createMockPackageManagerWithMockPackage($extensionName);
1435  $packagePath = $packageManager->getPackage($extensionName)->getPackagePath();
1436  GeneralUtility::mkdir($packagePath);
1437  GeneralUtility::mkdir($packagePath . 'Configuration/');
1438  GeneralUtility::mkdir($packagePath . 'Configuration/TCA/');
1440  $uniqueTableName = $this->getUniqueId('table_name_');
1441  $uniqueStringInTableConfiguration = $this->getUniqueId('table_configuration_');
1442  $tableConfiguration = '<?php return array(\'foo\' => \'' . $uniqueStringInTableConfiguration . '\'); ?>';
1443  file_put_contents($packagePath . 'Configuration/TCA/' . $uniqueTableName . '.php', $tableConfiguration);
1444  $mockCache = $this->getMockBuilder(PhpFrontend::class)
1445  ->setMethods(['getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove', 'flush', 'flushByTag', 'require'])
1446  ->disableOriginalConstructor()
1447  ->getMock();
1448 
1450  $mockCacheManager = $this->getMockBuilder(CacheManager::class)
1451  ->setMethods(['getCache'])
1452  ->getMock();
1453  $mockCacheManager->expects($this->any())->method('getCache')->will($this->returnValue($mockCache));
1454  ExtensionManagementUtilityAccessibleProxy::setCacheManager($mockCacheManager);
1455  $mockCache->expects($this->once())->method('require')->will($this->returnValue(false));
1456  $mockCache->expects($this->once())->method('set')->with($this->anything(), $this->stringContains($uniqueStringInTableConfiguration), $this->anything());
1457 
1458  $mockSignalSlotDispatcher = $this->createMock(SignalSlotDispatcher::class);
1459  $mockSignalSlotDispatcher->expects($this->once())->method('dispatch')->with($this->anything(), $this->anything(), $this->isType('array'))->will($this->returnArgument(2));
1460  ExtensionManagementUtilityAccessibleProxy::setSignalSlotDispatcher($mockSignalSlotDispatcher);
1461 
1462  ExtensionManagementUtility::loadBaseTca(true);
1463  }
1464 
1468  public function loadBaseTcaWritesCacheEntryWithNoTags()
1469  {
1470  $mockCache = $this->getMockBuilder(PhpFrontend::class)
1471  ->setMethods(['getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove', 'flush', 'flushByTag', 'require'])
1472  ->disableOriginalConstructor()
1473  ->getMock();
1474 
1476  $mockCacheManager = $this->getMockBuilder(CacheManager::class)
1477  ->setMethods(['getCache'])
1478  ->getMock();
1479  $mockCacheManager->expects($this->any())->method('getCache')->will($this->returnValue($mockCache));
1480  ExtensionManagementUtilityAccessibleProxy::setCacheManager($mockCacheManager);
1481  $mockCache->expects($this->once())->method('require')->will($this->returnValue(false));
1482  $mockCache->expects($this->once())->method('set')->with($this->anything(), $this->anything(), $this->equalTo([]));
1483  ExtensionManagementUtilityAccessibleProxy::loadBaseTca();
1484  }
1485 
1487  // Tests concerning getBaseTcaCacheIdentifier
1489 
1493  public function getBaseTcaCacheIdentifierCreatesSha1WithFourtyCharactersAndPrefix()
1494  {
1495  $prefix = 'tca_base_';
1496  $identifier = ExtensionManagementUtilityAccessibleProxy::getBaseTcaCacheIdentifier();
1497  $this->assertStringStartsWith($prefix, $identifier);
1498  $sha1 = str_replace($prefix, '', $identifier);
1499  $this->assertEquals(40, strlen($sha1));
1500  }
1501 
1503  // Tests concerning loadExtTables
1505 
1508  public function loadExtTablesDoesNotReadFromCacheIfCachingIsDenied()
1509  {
1511  $mockCacheManager = $this->getMockBuilder(CacheManager::class)
1512  ->setMethods(['getCache'])
1513  ->getMock();
1514  $mockCacheManager->expects($this->never())->method('getCache');
1515  ExtensionManagementUtilityAccessibleProxy::setCacheManager($mockCacheManager);
1516  $packageManager = $this->createMockPackageManagerWithMockPackage($this->getUniqueId());
1517  ExtensionManagementUtility::setPackageManager($packageManager);
1518  ExtensionManagementUtility::loadExtLocalconf(false);
1519  }
1520 
1524  public function loadExtTablesRequiresCacheFileIfExistsAndCachingIsAllowed()
1525  {
1526  $mockCache = $this->getMockBuilder(PhpFrontend::class)
1527  ->setMethods(['getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove', 'flush', 'flushByTag', 'require'])
1528  ->disableOriginalConstructor()
1529  ->getMock();
1530 
1532  $mockCacheManager = $this->getMockBuilder(CacheManager::class)
1533  ->setMethods(['getCache'])
1534  ->getMock();
1535  $mockCacheManager->expects($this->any())->method('getCache')->will($this->returnValue($mockCache));
1536  ExtensionManagementUtilityAccessibleProxy::setCacheManager($mockCacheManager);
1537  $mockCache->expects($this->any())->method('has')->will($this->returnValue(true));
1538  $mockCache->expects($this->once())->method('require');
1539  // Reset the internal cache access tracking variable of extMgm
1540  // This method is only in the ProxyClass!
1541  ExtensionManagementUtilityAccessibleProxy::resetExtTablesWasReadFromCacheOnceBoolean();
1542  ExtensionManagementUtility::loadExtTables(true);
1543  }
1544 
1546  // Tests concerning createExtTablesCacheEntry
1548 
1551  public function createExtTablesCacheEntryWritesCacheEntryWithContentOfLoadedExtensionExtTables()
1552  {
1553  $extensionName = $this->getUniqueId('foo');
1554  $packageManager = $this->createMockPackageManagerWithMockPackage($extensionName);
1555  $extensionPath = $packageManager->getPackage($extensionName)->getPackagePath();
1556  $extTablesLocation = $extensionPath . 'ext_tables.php';
1557  $uniqueStringInTables = $this->getUniqueId('foo');
1558  file_put_contents($extTablesLocation, "<?php\n\n$uniqueStringInTables\n\n?>");
1559  ExtensionManagementUtility::setPackageManager($packageManager);
1560  $mockCache = $this->getMockBuilder(PhpFrontend::class)
1561  ->setMethods(['getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove', 'flush', 'flushByTag', 'require'])
1562  ->disableOriginalConstructor()
1563  ->getMock();
1564 
1566  $mockCacheManager = $this->getMockBuilder(CacheManager::class)
1567  ->setMethods(['getCache'])
1568  ->getMock();
1569  $mockCacheManager->expects($this->any())->method('getCache')->will($this->returnValue($mockCache));
1570  ExtensionManagementUtilityAccessibleProxy::setCacheManager($mockCacheManager);
1571  $mockCache->expects($this->once())->method('set')->with($this->anything(), $this->stringContains($uniqueStringInTables), $this->anything());
1572  ExtensionManagementUtilityAccessibleProxy::createExtTablesCacheEntry();
1573  }
1574 
1578  public function createExtTablesCacheEntryWritesCacheEntryWithExtensionContentOnlyIfExtTablesExists()
1579  {
1580  $extensionName = $this->getUniqueId('foo');
1581  $packageManager = $this->createMockPackageManagerWithMockPackage($extensionName);
1582  ExtensionManagementUtility::setPackageManager($packageManager);
1583  $mockCache = $this->getMockBuilder(PhpFrontend::class)
1584  ->setMethods(['getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove', 'flush', 'flushByTag', 'require'])
1585  ->disableOriginalConstructor()
1586  ->getMock();
1587 
1589  $mockCacheManager = $this->getMockBuilder(CacheManager::class)
1590  ->setMethods(['getCache'])
1591  ->getMock();
1592  $mockCacheManager->expects($this->any())->method('getCache')->will($this->returnValue($mockCache));
1593  ExtensionManagementUtilityAccessibleProxy::setCacheManager($mockCacheManager);
1594  $mockCache->expects($this->once())
1595  ->method('set')
1596  ->with($this->anything(), $this->logicalNot($this->stringContains($extensionName)), $this->anything());
1597  ExtensionManagementUtilityAccessibleProxy::createExtTablesCacheEntry();
1598  }
1599 
1603  public function createExtTablesCacheEntryWritesCacheEntryWithNoTags()
1604  {
1605  $mockCache = $this->getMockBuilder(PhpFrontend::class)
1606  ->setMethods(['getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove', 'flush', 'flushByTag', 'require'])
1607  ->disableOriginalConstructor()
1608  ->getMock();
1609 
1611  $mockCacheManager = $this->getMockBuilder(CacheManager::class)
1612  ->setMethods(['getCache'])
1613  ->getMock();
1614  $mockCacheManager->expects($this->any())->method('getCache')->will($this->returnValue($mockCache));
1615  ExtensionManagementUtilityAccessibleProxy::setCacheManager($mockCacheManager);
1616  $mockCache->expects($this->once())->method('set')->with($this->anything(), $this->anything(), $this->equalTo([]));
1617  $packageManager = $this->createMockPackageManagerWithMockPackage($this->getUniqueId());
1618  ExtensionManagementUtility::setPackageManager($packageManager);
1619  ExtensionManagementUtilityAccessibleProxy::createExtTablesCacheEntry();
1620  }
1621 
1623  // Tests concerning getExtTablesCacheIdentifier
1625 
1628  public function getExtTablesCacheIdentifierCreatesSha1WithFourtyCharactersAndPrefix()
1629  {
1630  $prefix = 'ext_tables_';
1631  $identifier = ExtensionManagementUtilityAccessibleProxy::getExtTablesCacheIdentifier();
1632  $this->assertStringStartsWith($prefix, $identifier);
1633  $sha1 = str_replace($prefix, '', $identifier);
1634  $this->assertEquals(40, strlen($sha1));
1635  }
1636 
1638  // Tests concerning getExtensionVersion
1640 
1645  public function getExtensionVersionFaultyDataProvider()
1646  {
1647  return [
1648  [''],
1649  [0],
1650  [new \stdClass()],
1651  [true]
1652  ];
1653  }
1654 
1661  public function getExtensionVersionForFaultyExtensionKeyThrowsException($key)
1662  {
1663  $this->expectException(\InvalidArgumentException::class);
1664  $this->expectExceptionCode(1294586096);
1665 
1666  ExtensionManagementUtility::getExtensionVersion($key);
1667  }
1668 
1672  public function getExtensionVersionForNotLoadedExtensionReturnsEmptyString()
1673  {
1674  ExtensionManagementUtility::clearExtensionKeyMap();
1675  $uniqueSuffix = $this->getUniqueId('test');
1676  $extensionKey = 'unloadedextension' . $uniqueSuffix;
1677  $this->assertEquals('', ExtensionManagementUtility::getExtensionVersion($extensionKey));
1678  }
1679 
1683  public function getExtensionVersionForLoadedExtensionReturnsExtensionVersion()
1684  {
1685  ExtensionManagementUtility::clearExtensionKeyMap();
1686  $uniqueSuffix = $this->getUniqueId('test');
1687  $extensionKey = 'unloadedextension' . $uniqueSuffix;
1688  $packageMetaData = $this->getMockBuilder(MetaData::class)
1689  ->setMethods(['getVersion'])
1690  ->setConstructorArgs([$extensionKey])
1691  ->getMock();
1692  $packageMetaData->expects($this->any())->method('getVersion')->will($this->returnValue('1.2.3'));
1693  $packageManager = $this->createMockPackageManagerWithMockPackage($extensionKey, ['getPackagePath', 'getPackageKey', 'getPackageMetaData']);
1695  $package = $packageManager->getPackage($extensionKey);
1696  $package->expects($this->any())
1697  ->method('getPackageMetaData')
1698  ->will($this->returnValue($packageMetaData));
1699  ExtensionManagementUtility::setPackageManager($packageManager);
1700  $this->assertEquals('1.2.3', ExtensionManagementUtility::getExtensionVersion($extensionKey));
1701  }
1702 
1704  // Tests concerning loadExtension
1706 
1709  public function loadExtensionThrowsExceptionIfExtensionIsLoaded()
1710  {
1711  $this->expectException(\RuntimeException::class);
1712  $this->expectExceptionCode(1342345486);
1713 
1714  $extensionKey = $this->getUniqueId('test');
1715  $packageManager = $this->createMockPackageManagerWithMockPackage($extensionKey);
1716  ExtensionManagementUtility::setPackageManager($packageManager);
1717  ExtensionManagementUtility::loadExtension($extensionKey);
1718  }
1719 
1721  // Tests concerning unloadExtension
1723 
1726  public function unloadExtensionThrowsExceptionIfExtensionIsNotLoaded()
1727  {
1728  $this->expectException(\RuntimeException::class);
1729  $this->expectExceptionCode(1342345487);
1730 
1731  $packageName = $this->getUniqueId('foo');
1733  $packageManager = $this->getMockBuilder(PackageManager::class)
1734  ->setMethods(['isPackageActive'])
1735  ->disableOriginalConstructor()
1736  ->getMock();
1737  $packageManager->expects($this->once())
1738  ->method('isPackageActive')
1739  ->with($this->equalTo($packageName))
1740  ->will($this->returnValue(false));
1741  ExtensionManagementUtility::setPackageManager($packageManager);
1742  ExtensionManagementUtility::unloadExtension($packageName);
1743  }
1744 
1748  public function unloadExtensionCallsPackageManagerToDeactivatePackage()
1749  {
1750  $packageName = $this->getUniqueId('foo');
1752  $packageManager = $this->getMockBuilder(PackageManager::class)
1753  ->setMethods(['isPackageActive', 'deactivatePackage'])
1754  ->disableOriginalConstructor()
1755  ->getMock();
1756  $packageManager->expects($this->any())
1757  ->method('isPackageActive')
1758  ->will($this->returnValue(true));
1759  $packageManager->expects($this->once())
1760  ->method('deactivatePackage')
1761  ->with($packageName);
1762  ExtensionManagementUtility::setPackageManager($packageManager);
1763  ExtensionManagementUtility::unloadExtension($packageName);
1764  }
1765 
1767  // Tests concerning makeCategorizable
1769 
1772  public function doesMakeCategorizableCallsTheCategoryRegistryWithDefaultFieldName()
1773  {
1774  $extensionKey = $this->getUniqueId('extension');
1775  $tableName = $this->getUniqueId('table');
1776 
1778  $registryMock = $this->getMockBuilder(CategoryRegistry::class)->getMock();
1779  $registryMock->expects($this->once())->method('add')->with($extensionKey, $tableName, 'categories', []);
1780  GeneralUtility::setSingletonInstance(CategoryRegistry::class, $registryMock);
1781  ExtensionManagementUtility::makeCategorizable($extensionKey, $tableName);
1782  }
1783 
1787  public function doesMakeCategorizableCallsTheCategoryRegistryWithFieldName()
1788  {
1789  $extensionKey = $this->getUniqueId('extension');
1790  $tableName = $this->getUniqueId('table');
1791  $fieldName = $this->getUniqueId('field');
1792 
1794  $registryMock = $this->getMockBuilder(CategoryRegistry::class)->getMock();
1795  $registryMock->expects($this->once())->method('add')->with($extensionKey, $tableName, $fieldName, []);
1796  GeneralUtility::setSingletonInstance(CategoryRegistry::class, $registryMock);
1797  ExtensionManagementUtility::makeCategorizable($extensionKey, $tableName, $fieldName);
1798  }
1799 
1801  // Tests concerning addPlugin
1803 
1807  public function addPluginSetsTcaCorrectlyForGivenExtKeyAsParameter()
1808  {
1809  $extKey = 'indexed_search';
1810  $expectedTCA = [
1811  [
1812  'label',
1813  $extKey,
1814  'EXT:' . $extKey . '/Resources/Public/Icons/Extension.png'
1815  ]
1816  ];
1817  $GLOBALS['TCA']['tt_content']['columns']['list_type']['config']['items'] = [];
1818  ExtensionManagementUtility::addPlugin(['label', $extKey], 'list_type', $extKey);
1819  $this->assertEquals($expectedTCA, $GLOBALS['TCA']['tt_content']['columns']['list_type']['config']['items']);
1820  }
1821 
1825  public function addPluginThrowsExceptionForMissingExtkey()
1826  {
1827  $this->expectException(\InvalidArgumentException::class);
1828  $this->expectExceptionCode(1404068038);
1829 
1830  ExtensionManagementUtility::addPlugin('test');
1831  }
1832 }
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\addModule
‪static addModule($main, $sub='', $position='', $path=null, $moduleConfiguration=[])
Definition: ExtensionManagementUtility.php:863
‪TYPO3\CMS\Core\Core\Environment\getPublicPath
‪static string getPublicPath()
Definition: Environment.php:153
‪TYPO3\CMS\Core\Tests\Unit\Utility\AccessibleProxies\ExtensionManagementUtilityAccessibleProxy\setCacheManager
‪static setCacheManager(CacheManager $cacheManager=null)
Definition: ExtensionManagementUtilityAccessibleProxy.php:27
‪TYPO3\CMS\Core\Tests\Unit\Utility\AccessibleProxies\ExtensionManagementUtilityAccessibleProxy\loadSingleExtLocalconfFiles
‪static loadSingleExtLocalconfFiles()
Definition: ExtensionManagementUtilityAccessibleProxy.php:47
‪TYPO3\CMS\Core\Tests\Unit\Utility\AccessibleProxies\ExtensionManagementUtilityAccessibleProxy\setSignalSlotDispatcher
‪static setSignalSlotDispatcher(Dispatcher $dispatcher=null)
Definition: ExtensionManagementUtilityAccessibleProxy.php:32
‪TYPO3\CMS\Core\Cache\Frontend\PhpFrontend
Definition: PhpFrontend.php:24
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\addFieldsToPalette
‪static addFieldsToPalette($table, $palette, $addFields, $insertionPosition='')
Definition: ExtensionManagementUtility.php:462
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\addTcaSelectItem
‪static addTcaSelectItem($table, $field, array $item, $relativeToField='', $relativePosition='')
Definition: ExtensionManagementUtility.php:503
‪TYPO3\CMS\Core\Tests\Unit\Utility
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\addToAllTCAtypes
‪static addToAllTCAtypes($table, $newFieldsString, $typeList='', $position='')
Definition: ExtensionManagementUtility.php:281
‪TYPO3\CMS\Core\Tests\Unit\Utility\AccessibleProxies\ExtensionManagementUtilityAccessibleProxy\removeDuplicatesForInsertion
‪static removeDuplicatesForInsertion($insertionList, $list='')
Definition: ExtensionManagementUtilityAccessibleProxy.php:86
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\addFieldsToAllPalettesOfField
‪static addFieldsToAllPalettesOfField($table, $field, $addFields, $insertionPosition='')
Definition: ExtensionManagementUtility.php:409
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility
Definition: ExtensionManagementUtility.php:36
‪TYPO3\CMS\Core\Category\CategoryRegistry\getInstance
‪static CategoryRegistry getInstance()
Definition: CategoryRegistry.php:50
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\clearExtensionKeyMap
‪static clearExtensionKeyMap()
Definition: ExtensionManagementUtility.php:214
‪TYPO3\CMS\Core\Tests\Unit\Utility\AccessibleProxies\ExtensionManagementUtilityAccessibleProxy\getExtLocalconfCacheIdentifier
‪static getExtLocalconfCacheIdentifier()
Definition: ExtensionManagementUtilityAccessibleProxy.php:42
‪TYPO3\CMS\Core\Category\CategoryRegistry
Definition: CategoryRegistry.php:27
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\setPackageManager
‪static setPackageManager(PackageManager $packageManager)
Definition: ExtensionManagementUtility.php:63
‪TYPO3\CMS\Core\Package\Package
Definition: Package.php:21
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\isLoaded
‪static bool isLoaded($key, $exitOnError=null)
Definition: ExtensionManagementUtility.php:115
‪TYPO3\CMS\Core\Cache\CacheManager
Definition: CacheManager.php:34
‪TYPO3\CMS\Core\Package\MetaData
Definition: PackageConstraint.php:2
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\getCN
‪static string getCN($key)
Definition: ExtensionManagementUtility.php:179
‪TYPO3\CMS\Core\Tests\Unit\Utility\AccessibleProxies\ExtensionManagementUtilityAccessibleProxy\getPackageManager
‪static getPackageManager()
Definition: ExtensionManagementUtilityAccessibleProxy.php:37
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:5
‪TYPO3\CMS\Core\Core\Environment
Definition: Environment.php:39
‪TYPO3\CMS\Core\Tests\Unit\Utility\AccessibleProxies\ExtensionManagementUtilityAccessibleProxy\createExtLocalconfCacheEntry
‪static createExtLocalconfCacheEntry(FrontendInterface $cache)
Definition: ExtensionManagementUtilityAccessibleProxy.php:62
‪$tca
‪$tca
Definition: sys_file_metadata.php:4
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\extPath
‪static string extPath($key, $script='')
Definition: ExtensionManagementUtility.php:149
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\loadBaseTca
‪static loadBaseTca($allowCaching=true, FrontendInterface $codeCache=null)
Definition: ExtensionManagementUtility.php:1646
‪TYPO3\CMS\Core\Tests\Unit\Utility\AccessibleProxies\ExtensionManagementUtilityAccessibleProxy
Definition: ExtensionManagementUtilityAccessibleProxy.php:26
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:45
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\loadExtLocalconf
‪static loadExtLocalconf($allowCaching=true, FrontendInterface $codeCache=null)
Definition: ExtensionManagementUtility.php:1543
‪TYPO3\CMS\Core\Core\Environment\getVarPath
‪static string getVarPath()
Definition: Environment.php:165
‪TYPO3\CMS\Extbase\SignalSlot\Dispatcher
Definition: Dispatcher.php:28