addTcaSelectItemInsertsItemAtSpecifiedPosition()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 19
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 11
dl 0
loc 19
rs 9.9
c 0
b 0
f 0
cc 1
nc 1
nop 3
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the TYPO3 CMS project.
7
 *
8
 * It is free software; you can redistribute it and/or modify it under
9
 * the terms of the GNU General Public License, either version 2
10
 * of the License, or any later version.
11
 *
12
 * For the full copyright and license information, please read the
13
 * LICENSE.txt file that was distributed with this source code.
14
 *
15
 * The TYPO3 project - inspiring people to share!
16
 */
17
18
namespace TYPO3\CMS\Core\Tests\Unit\Utility;
19
20
use Prophecy\Argument;
21
use Prophecy\PhpUnit\ProphecyTrait;
22
use Psr\EventDispatcher\EventDispatcherInterface;
23
use TYPO3\CMS\Core\Cache\CacheManager;
24
use TYPO3\CMS\Core\Cache\Frontend\PhpFrontend;
25
use TYPO3\CMS\Core\Core\Environment;
26
use TYPO3\CMS\Core\Package\Cache\PackageStatesPackageCache;
27
use TYPO3\CMS\Core\Package\MetaData;
28
use TYPO3\CMS\Core\Package\Package;
29
use TYPO3\CMS\Core\Package\PackageManager;
30
use TYPO3\CMS\Core\Tests\Unit\Utility\AccessibleProxies\ExtensionManagementUtilityAccessibleProxy;
31
use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
32
use TYPO3\CMS\Core\Utility\GeneralUtility;
33
use TYPO3\CMS\Core\Utility\StringUtility;
34
use TYPO3\TestingFramework\Core\Unit\UnitTestCase;
35
36
/**
37
 * Test case
38
 */
39
class ExtensionManagementUtilityTest extends UnitTestCase
40
{
41
    use ProphecyTrait;
42
43
    /**
44
     * @var bool Reset singletons created by subject
45
     */
46
    protected bool $resetSingletonInstances = true;
47
48
    protected ?PackageManager $backUpPackageManager;
49
50
    /**
51
     * Set up
52
     */
53
    protected function setUp(): void
54
    {
55
        parent::setUp();
56
        $this->backUpPackageManager = ExtensionManagementUtilityAccessibleProxy::getPackageManager();
57
    }
58
59
    /**
60
     * Tear down
61
     */
62
    protected function tearDown(): void
63
    {
64
        ExtensionManagementUtilityAccessibleProxy::setPackageManager($this->backUpPackageManager);
0 ignored issues
show
Bug introduced by
It seems like $this->backUpPackageManager can also be of type null; however, parameter $packageManager of TYPO3\CMS\Core\Utility\E...ty::setPackageManager() does only seem to accept TYPO3\CMS\Core\Package\PackageManager, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

64
        ExtensionManagementUtilityAccessibleProxy::setPackageManager(/** @scrutinizer ignore-type */ $this->backUpPackageManager);
Loading history...
65
        ExtensionManagementUtilityAccessibleProxy::setCacheManager(null);
66
        parent::tearDown();
67
    }
68
69
    /**
70
     * @param string $packageKey
71
     * @param array $packageMethods
72
     * @return PackageManager|\PHPUnit\Framework\MockObject\MockObject
73
     */
74
    protected function createMockPackageManagerWithMockPackage(string $packageKey, array $packageMethods = ['getPackagePath', 'getPackageKey'])
75
    {
76
        $packagePath = Environment::getVarPath() . '/tests/' . $packageKey . '/';
77
        GeneralUtility::mkdir_deep($packagePath);
78
        $this->testFilesToDelete[] = $packagePath;
79
        $package = $this->getMockBuilder(Package::class)
80
                ->disableOriginalConstructor()
81
                ->onlyMethods($packageMethods)
82
                ->getMock();
83
        $packageManager = $this->getMockBuilder(PackageManager::class)
84
            ->onlyMethods(['isPackageActive', 'getPackage', 'getActivePackages'])
85
            ->disableOriginalConstructor()
86
            ->getMock();
87
        $package
88
                ->method('getPackagePath')
89
                ->willReturn($packagePath);
90
        $package
91
                ->method('getPackageKey')
92
                ->willReturn($packageKey);
93
        $packageManager
94
                ->method('isPackageActive')
95
                ->willReturnMap([
96
                    [null, false],
97
                    [$packageKey, true],
98
                ]);
99
        $packageManager
100
                ->method('getPackage')
101
                ->with(self::equalTo($packageKey))
102
                ->willReturn($package);
103
        $packageManager
104
                ->method('getActivePackages')
105
                ->willReturn([$packageKey => $package]);
106
        return $packageManager;
107
    }
108
109
    ///////////////////////////////
110
    // Tests concerning isLoaded
111
    ///////////////////////////////
112
    /**
113
     * @test
114
     */
115
    public function isLoadedReturnsFalseIfExtensionIsNotLoaded(): void
116
    {
117
        self::assertFalse(ExtensionManagementUtility::isLoaded(StringUtility::getUniqueId('foobar')));
118
    }
119
120
    ///////////////////////////////
121
    // Tests concerning extPath
122
    ///////////////////////////////
123
    /**
124
     * @test
125
     */
126
    public function extPathThrowsExceptionIfExtensionIsNotLoaded(): void
127
    {
128
        $this->expectException(\BadFunctionCallException::class);
129
        $this->expectExceptionCode(1365429656);
130
131
        $packageName = StringUtility::getUniqueId('foo');
132
        /** @var PackageManager|\PHPUnit\Framework\MockObject\MockObject $packageManager */
133
        $packageManager = $this->getMockBuilder(PackageManager::class)
134
            ->onlyMethods(['isPackageActive'])
135
            ->disableOriginalConstructor()
136
            ->getMock();
137
        $packageManager->expects(self::once())
138
                ->method('isPackageActive')
139
                ->with(self::equalTo($packageName))
140
                ->willReturn(false);
141
        ExtensionManagementUtility::setPackageManager($packageManager);
142
        ExtensionManagementUtility::extPath($packageName);
143
    }
144
145
    /**
146
     * @test
147
     */
148
    public function extPathAppendsScriptNameToPath(): void
149
    {
150
        $package = $this->getMockBuilder(Package::class)
151
                ->disableOriginalConstructor()
152
                ->onlyMethods(['getPackagePath'])
153
                ->getMock();
154
        /** @var PackageManager|\PHPUnit\Framework\MockObject\MockObject $packageManager */
155
        $packageManager = $this->getMockBuilder(PackageManager::class)
156
            ->onlyMethods(['isPackageActive', 'getPackage'])
157
            ->disableOriginalConstructor()
158
            ->getMock();
159
        $package->expects(self::once())
160
                ->method('getPackagePath')
161
                ->willReturn(Environment::getPublicPath() . '/foo/');
162
        $packageManager->expects(self::once())
163
                ->method('isPackageActive')
164
                ->with(self::equalTo('foo'))
165
                ->willReturn(true);
166
        $packageManager->expects(self::once())
167
                ->method('getPackage')
168
                ->with('foo')
169
                ->willReturn($package);
170
        ExtensionManagementUtility::setPackageManager($packageManager);
171
        self::assertSame(Environment::getPublicPath() . '/foo/bar.txt', ExtensionManagementUtility::extPath('foo', 'bar.txt'));
172
    }
173
174
    //////////////////////
175
    // Utility functions
176
    //////////////////////
177
    /**
178
     * Generates a basic TCA for a given table.
179
     *
180
     * @param string $table name of the table, must not be empty
181
     * @return array generated TCA for the given table, will not be empty
182
     */
183
    private function generateTCAForTable($table): array
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
205
    /**
206
     * Data provider for getClassNamePrefixForExtensionKey.
207
     *
208
     * @return array
209
     */
210
    public function extensionKeyDataProvider(): array
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
232
    /**
233
     * @test
234
     * @param string $extensionName
235
     * @param string $expectedPrefix
236
     * @dataProvider extensionKeyDataProvider
237
     */
238
    public function getClassNamePrefixForExtensionKey(string $extensionName, string $expectedPrefix): void
239
    {
240
        self::assertSame($expectedPrefix, ExtensionManagementUtility::getCN($extensionName));
241
    }
242
243
    //////////////////////////////////////
244
    // Tests concerning addToAllTCAtypes
245
    //////////////////////////////////////
246
    /**
247
     * Tests whether fields can be add to all TCA types and duplicate fields are considered.
248
     *
249
     * @test
250
     * @see ExtensionManagementUtility::addToAllTCAtypes()
251
     */
252
    public function canAddFieldsToAllTCATypesBeforeExistingOnes(): void
253
    {
254
        $table = StringUtility::getUniqueId('tx_coretest_table');
255
        $GLOBALS['TCA'] = $this->generateTCAForTable($table);
256
        ExtensionManagementUtility::addToAllTCAtypes($table, 'newA, newA, newB, fieldA', '', 'before:fieldD');
257
        // Checking typeA:
258
        self::assertEquals('fieldA, fieldB, fieldC;labelC, --palette--;;paletteC, fieldC1, newA, newB, fieldD, fieldD1', $GLOBALS['TCA'][$table]['types']['typeA']['showitem']);
259
        // Checking typeB:
260
        self::assertEquals('fieldA, fieldB, fieldC;labelC, --palette--;;paletteC, fieldC1, newA, newB, fieldD, fieldD1', $GLOBALS['TCA'][$table]['types']['typeB']['showitem']);
261
    }
262
263
    /**
264
     * Tests whether fields can be add to all TCA types and duplicate fields are considered.
265
     *
266
     * @test
267
     * @see ExtensionManagementUtility::addToAllTCAtypes()
268
     */
269
    public function canAddFieldsToAllTCATypesAfterExistingOnes(): void
270
    {
271
        $table = StringUtility::getUniqueId('tx_coretest_table');
272
        $GLOBALS['TCA'] = $this->generateTCAForTable($table);
273
        ExtensionManagementUtility::addToAllTCAtypes($table, 'newA, newA, newB, fieldA', '', 'after:fieldC');
274
        // Checking typeA:
275
        self::assertEquals('fieldA, fieldB, fieldC;labelC, newA, newB, --palette--;;paletteC, fieldC1, fieldD, fieldD1', $GLOBALS['TCA'][$table]['types']['typeA']['showitem']);
276
        // Checking typeB:
277
        self::assertEquals('fieldA, fieldB, fieldC;labelC, newA, newB, --palette--;;paletteC, fieldC1, fieldD, fieldD1', $GLOBALS['TCA'][$table]['types']['typeB']['showitem']);
278
    }
279
280
    /**
281
     * Tests whether fields can be add to all TCA types and duplicate fields are considered.
282
     *
283
     * @test
284
     * @see ExtensionManagementUtility::addToAllTCAtypes()
285
     */
286
    public function canAddFieldsToAllTCATypesRespectsPalettes(): void
287
    {
288
        $table = StringUtility::getUniqueId('tx_coretest_table');
289
        $GLOBALS['TCA'] = $this->generateTCAForTable($table);
290
        $GLOBALS['TCA'][$table]['types']['typeD'] = ['showitem' => 'fieldY, --palette--;;standard, fieldZ'];
291
        ExtensionManagementUtility::addToAllTCAtypes($table, 'newA, newA, newB, fieldA', '', 'after:--palette--;;standard');
292
        // Checking typeD:
293
        self::assertEquals('fieldY, --palette--;;standard, newA, newB, fieldA, fieldZ', $GLOBALS['TCA'][$table]['types']['typeD']['showitem']);
294
    }
295
296
    /**
297
     * Tests whether fields can be add to all TCA types and fields in pallets are respected.
298
     *
299
     * @test
300
     * @see ExtensionManagementUtility::addToAllTCAtypes()
301
     */
302
    public function canAddFieldsToAllTCATypesRespectsPositionFieldInPalette(): void
303
    {
304
        $table = StringUtility::getUniqueId('tx_coretest_table');
305
        $GLOBALS['TCA'] = $this->generateTCAForTable($table);
306
        ExtensionManagementUtility::addToAllTCAtypes($table, 'newA, newA, newB, fieldA', '', 'after:fieldX1');
307
        // Checking typeA:
308
        self::assertEquals('fieldA, fieldB, fieldC;labelC, --palette--;;paletteC, newA, newB, fieldC1, fieldD, fieldD1', $GLOBALS['TCA'][$table]['types']['typeA']['showitem']);
309
    }
310
311
    /**
312
     * Tests whether fields can be add to a TCA type before existing ones
313
     *
314
     * @test
315
     * @see ExtensionManagementUtility::addToAllTCAtypes()
316
     */
317
    public function canAddFieldsToTCATypeBeforeExistingOnes(): void
318
    {
319
        $table = StringUtility::getUniqueId('tx_coretest_table');
320
        $GLOBALS['TCA'] = $this->generateTCAForTable($table);
321
        ExtensionManagementUtility::addToAllTCAtypes($table, 'newA, newA, newB, fieldA', 'typeA', 'before:fieldD');
322
        // Checking typeA:
323
        self::assertEquals('fieldA, fieldB, fieldC;labelC, --palette--;;paletteC, fieldC1, newA, newB, fieldD, fieldD1', $GLOBALS['TCA'][$table]['types']['typeA']['showitem']);
324
        // Checking typeB:
325
        self::assertEquals('fieldA, fieldB, fieldC;labelC, --palette--;;paletteC, fieldC1, fieldD, fieldD1', $GLOBALS['TCA'][$table]['types']['typeB']['showitem']);
326
    }
327
328
    /**
329
     * Tests whether fields can be add to a TCA type after existing ones
330
     *
331
     * @test
332
     * @see ExtensionManagementUtility::addToAllTCAtypes()
333
     */
334
    public function canAddFieldsToTCATypeAfterExistingOnes(): void
335
    {
336
        $table = StringUtility::getUniqueId('tx_coretest_table');
337
        $GLOBALS['TCA'] = $this->generateTCAForTable($table);
338
        ExtensionManagementUtility::addToAllTCAtypes($table, 'newA, newA, newB, fieldA', 'typeA', 'after:fieldC');
339
        // Checking typeA:
340
        self::assertEquals('fieldA, fieldB, fieldC;labelC, newA, newB, --palette--;;paletteC, fieldC1, fieldD, fieldD1', $GLOBALS['TCA'][$table]['types']['typeA']['showitem']);
341
        // Checking typeB:
342
        self::assertEquals('fieldA, fieldB, fieldC;labelC, --palette--;;paletteC, fieldC1, fieldD, fieldD1', $GLOBALS['TCA'][$table]['types']['typeB']['showitem']);
343
    }
344
345
    /**
346
     * @test
347
     */
348
    public function canAddFieldWithPartOfAlreadyExistingFieldname(): void
349
    {
350
        $table = StringUtility::getUniqueId('tx_coretest_table');
351
        $GLOBALS['TCA'] = $this->generateTCAForTable($table);
352
        ExtensionManagementUtility::addToAllTCAtypes($table, 'field', 'typeA', 'after:fieldD1');
353
354
        self::assertEquals('fieldA, fieldB, fieldC;labelC, --palette--;;paletteC, fieldC1, fieldD, fieldD1, field', $GLOBALS['TCA'][$table]['types']['typeA']['showitem']);
355
    }
356
357
    /**
358
     * Test whether replacing other TCA fields works as promised
359
     *
360
     * @test
361
     * @see ExtensionManagementUtility::addFieldsToAllPalettesOfField()
362
     */
363
    public function canAddFieldsToTCATypeAndReplaceExistingOnes(): void
364
    {
365
        $table = StringUtility::getUniqueId('tx_coretest_table');
366
        $GLOBALS['TCA'] = $this->generateTCAForTable($table);
367
        $typesBefore = $GLOBALS['TCA'][$table]['types'];
368
        ExtensionManagementUtility::addToAllTCAtypes($table, 'fieldZ', '', 'replace:fieldX');
369
        self::assertEquals($typesBefore, $GLOBALS['TCA'][$table]['types'], 'It\'s wrong that the "types" array changes here - the replaced field is only on palettes');
370
        // unchanged because the palette is not used
371
        self::assertEquals('fieldX, fieldX1, fieldY', $GLOBALS['TCA'][$table]['palettes']['paletteA']['showitem']);
372
        self::assertEquals('fieldX, fieldX1, fieldY', $GLOBALS['TCA'][$table]['palettes']['paletteB']['showitem']);
373
        // changed
374
        self::assertEquals('fieldZ, fieldX1, fieldY', $GLOBALS['TCA'][$table]['palettes']['paletteC']['showitem']);
375
        self::assertEquals('fieldZ, fieldX1, fieldY', $GLOBALS['TCA'][$table]['palettes']['paletteD']['showitem']);
376
    }
377
378
    /**
379
     * @test
380
     */
381
    public function addToAllTCAtypesReplacesExistingOnes(): void
382
    {
383
        $table = StringUtility::getUniqueId('tx_coretest_table');
384
        $GLOBALS['TCA'] = $this->generateTCAForTable($table);
385
        $typesBefore = $GLOBALS['TCA'][$table]['types'];
386
        ExtensionManagementUtility::addToAllTCAtypes($table, 'fieldX, --palette--;;foo', '', 'replace:fieldX');
387
        self::assertEquals($typesBefore, $GLOBALS['TCA'][$table]['types'], 'It\'s wrong that the "types" array changes here - the replaced field is only on palettes');
388
        // unchanged because the palette is not used
389
        self::assertEquals('fieldX, fieldX1, fieldY', $GLOBALS['TCA'][$table]['palettes']['paletteA']['showitem']);
390
        self::assertEquals('fieldX, fieldX1, fieldY', $GLOBALS['TCA'][$table]['palettes']['paletteB']['showitem']);
391
        // changed
392
        self::assertEquals('fieldX, --palette--;;foo, fieldX1, fieldY', $GLOBALS['TCA'][$table]['palettes']['paletteC']['showitem']);
393
        self::assertEquals('fieldX, --palette--;;foo, fieldX1, fieldY', $GLOBALS['TCA'][$table]['palettes']['paletteD']['showitem']);
394
    }
395
396
    /**
397
     * Tests whether fields can be added to a palette before existing elements.
398
     *
399
     * @test
400
     * @see ExtensionManagementUtility::addFieldsToPalette()
401
     */
402
    public function canAddFieldsToPaletteBeforeExistingOnes(): void
403
    {
404
        $table = StringUtility::getUniqueId('tx_coretest_table');
405
        $GLOBALS['TCA'] = $this->generateTCAForTable($table);
406
        ExtensionManagementUtility::addFieldsToPalette($table, 'paletteA', 'newA, newA, newB, fieldX', 'before:fieldY');
407
        self::assertEquals('fieldX, fieldX1, newA, newB, fieldY', $GLOBALS['TCA'][$table]['palettes']['paletteA']['showitem']);
408
    }
409
410
    /**
411
     * Tests whether fields can be added to a palette after existing elements.
412
     *
413
     * @test
414
     * @see ExtensionManagementUtility::addFieldsToPalette()
415
     */
416
    public function canAddFieldsToPaletteAfterExistingOnes(): void
417
    {
418
        $table = StringUtility::getUniqueId('tx_coretest_table');
419
        $GLOBALS['TCA'] = $this->generateTCAForTable($table);
420
        ExtensionManagementUtility::addFieldsToPalette($table, 'paletteA', 'newA, newA, newB, fieldX', 'after:fieldX');
421
        self::assertEquals('fieldX, newA, newB, fieldX1, fieldY', $GLOBALS['TCA'][$table]['palettes']['paletteA']['showitem']);
422
    }
423
424
    /**
425
     * Tests whether fields can be added to a palette after a not existing elements.
426
     *
427
     * @test
428
     * @see ExtensionManagementUtility::addFieldsToPalette()
429
     */
430
    public function canAddFieldsToPaletteAfterNotExistingOnes(): void
431
    {
432
        $table = StringUtility::getUniqueId('tx_coretest_table');
433
        $GLOBALS['TCA'] = $this->generateTCAForTable($table);
434
        ExtensionManagementUtility::addFieldsToPalette($table, 'paletteA', 'newA, newA, newB, fieldX', 'after:' . StringUtility::getUniqueId('notExisting'));
435
        self::assertEquals('fieldX, fieldX1, fieldY, newA, newB', $GLOBALS['TCA'][$table]['palettes']['paletteA']['showitem']);
436
    }
437
438
    /**
439
     * @return array
440
     */
441
    public function removeDuplicatesForInsertionRemovesDuplicatesDataProvider(): array
442
    {
443
        return [
444
            'Simple' => [
445
                'field_b, field_d, field_c',
446
                'field_a, field_b, field_c',
447
                'field_d',
448
            ],
449
            'with linebreaks' => [
450
                'field_b, --linebreak--, field_d, --linebreak--, field_c',
451
                'field_a, field_b, field_c',
452
                '--linebreak--, field_d, --linebreak--',
453
            ],
454
            'with linebreaks in list and insertion list' => [
455
                'field_b, --linebreak--, field_d, --linebreak--, field_c',
456
                'field_a, field_b, --linebreak--, field_c',
457
                '--linebreak--, field_d, --linebreak--',
458
            ],
459
        ];
460
    }
461
462
    /**
463
     * @test
464
     * @dataProvider removeDuplicatesForInsertionRemovesDuplicatesDataProvider
465
     * @param $insertionList
466
     * @param $list
467
     * @param $expected
468
     */
469
    public function removeDuplicatesForInsertionRemovesDuplicates($insertionList, $list, $expected): void
470
    {
471
        $result = ExtensionManagementUtilityAccessibleProxy::removeDuplicatesForInsertion($insertionList, $list);
472
        self::assertSame($expected, $result);
473
    }
474
475
    ///////////////////////////////////////////////////
476
    // Tests concerning addFieldsToAllPalettesOfField
477
    ///////////////////////////////////////////////////
478
479
    /**
480
     * @test
481
     */
482
    public function addFieldsToAllPalettesOfFieldDoesNotAddAnythingIfFieldIsNotRegisteredInColumns(): void
483
    {
484
        $GLOBALS['TCA'] = [
485
            'aTable' => [
486
                'types' => [
487
                    'typeA' => [
488
                        'showitem' => 'fieldA;labelA, --palette--;;paletteA',
489
                    ],
490
                ],
491
                'palettes' => [
492
                    'paletteA' => [
493
                        'showitem' => 'fieldX, fieldY',
494
                    ],
495
                ],
496
            ],
497
        ];
498
        $expected = $GLOBALS['TCA'];
499
        ExtensionManagementUtility::addFieldsToAllPalettesOfField(
500
            'aTable',
501
            'fieldA',
502
            'newA'
503
        );
504
        self::assertEquals($expected, $GLOBALS['TCA']);
505
    }
506
507
    /**
508
     * @test
509
     */
510
    public function addFieldsToAllPalettesOfFieldAddsFieldsToPaletteAndSuppressesDuplicates(): void
511
    {
512
        $GLOBALS['TCA'] = [
513
            'aTable' => [
514
                'columns' => [
515
                    'fieldA' => [],
516
                ],
517
                'types' => [
518
                    'typeA' => [
519
                        'showitem' => 'fieldA;labelA, --palette--;;paletteA',
520
                    ],
521
                ],
522
                'palettes' => [
523
                    'paletteA' => [
524
                        'showitem' => 'fieldX, fieldY',
525
                    ],
526
                ],
527
            ],
528
        ];
529
        $expected = [
530
            'aTable' => [
531
                'columns' => [
532
                    'fieldA' => [],
533
                ],
534
                'types' => [
535
                    'typeA' => [
536
                        'showitem' => 'fieldA;labelA, --palette--;;paletteA',
537
                    ],
538
                ],
539
                'palettes' => [
540
                    'paletteA' => [
541
                        'showitem' => 'fieldX, fieldY, dupeA',
542
                    ],
543
                ],
544
            ],
545
        ];
546
        ExtensionManagementUtility::addFieldsToAllPalettesOfField(
547
            'aTable',
548
            'fieldA',
549
            'dupeA, dupeA' // Duplicate
550
        );
551
        self::assertEquals($expected, $GLOBALS['TCA']);
552
    }
553
554
    /**
555
     * @test
556
     */
557
    public function addFieldsToAllPalettesOfFieldDoesNotAddAFieldThatIsPartOfPaletteAlready(): void
558
    {
559
        $GLOBALS['TCA'] = [
560
            'aTable' => [
561
                'columns' => [
562
                    'fieldA' => [],
563
                ],
564
                'types' => [
565
                    'typeA' => [
566
                        'showitem' => 'fieldA;labelA, --palette--;;paletteA',
567
                    ],
568
                ],
569
                'palettes' => [
570
                    'paletteA' => [
571
                        'showitem' => 'existingA',
572
                    ],
573
                ],
574
            ],
575
        ];
576
        $expected = [
577
            'aTable' => [
578
                'columns' => [
579
                    'fieldA' => [],
580
                ],
581
                'types' => [
582
                    'typeA' => [
583
                        'showitem' => 'fieldA;labelA, --palette--;;paletteA',
584
                    ],
585
                ],
586
                'palettes' => [
587
                    'paletteA' => [
588
                        'showitem' => 'existingA',
589
                    ],
590
                ],
591
            ],
592
        ];
593
        ExtensionManagementUtility::addFieldsToAllPalettesOfField(
594
            'aTable',
595
            'fieldA',
596
            'existingA'
597
        );
598
        self::assertEquals($expected, $GLOBALS['TCA']);
599
    }
600
601
    /**
602
     * @test
603
     */
604
    public function addFieldsToAllPalettesOfFieldAddsFieldsToMultiplePalettes(): void
605
    {
606
        $GLOBALS['TCA'] = [
607
            'aTable' => [
608
                'columns' => [
609
                    'fieldA' => [],
610
                ],
611
                'types' => [
612
                    'typeA' => [
613
                        'showitem' => 'fieldA, --palette--;;palette1',
614
                    ],
615
                    'typeB' => [
616
                        'showitem' => 'fieldA;aLabel, --palette--;;palette2',
617
                    ],
618
                ],
619
                'palettes' => [
620
                    'palette1' => [
621
                        'showitem' => 'fieldX',
622
                    ],
623
                    'palette2' => [
624
                        'showitem' => 'fieldY',
625
                    ],
626
                ],
627
            ],
628
        ];
629
        $expected = [
630
            'aTable' => [
631
                'columns' => [
632
                    'fieldA' => [],
633
                ],
634
                'types' => [
635
                    'typeA' => [
636
                        'showitem' => 'fieldA, --palette--;;palette1',
637
                    ],
638
                    'typeB' => [
639
                        'showitem' => 'fieldA;aLabel, --palette--;;palette2',
640
                    ],
641
                ],
642
                'palettes' => [
643
                    'palette1' => [
644
                        'showitem' => 'fieldX, newA',
645
                    ],
646
                    'palette2' => [
647
                        'showitem' => 'fieldY, newA',
648
                    ],
649
                ],
650
            ],
651
        ];
652
        ExtensionManagementUtility::addFieldsToAllPalettesOfField(
653
            'aTable',
654
            'fieldA',
655
            'newA'
656
        );
657
        self::assertEquals($expected, $GLOBALS['TCA']);
658
    }
659
660
    /**
661
     * @test
662
     */
663
    public function addFieldsToAllPalettesOfFieldAddsMultipleFields(): void
664
    {
665
        $GLOBALS['TCA'] = [
666
            'aTable' => [
667
                'columns' => [
668
                    'fieldA' => [],
669
                ],
670
                'types' => [
671
                    'typeA' => [
672
                        'showitem' => 'fieldA, --palette--;;palette1',
673
                    ],
674
                ],
675
                'palettes' => [
676
                    'palette1' => [
677
                        'showitem' => 'fieldX',
678
                    ],
679
                ],
680
            ],
681
        ];
682
        $expected = [
683
            'aTable' => [
684
                'columns' => [
685
                    'fieldA' => [],
686
                ],
687
                'types' => [
688
                    'typeA' => [
689
                        'showitem' => 'fieldA, --palette--;;palette1',
690
                    ],
691
                ],
692
                'palettes' => [
693
                    'palette1' => [
694
                        'showitem' => 'fieldX, newA, newB',
695
                    ],
696
                ],
697
            ],
698
        ];
699
        ExtensionManagementUtility::addFieldsToAllPalettesOfField(
700
            'aTable',
701
            'fieldA',
702
            'newA, newB'
703
        );
704
        self::assertEquals($expected, $GLOBALS['TCA']);
705
    }
706
707
    /**
708
     * @test
709
     */
710
    public function addFieldsToAllPalettesOfFieldAddsBeforeExistingIfRequested(): void
711
    {
712
        $GLOBALS['TCA'] = [
713
            'aTable' => [
714
                'columns' => [
715
                    'fieldA' => [],
716
                ],
717
                'types' => [
718
                    'typeA' => [
719
                        'showitem' => 'fieldA;labelA, --palette--;;paletteA',
720
                    ],
721
                ],
722
                'palettes' => [
723
                    'paletteA' => [
724
                        'showitem' => 'existingA, existingB',
725
                    ],
726
                ],
727
            ],
728
        ];
729
        $expected = [
730
            'aTable' => [
731
                'columns' => [
732
                    'fieldA' => [],
733
                ],
734
                'types' => [
735
                    'typeA' => [
736
                        'showitem' => 'fieldA;labelA, --palette--;;paletteA',
737
                    ],
738
                ],
739
                'palettes' => [
740
                    'paletteA' => [
741
                        'showitem' => 'existingA, newA, existingB',
742
                    ],
743
                ],
744
            ],
745
        ];
746
        ExtensionManagementUtility::addFieldsToAllPalettesOfField(
747
            'aTable',
748
            'fieldA',
749
            'newA',
750
            'before:existingB'
751
        );
752
        self::assertEquals($expected, $GLOBALS['TCA']);
753
    }
754
755
    /**
756
     * @test
757
     */
758
    public function addFieldsToAllPalettesOfFieldAddsFieldsAtEndIfBeforeRequestedDoesNotExist(): void
759
    {
760
        $GLOBALS['TCA'] = [
761
            'aTable' => [
762
                'columns' => [
763
                    'fieldA' => [],
764
                ],
765
                'types' => [
766
                    'typeA' => [
767
                        'showitem' => 'fieldA;labelA, --palette--;;paletteA',
768
                    ],
769
                ],
770
                'palettes' => [
771
                    'paletteA' => [
772
                        'showitem' => 'fieldX, fieldY',
773
                    ],
774
                ],
775
            ],
776
        ];
777
        $expected = [
778
            'aTable' => [
779
                'columns' => [
780
                    'fieldA' => [],
781
                ],
782
                'types' => [
783
                    'typeA' => [
784
                        'showitem' => 'fieldA;labelA, --palette--;;paletteA',
785
                    ],
786
                ],
787
                'palettes' => [
788
                    'paletteA' => [
789
                        'showitem' => 'fieldX, fieldY, newA, newB',
790
                    ],
791
                ],
792
            ],
793
        ];
794
        ExtensionManagementUtility::addFieldsToAllPalettesOfField(
795
            'aTable',
796
            'fieldA',
797
            'newA, newB',
798
            'before:notExisting'
799
        );
800
        self::assertEquals($expected, $GLOBALS['TCA']);
801
    }
802
803
    /**
804
     * @test
805
     */
806
    public function addFieldsToAllPalettesOfFieldAddsAfterExistingIfRequested(): void
807
    {
808
        $GLOBALS['TCA'] = [
809
            'aTable' => [
810
                'columns' => [
811
                    'fieldA' => [],
812
                ],
813
                'types' => [
814
                    'typeA' => [
815
                        'showitem' => 'fieldA;labelA, --palette--;;paletteA',
816
                    ],
817
                ],
818
                'palettes' => [
819
                    'paletteA' => [
820
                        'showitem' => 'existingA, existingB',
821
                    ],
822
                ],
823
            ],
824
        ];
825
        $expected = [
826
            'aTable' => [
827
                'columns' => [
828
                    'fieldA' => [],
829
                ],
830
                'types' => [
831
                    'typeA' => [
832
                        'showitem' => 'fieldA;labelA, --palette--;;paletteA',
833
                    ],
834
                ],
835
                'palettes' => [
836
                    'paletteA' => [
837
                        'showitem' => 'existingA, newA, existingB',
838
                    ],
839
                ],
840
            ],
841
        ];
842
        ExtensionManagementUtility::addFieldsToAllPalettesOfField(
843
            'aTable',
844
            'fieldA',
845
            'newA',
846
            'after:existingA'
847
        );
848
        self::assertEquals($expected, $GLOBALS['TCA']);
849
    }
850
851
    /**
852
     * @test
853
     */
854
    public function addFieldsToAllPalettesOfFieldAddsFieldsAtEndIfAfterRequestedDoesNotExist(): void
855
    {
856
        $GLOBALS['TCA'] = [
857
            'aTable' => [
858
                'columns' => [
859
                    'fieldA' => [],
860
                ],
861
                'types' => [
862
                    'typeA' => [
863
                        'showitem' => 'fieldA;labelA, --palette--;;paletteA',
864
                    ],
865
                ],
866
                'palettes' => [
867
                    'paletteA' => [
868
                        'showitem' => 'existingA, existingB',
869
                    ],
870
                ],
871
            ],
872
        ];
873
        $expected = [
874
            'aTable' => [
875
                'columns' => [
876
                    'fieldA' => [],
877
                ],
878
                'types' => [
879
                    'typeA' => [
880
                        'showitem' => 'fieldA;labelA, --palette--;;paletteA',
881
                    ],
882
                ],
883
                'palettes' => [
884
                    'paletteA' => [
885
                        'showitem' => 'existingA, existingB, newA, newB',
886
                    ],
887
                ],
888
            ],
889
        ];
890
        ExtensionManagementUtility::addFieldsToAllPalettesOfField(
891
            'aTable',
892
            'fieldA',
893
            'newA, newB',
894
            'after:notExistingA'
895
        );
896
        self::assertEquals($expected, $GLOBALS['TCA']);
897
    }
898
899
    /**
900
     * @test
901
     */
902
    public function addFieldsToAllPalettesOfFieldAddsNewPaletteIfFieldHasNoPaletteYet(): void
903
    {
904
        $GLOBALS['TCA'] = [
905
            'aTable' => [
906
                'columns' => [
907
                    'fieldA' => [],
908
                ],
909
                'types' => [
910
                    'typeA' => [
911
                        'showitem' => 'fieldA',
912
                    ],
913
                ],
914
            ],
915
        ];
916
        $expected = [
917
            'aTable' => [
918
                'columns' => [
919
                    'fieldA' => [],
920
                ],
921
                'types' => [
922
                    'typeA' => [
923
                        'showitem' => 'fieldA, --palette--;;generatedFor-fieldA',
924
                    ],
925
                ],
926
                'palettes' => [
927
                    'generatedFor-fieldA' => [
928
                        'showitem' => 'newA',
929
                    ],
930
                ],
931
            ],
932
        ];
933
        ExtensionManagementUtility::addFieldsToAllPalettesOfField(
934
            'aTable',
935
            'fieldA',
936
            'newA'
937
        );
938
        self::assertEquals($expected, $GLOBALS['TCA']);
939
    }
940
941
    /**
942
     * @test
943
     */
944
    public function addFieldsToAllPalettesOfFieldAddsNewPaletteIfFieldHasNoPaletteYetAndKeepsExistingLabel(): void
945
    {
946
        $GLOBALS['TCA'] = [
947
            'aTable' => [
948
                'columns' => [
949
                    'fieldA' => [],
950
                ],
951
                'types' => [
952
                    'typeA' => [
953
                        'showitem' => 'fieldA;labelA',
954
                    ],
955
                ],
956
            ],
957
        ];
958
        $expected = [
959
            'aTable' => [
960
                'columns' => [
961
                    'fieldA' => [],
962
                ],
963
                'types' => [
964
                    'typeA' => [
965
                        'showitem' => 'fieldA;labelA, --palette--;;generatedFor-fieldA',
966
                    ],
967
                ],
968
                'palettes' => [
969
                    'generatedFor-fieldA' => [
970
                        'showitem' => 'newA',
971
                    ],
972
                ],
973
            ],
974
        ];
975
        ExtensionManagementUtility::addFieldsToAllPalettesOfField(
976
            'aTable',
977
            'fieldA',
978
            'newA'
979
        );
980
        self::assertEquals($expected, $GLOBALS['TCA']);
981
    }
982
983
    ///////////////////////////////////////////////////
984
    // Tests concerning executePositionedStringInsertion
985
    ///////////////////////////////////////////////////
986
987
    /**
988
     * Data provider for executePositionedStringInsertionTrimsCorrectCharacters
989
     * @return array
990
     */
991
    public function executePositionedStringInsertionTrimsCorrectCharactersDataProvider(): array
992
    {
993
        return [
994
            'normal characters' => [
995
                'tr0',
996
                'tr0',
997
            ],
998
            'newlines' => [
999
                "test\n",
1000
                'test',
1001
            ],
1002
            'newlines with carriage return' => [
1003
                "test\r\n",
1004
                'test',
1005
            ],
1006
            'tabs' => [
1007
                "test\t",
1008
                'test',
1009
            ],
1010
            'commas' => [
1011
                'test,',
1012
                'test',
1013
            ],
1014
            'multiple commas with trailing spaces' => [
1015
                "test,,\t, \r\n",
1016
                'test',
1017
            ],
1018
        ];
1019
    }
1020
1021
    /**
1022
     * @test
1023
     * @dataProvider executePositionedStringInsertionTrimsCorrectCharactersDataProvider
1024
     * @param $string
1025
     * @param $expectedResult
1026
     */
1027
    public function executePositionedStringInsertionTrimsCorrectCharacters($string, $expectedResult): void
1028
    {
1029
        $extensionManagementUtility = $this->getAccessibleMock(ExtensionManagementUtility::class, ['dummy']);
1030
        $string = $extensionManagementUtility->_call('executePositionedStringInsertion', $string, '');
1031
        self::assertEquals($expectedResult, $string);
1032
    }
1033
1034
    /////////////////////////////////////////
1035
    // Tests concerning addTcaSelectItem
1036
    /////////////////////////////////////////
1037
    /**
1038
     * @test
1039
     */
1040
    public function addTcaSelectItemThrowsExceptionIfTableIsNotOfTypeString(): void
1041
    {
1042
        $this->expectException(\InvalidArgumentException::class);
1043
        $this->expectExceptionCode(1303236963);
1044
1045
        ExtensionManagementUtility::addTcaSelectItem([], 'foo', []);
0 ignored issues
show
Bug introduced by
array() of type array is incompatible with the type string expected by parameter $table of TYPO3\CMS\Core\Utility\E...ity::addTcaSelectItem(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

1045
        ExtensionManagementUtility::addTcaSelectItem(/** @scrutinizer ignore-type */ [], 'foo', []);
Loading history...
1046
    }
1047
1048
    /**
1049
     * @test
1050
     */
1051
    public function addTcaSelectItemThrowsExceptionIfFieldIsNotOfTypeString(): void
1052
    {
1053
        $this->expectException(\InvalidArgumentException::class);
1054
        $this->expectExceptionCode(1303236964);
1055
1056
        ExtensionManagementUtility::addTcaSelectItem('foo', [], []);
0 ignored issues
show
Bug introduced by
array() of type array is incompatible with the type string expected by parameter $field of TYPO3\CMS\Core\Utility\E...ity::addTcaSelectItem(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

1056
        ExtensionManagementUtility::addTcaSelectItem('foo', /** @scrutinizer ignore-type */ [], []);
Loading history...
1057
    }
1058
1059
    /**
1060
     * @test
1061
     */
1062
    public function addTcaSelectItemThrowsExceptionIfRelativeToFieldIsNotOfTypeString(): void
1063
    {
1064
        $this->expectException(\InvalidArgumentException::class);
1065
        $this->expectExceptionCode(1303236965);
1066
1067
        ExtensionManagementUtility::addTcaSelectItem('foo', 'bar', [], []);
0 ignored issues
show
Bug introduced by
array() of type array is incompatible with the type string expected by parameter $relativeToField of TYPO3\CMS\Core\Utility\E...ity::addTcaSelectItem(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

1067
        ExtensionManagementUtility::addTcaSelectItem('foo', 'bar', [], /** @scrutinizer ignore-type */ []);
Loading history...
1068
    }
1069
1070
    /**
1071
     * @test
1072
     */
1073
    public function addTcaSelectItemThrowsExceptionIfRelativePositionIsNotOfTypeString(): void
1074
    {
1075
        $this->expectException(\InvalidArgumentException::class);
1076
        $this->expectExceptionCode(1303236966);
1077
1078
        ExtensionManagementUtility::addTcaSelectItem('foo', 'bar', [], 'foo', []);
0 ignored issues
show
Bug introduced by
array() of type array is incompatible with the type string expected by parameter $relativePosition of TYPO3\CMS\Core\Utility\E...ity::addTcaSelectItem(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

1078
        ExtensionManagementUtility::addTcaSelectItem('foo', 'bar', [], 'foo', /** @scrutinizer ignore-type */ []);
Loading history...
1079
    }
1080
1081
    /**
1082
     * @test
1083
     */
1084
    public function addTcaSelectItemThrowsExceptionIfRelativePositionIsNotOneOfValidKeywords(): void
1085
    {
1086
        $this->expectException(\InvalidArgumentException::class);
1087
        $this->expectExceptionCode(1303236967);
1088
1089
        ExtensionManagementUtility::addTcaSelectItem('foo', 'bar', [], 'foo', 'not allowed keyword');
1090
    }
1091
1092
    /**
1093
     * @test
1094
     */
1095
    public function addTcaSelectItemThrowsExceptionIfFieldIsNotFoundInTca(): void
1096
    {
1097
        $this->expectException(\RuntimeException::class);
1098
        $this->expectExceptionCode(1303237468);
1099
1100
        $GLOBALS['TCA'] = [];
1101
        ExtensionManagementUtility::addTcaSelectItem('foo', 'bar', []);
1102
    }
1103
1104
    /**
1105
     * Data provider for addTcaSelectItemInsertsItemAtSpecifiedPosition
1106
     */
1107
    public function addTcaSelectItemDataProvider(): array
1108
    {
1109
        // Every array splits into:
1110
        // - relativeToField
1111
        // - relativePosition
1112
        // - expectedResultArray
1113
        return [
1114
            'add at end of array' => [
1115
                '',
1116
                '',
1117
                [
1118
                    0 => ['firstElement'],
1119
                    1 => ['matchMe'],
1120
                    2 => ['thirdElement'],
1121
                    3 => ['insertedElement'],
1122
                ],
1123
            ],
1124
            'replace element' => [
1125
                'matchMe',
1126
                'replace',
1127
                [
1128
                    0 => ['firstElement'],
1129
                    1 => ['insertedElement'],
1130
                    2 => ['thirdElement'],
1131
                ],
1132
            ],
1133
            'add element after' => [
1134
                'matchMe',
1135
                'after',
1136
                [
1137
                    0 => ['firstElement'],
1138
                    1 => ['matchMe'],
1139
                    2 => ['insertedElement'],
1140
                    3 => ['thirdElement'],
1141
                ],
1142
            ],
1143
            'add element before' => [
1144
                'matchMe',
1145
                'before',
1146
                [
1147
                    0 => ['firstElement'],
1148
                    1 => ['insertedElement'],
1149
                    2 => ['matchMe'],
1150
                    3 => ['thirdElement'],
1151
                ],
1152
            ],
1153
            'add at end if relative position was not found' => [
1154
                'notExistingItem',
1155
                'after',
1156
                [
1157
                    0 => ['firstElement'],
1158
                    1 => ['matchMe'],
1159
                    2 => ['thirdElement'],
1160
                    3 => ['insertedElement'],
1161
                ],
1162
            ],
1163
        ];
1164
    }
1165
1166
    /**
1167
     * @test
1168
     * @dataProvider addTcaSelectItemDataProvider
1169
     * @param $relativeToField
1170
     * @param $relativePosition
1171
     * @param $expectedResultArray
1172
     */
1173
    public function addTcaSelectItemInsertsItemAtSpecifiedPosition($relativeToField, $relativePosition, $expectedResultArray): void
1174
    {
1175
        $GLOBALS['TCA'] = [
1176
            'testTable' => [
1177
                'columns' => [
1178
                    'testField' => [
1179
                        'config' => [
1180
                            'items' => [
1181
                                '0' => ['firstElement'],
1182
                                '1' => ['matchMe'],
1183
                                2 => ['thirdElement'],
1184
                            ],
1185
                        ],
1186
                    ],
1187
                ],
1188
            ],
1189
        ];
1190
        ExtensionManagementUtility::addTcaSelectItem('testTable', 'testField', ['insertedElement'], $relativeToField, $relativePosition);
1191
        self::assertEquals($expectedResultArray, $GLOBALS['TCA']['testTable']['columns']['testField']['config']['items']);
1192
    }
1193
1194
    /////////////////////////////////////////
1195
    // Tests concerning loadExtLocalconf
1196
    /////////////////////////////////////////
1197
    /**
1198
     * @test
1199
     */
1200
    public function loadExtLocalconfDoesNotReadFromCacheIfCachingIsDenied(): void
1201
    {
1202
        /** @var CacheManager|\PHPUnit\Framework\MockObject\MockObject $mockCacheManager */
1203
        $mockCacheManager = $this->getMockBuilder(CacheManager::class)
1204
            ->onlyMethods(['getCache'])
1205
            ->getMock();
1206
        $mockCacheManager->expects(self::never())->method('getCache');
1207
        ExtensionManagementUtilityAccessibleProxy::setCacheManager($mockCacheManager);
1208
        $packageManager = $this->createMockPackageManagerWithMockPackage(StringUtility::getUniqueId());
1209
        ExtensionManagementUtility::setPackageManager($packageManager);
1210
        ExtensionManagementUtility::loadExtLocalconf(false);
1211
    }
1212
1213
    /**
1214
     * @test
1215
     */
1216
    public function loadExtLocalconfRequiresCacheFileIfExistsAndCachingIsAllowed(): void
1217
    {
1218
        $mockCache = $this->getMockBuilder(PhpFrontend::class)
1219
            ->onlyMethods(['getIdentifier', 'set', 'get', 'has', 'remove', 'flush', 'flushByTag', 'require'])
1220
            ->disableOriginalConstructor()
1221
            ->getMock();
1222
1223
        /** @var CacheManager|\PHPUnit\Framework\MockObject\MockObject $mockCacheManager */
1224
        $mockCacheManager = $this->getMockBuilder(CacheManager::class)
1225
            ->onlyMethods(['getCache'])
1226
            ->getMock();
1227
        $mockCacheManager->method('getCache')->willReturn($mockCache);
1228
        ExtensionManagementUtilityAccessibleProxy::setCacheManager($mockCacheManager);
1229
        $mockCache->method('has')->willReturn(true);
1230
        $mockCache->expects(self::once())->method('require');
1231
        ExtensionManagementUtility::loadExtLocalconf(true);
1232
    }
1233
1234
    /////////////////////////////////////////
1235
    // Tests concerning loadSingleExtLocalconfFiles
1236
    /////////////////////////////////////////
1237
    /**
1238
     * @test
1239
     */
1240
    public function loadSingleExtLocalconfFilesRequiresExtLocalconfFileRegisteredInGlobalTypo3LoadedExt(): void
1241
    {
1242
        $this->expectException(\RuntimeException::class);
1243
        $this->expectExceptionCode(1340559079);
1244
1245
        $extensionName = StringUtility::getUniqueId('foo');
1246
        $packageManager = $this->createMockPackageManagerWithMockPackage($extensionName);
1247
        $extLocalconfLocation = $packageManager->getPackage($extensionName)->getPackagePath() . 'ext_localconf.php';
1248
        file_put_contents($extLocalconfLocation, "<?php\n\nthrow new RuntimeException('', 1340559079);\n\n?>");
1249
        ExtensionManagementUtility::setPackageManager($packageManager);
1250
        ExtensionManagementUtilityAccessibleProxy::loadSingleExtLocalconfFiles();
1251
    }
1252
1253
    /////////////////////////////////////////
1254
    // Tests concerning addModule
1255
    /////////////////////////////////////////
1256
1257
    /**
1258
     * Data provider for addModule tests
1259
     * @return array
1260
     */
1261
    public function addModulePositionTestsDataProvider(): array
1262
    {
1263
        return [
1264
            'can add new main module if none exists' => [
1265
                'top',
1266
                '',
1267
                'newModule',
1268
            ],
1269
            'can add new sub module if no position specified' => [
1270
                '',
1271
                'some,modules',
1272
                'some,modules,newModule',
1273
            ],
1274
            'can add new sub module to top of module' => [
1275
                'top',
1276
                'some,modules',
1277
                'newModule,some,modules',
1278
            ],
1279
            'can add new sub module if bottom of module' => [
1280
                'bottom',
1281
                'some,modules',
1282
                'some,modules,newModule',
1283
            ],
1284
            'can add new sub module before specified sub module' => [
1285
                'before:modules',
1286
                'some,modules',
1287
                'some,newModule,modules',
1288
            ],
1289
            'can add new sub module after specified sub module' => [
1290
                'after:some',
1291
                'some,modules',
1292
                'some,newModule,modules',
1293
            ],
1294
            'can add new sub module at the bottom if specified sub module to add before does not exist' => [
1295
                'before:modules',
1296
                'some,otherModules',
1297
                'some,otherModules,newModule',
1298
            ],
1299
            'can add new sub module at the bottom if specified sub module to add after does not exist' => [
1300
                'after:some',
1301
                'someOther,modules',
1302
                'someOther,modules,newModule',
1303
            ],
1304
        ];
1305
    }
1306
1307
    /**
1308
     * @test
1309
     * @dataProvider addModulePositionTestsDataProvider
1310
     * @param $position
1311
     * @param $existing
1312
     * @param $expected
1313
     */
1314
    public function addModuleCanAddModule($position, $existing, $expected): void
1315
    {
1316
        $mainModule = 'foobar';
1317
        $subModule = 'newModule';
1318
        if ($existing) {
1319
            $GLOBALS['TBE_MODULES'][$mainModule] = $existing;
1320
        }
1321
1322
        ExtensionManagementUtility::addModule($mainModule, $subModule, $position);
1323
1324
        self::assertTrue(isset($GLOBALS['TBE_MODULES'][$mainModule]));
1325
        self::assertEquals($expected, $GLOBALS['TBE_MODULES'][$mainModule]);
1326
    }
1327
1328
    /**
1329
     * @test
1330
     * @dataProvider addModulePositionTestsDataProvider
1331
     * @param $position
1332
     * @param $existing
1333
     * @param $expected
1334
     */
1335
    public function addModuleCanAddMainModule($position, $existing, $expected): void
1336
    {
1337
        $mainModule = 'newModule';
1338
        if ($existing) {
1339
            foreach (explode(',', $existing) as $existingMainModule) {
1340
                $GLOBALS['TBE_MODULES'][$existingMainModule] = '';
1341
            }
1342
        }
1343
1344
        ExtensionManagementUtility::addModule($mainModule, '', $position);
1345
1346
        self::assertTrue(isset($GLOBALS['TBE_MODULES'][$mainModule]));
1347
        unset($GLOBALS['TBE_MODULES']['_configuration']);
1348
        unset($GLOBALS['TBE_MODULES']['_navigationComponents']);
1349
        self::assertEquals($expected, implode(',', array_keys($GLOBALS['TBE_MODULES'])));
1350
    }
1351
1352
    /////////////////////////////////////////
1353
    // Tests concerning createExtLocalconfCacheEntry
1354
    /////////////////////////////////////////
1355
    /**
1356
     * @test
1357
     */
1358
    public function createExtLocalconfCacheEntryWritesCacheEntryWithContentOfLoadedExtensionExtLocalconf(): void
1359
    {
1360
        $extensionName = StringUtility::getUniqueId('foo');
1361
        $packageManager = $this->createMockPackageManagerWithMockPackage($extensionName);
1362
        $mockCache = $this->getMockBuilder(PhpFrontend::class)->disableOriginalConstructor()->getMock();
1363
        $packageManager->setPackageCache(new PackageStatesPackageCache('vfs://Test/Configuration/PackageStates.php', $mockCache));
1364
        $extLocalconfLocation = $packageManager->getPackage($extensionName)->getPackagePath() . 'ext_localconf.php';
1365
        $uniqueStringInLocalconf = StringUtility::getUniqueId('foo');
1366
        file_put_contents($extLocalconfLocation, "<?php\n\n" . $uniqueStringInLocalconf . "\n\n?>");
1367
        ExtensionManagementUtility::setPackageManager($packageManager);
1368
        $mockCache = $this->getMockBuilder(PhpFrontend::class)
1369
            ->onlyMethods(['getIdentifier', 'set', 'get', 'has', 'remove', 'flush', 'flushByTag', 'require'])
1370
            ->disableOriginalConstructor()
1371
            ->getMock();
1372
1373
        $mockCache->expects(self::once())->method('set')->with(self::anything(), self::stringContains($uniqueStringInLocalconf), self::anything());
1374
        ExtensionManagementUtilityAccessibleProxy::createExtLocalconfCacheEntry($mockCache);
1375
    }
1376
1377
    /**
1378
     * @test
1379
     */
1380
    public function createExtLocalconfCacheEntryWritesCacheEntryWithExtensionContentOnlyIfExtLocalconfExists(): void
1381
    {
1382
        $extensionName = StringUtility::getUniqueId('foo');
1383
        $packageManager = $this->createMockPackageManagerWithMockPackage($extensionName);
1384
        $mockCache = $this->getMockBuilder(PhpFrontend::class)->disableOriginalConstructor()->getMock();
1385
        $packageManager->setPackageCache(new PackageStatesPackageCache('vfs://Test/Configuration/PackageStates.php', $mockCache));
1386
        ExtensionManagementUtility::setPackageManager($packageManager);
1387
        $mockCache = $this->getMockBuilder(PhpFrontend::class)
1388
            ->onlyMethods(['getIdentifier', 'set', 'get', 'has', 'remove', 'flush', 'flushByTag', 'require'])
1389
            ->disableOriginalConstructor()
1390
            ->getMock();
1391
1392
        $mockCache->expects(self::once())
1393
            ->method('set')
1394
            ->with(self::anything(), self::logicalNot(self::stringContains($extensionName)), self::anything());
1395
        ExtensionManagementUtilityAccessibleProxy::createExtLocalconfCacheEntry($mockCache);
1396
    }
1397
1398
    /**
1399
     * @test
1400
     */
1401
    public function createExtLocalconfCacheEntryWritesCacheEntryWithNoTags(): void
1402
    {
1403
        $mockCache = $this->getMockBuilder(PhpFrontend::class)
1404
            ->onlyMethods(['getIdentifier', 'set', 'get', 'has', 'remove', 'flush', 'flushByTag', 'require'])
1405
            ->disableOriginalConstructor()
1406
            ->getMock();
1407
        $mockCache->expects(self::once())->method('set')->with(self::anything(), self::anything(), self::equalTo([]));
1408
        $packageManager = $this->createMockPackageManagerWithMockPackage(StringUtility::getUniqueId());
1409
        $packageManager->setPackageCache(new PackageStatesPackageCache('vfs://Test/Configuration/PackageStates.php', $mockCache));
1410
        ExtensionManagementUtility::setPackageManager($packageManager);
1411
        ExtensionManagementUtilityAccessibleProxy::createExtLocalconfCacheEntry($mockCache);
1412
    }
1413
1414
    /////////////////////////////////////////
1415
    // Tests concerning getExtLocalconfCacheIdentifier
1416
    /////////////////////////////////////////
1417
    /**
1418
     * @test
1419
     */
1420
    public function getExtLocalconfCacheIdentifierCreatesSha1WithFourtyCharactersAndPrefix(): void
1421
    {
1422
        $prefix = 'ext_localconf_';
1423
        $identifier = ExtensionManagementUtilityAccessibleProxy::getExtLocalconfCacheIdentifier();
1424
        self::assertStringStartsWith($prefix, $identifier);
1425
        $sha1 = str_replace($prefix, '', $identifier);
1426
        self::assertEquals(40, strlen($sha1));
1427
    }
1428
1429
    /////////////////////////////////////////
1430
    // Tests concerning loadBaseTca
1431
    /////////////////////////////////////////
1432
1433
    /**
1434
     * @test
1435
     */
1436
    public function loadBaseTcaDoesNotReadFromCacheIfCachingIsDenied(): void
1437
    {
1438
        /** @var CacheManager|\PHPUnit\Framework\MockObject\MockObject $mockCacheManager */
1439
        $mockCacheManager = $this->getMockBuilder(CacheManager::class)
1440
            ->onlyMethods(['getCache'])
1441
            ->getMock();
1442
        $mockCacheManager->expects(self::never())->method('getCache');
1443
        ExtensionManagementUtilityAccessibleProxy::setCacheManager($mockCacheManager);
1444
        ExtensionManagementUtilityAccessibleProxy::loadBaseTca(false);
1445
    }
1446
1447
    /**
1448
     * @test
1449
     */
1450
    public function loadBaseTcaRequiresCacheFileIfExistsAndCachingIsAllowed(): void
1451
    {
1452
        $mockCache = $this->getMockBuilder(PhpFrontend::class)
1453
            ->onlyMethods(['getIdentifier', 'set', 'get', 'has', 'remove', 'flush', 'flushByTag', 'require'])
1454
            ->disableOriginalConstructor()
1455
            ->getMock();
1456
1457
        $mockCache->expects(self::once())->method('require')->willReturn(['tca' => []]);
1458
        ExtensionManagementUtilityAccessibleProxy::loadBaseTca(true, $mockCache);
1459
    }
1460
1461
    /**
1462
     * @test
1463
     */
1464
    public function loadBaseTcaCreatesCacheFileWithContentOfAnExtensionsConfigurationTcaPhpFile(): void
1465
    {
1466
        $extensionName = StringUtility::getUniqueId('test_baseTca_');
1467
        $packageManager = $this->createMockPackageManagerWithMockPackage($extensionName);
1468
        $mockCache = $this->getMockBuilder(PhpFrontend::class)->disableOriginalConstructor()->getMock();
1469
        $packageManager->setPackageCache(new PackageStatesPackageCache('vfs://Test/Configuration/PackageStates.php', $mockCache));
1470
        $packagePath = $packageManager->getPackage($extensionName)->getPackagePath();
1471
        GeneralUtility::mkdir($packagePath);
1472
        GeneralUtility::mkdir($packagePath . 'Configuration/');
1473
        GeneralUtility::mkdir($packagePath . 'Configuration/TCA/');
1474
        ExtensionManagementUtility::setPackageManager($packageManager);
1475
        $uniqueTableName = StringUtility::getUniqueId('table_name_');
1476
        $uniqueStringInTableConfiguration = StringUtility::getUniqueId('table_configuration_');
1477
        $tableConfiguration = '<?php return array(\'foo\' => \'' . $uniqueStringInTableConfiguration . '\'); ?>';
1478
        file_put_contents($packagePath . 'Configuration/TCA/' . $uniqueTableName . '.php', $tableConfiguration);
1479
        $mockCache = $this->getMockBuilder(PhpFrontend::class)
1480
            ->onlyMethods(['getIdentifier', 'set', 'get', 'has', 'remove', 'flush', 'flushByTag', 'require'])
1481
            ->disableOriginalConstructor()
1482
            ->getMock();
1483
1484
        /** @var CacheManager|\PHPUnit\Framework\MockObject\MockObject $mockCacheManager */
1485
        $mockCacheManager = $this->getMockBuilder(CacheManager::class)
1486
            ->onlyMethods(['getCache'])
1487
            ->getMock();
1488
        $mockCacheManager->method('getCache')->willReturn($mockCache);
1489
        ExtensionManagementUtilityAccessibleProxy::setCacheManager($mockCacheManager);
1490
        $mockCache->expects(self::once())->method('require')->willReturn(false);
1491
        $mockCache->expects(self::once())->method('set')->with(self::anything(), self::stringContains($uniqueStringInTableConfiguration), self::anything());
1492
1493
        $eventDispatcher = $this->prophesize(EventDispatcherInterface::class);
1494
        $eventDispatcher->dispatch(Argument::any())->shouldBeCalled()->willReturnArgument(0);
1495
        ExtensionManagementUtility::setEventDispatcher($eventDispatcher->reveal());
1496
1497
        ExtensionManagementUtility::loadBaseTca(true);
1498
    }
1499
1500
    /**
1501
     * @test
1502
     */
1503
    public function loadBaseTcaWritesCacheEntryWithNoTags(): void
1504
    {
1505
        $mockCache = $this->getMockBuilder(PhpFrontend::class)
1506
            ->onlyMethods(['getIdentifier', 'set', 'get', 'has', 'remove', 'flush', 'flushByTag', 'require'])
1507
            ->disableOriginalConstructor()
1508
            ->getMock();
1509
1510
        /** @var CacheManager|\PHPUnit\Framework\MockObject\MockObject $mockCacheManager */
1511
        $mockCacheManager = $this->getMockBuilder(CacheManager::class)
1512
            ->onlyMethods(['getCache'])
1513
            ->getMock();
1514
        $mockCacheManager->method('getCache')->willReturn($mockCache);
1515
        ExtensionManagementUtilityAccessibleProxy::setCacheManager($mockCacheManager);
1516
        $mockCache->expects(self::once())->method('require')->willReturn(false);
1517
        $mockCache->expects(self::once())->method('set')->with(self::anything(), self::anything(), self::equalTo([]));
1518
        ExtensionManagementUtilityAccessibleProxy::loadBaseTca();
1519
    }
1520
1521
    /////////////////////////////////////////
1522
    // Tests concerning getBaseTcaCacheIdentifier
1523
    /////////////////////////////////////////
1524
1525
    /**
1526
     * @test
1527
     */
1528
    public function getBaseTcaCacheIdentifierCreatesSha1WithFourtyCharactersAndPrefix(): void
1529
    {
1530
        $prefix = 'tca_base_';
1531
        $identifier = ExtensionManagementUtilityAccessibleProxy::getBaseTcaCacheIdentifier();
1532
        self::assertStringStartsWith($prefix, $identifier);
1533
        $sha1 = str_replace($prefix, '', $identifier);
1534
        self::assertEquals(40, strlen($sha1));
1535
    }
1536
1537
    /////////////////////////////////////////
1538
    // Tests concerning loadExtTables
1539
    /////////////////////////////////////////
1540
    /**
1541
     * @test
1542
     */
1543
    public function loadExtTablesDoesNotReadFromCacheIfCachingIsDenied(): void
1544
    {
1545
        /** @var CacheManager|\PHPUnit\Framework\MockObject\MockObject $mockCacheManager */
1546
        $mockCacheManager = $this->getMockBuilder(CacheManager::class)
1547
            ->onlyMethods(['getCache'])
1548
            ->getMock();
1549
        $mockCacheManager->expects(self::never())->method('getCache');
1550
        ExtensionManagementUtilityAccessibleProxy::setCacheManager($mockCacheManager);
1551
        $packageManager = $this->createMockPackageManagerWithMockPackage(StringUtility::getUniqueId());
1552
        ExtensionManagementUtility::setPackageManager($packageManager);
1553
        ExtensionManagementUtility::loadExtLocalconf(false);
1554
    }
1555
1556
    /**
1557
     * @test
1558
     */
1559
    public function loadExtTablesRequiresCacheFileIfExistsAndCachingIsAllowed(): void
1560
    {
1561
        $mockCache = $this->getMockBuilder(PhpFrontend::class)
1562
            ->onlyMethods(['getIdentifier', 'set', 'get', 'has', 'remove', 'flush', 'flushByTag', 'require'])
1563
            ->disableOriginalConstructor()
1564
            ->getMock();
1565
1566
        /** @var CacheManager|\PHPUnit\Framework\MockObject\MockObject $mockCacheManager */
1567
        $mockCacheManager = $this->getMockBuilder(CacheManager::class)
1568
            ->onlyMethods(['getCache'])
1569
            ->getMock();
1570
        $mockCacheManager->method('getCache')->willReturn($mockCache);
1571
        ExtensionManagementUtilityAccessibleProxy::setCacheManager($mockCacheManager);
1572
        $mockCache->method('has')->willReturn(true);
1573
        $mockCache->expects(self::once())->method('require');
1574
        // Reset the internal cache access tracking variable of extMgm
1575
        // This method is only in the ProxyClass!
1576
        ExtensionManagementUtilityAccessibleProxy::resetExtTablesWasReadFromCacheOnceBoolean();
1577
        ExtensionManagementUtility::loadExtTables(true);
1578
    }
1579
1580
    /////////////////////////////////////////
1581
    // Tests concerning createExtTablesCacheEntry
1582
    /////////////////////////////////////////
1583
    /**
1584
     * @test
1585
     */
1586
    public function createExtTablesCacheEntryWritesCacheEntryWithContentOfLoadedExtensionExtTables(): void
1587
    {
1588
        $extensionName = StringUtility::getUniqueId('foo');
1589
        $packageManager = $this->createMockPackageManagerWithMockPackage($extensionName);
1590
        $extensionPath = $packageManager->getPackage($extensionName)->getPackagePath();
1591
        $extTablesLocation = $extensionPath . 'ext_tables.php';
1592
        $uniqueStringInTables = StringUtility::getUniqueId('foo');
1593
        file_put_contents($extTablesLocation, "<?php\n\n$uniqueStringInTables\n\n?>");
1594
        ExtensionManagementUtility::setPackageManager($packageManager);
1595
        $mockCache = $this->getMockBuilder(PhpFrontend::class)
1596
            ->onlyMethods(['getIdentifier', 'set', 'get', 'has', 'remove', 'flush', 'flushByTag', 'require'])
1597
            ->disableOriginalConstructor()
1598
            ->getMock();
1599
        $packageManager->setPackageCache(new PackageStatesPackageCache('vfs://Test/Configuration/PackageStates.php', $mockCache));
1600
1601
        $mockCache->expects(self::once())->method('set')->with(self::anything(), self::stringContains($uniqueStringInTables), self::anything());
1602
        ExtensionManagementUtilityAccessibleProxy::createExtTablesCacheEntry($mockCache);
1603
    }
1604
1605
    /**
1606
     * @test
1607
     */
1608
    public function createExtTablesCacheEntryWritesCacheEntryWithExtensionContentOnlyIfExtTablesExists(): void
1609
    {
1610
        $extensionName = StringUtility::getUniqueId('foo');
1611
        $packageManager = $this->createMockPackageManagerWithMockPackage($extensionName);
1612
        ExtensionManagementUtility::setPackageManager($packageManager);
1613
        $mockCache = $this->getMockBuilder(PhpFrontend::class)
1614
            ->onlyMethods(['getIdentifier', 'set', 'get', 'has', 'remove', 'flush', 'flushByTag', 'require'])
1615
            ->disableOriginalConstructor()
1616
            ->getMock();
1617
        $packageManager->setPackageCache(new PackageStatesPackageCache('vfs://Test/Configuration/PackageStates.php', $mockCache));
1618
1619
        $mockCache->expects(self::once())
1620
            ->method('set')
1621
            ->with(self::anything(), self::logicalNot(self::stringContains($extensionName)), self::anything());
1622
        ExtensionManagementUtilityAccessibleProxy::createExtTablesCacheEntry($mockCache);
1623
    }
1624
1625
    /**
1626
     * @test
1627
     */
1628
    public function createExtTablesCacheEntryWritesCacheEntryWithNoTags(): void
1629
    {
1630
        $mockCache = $this->getMockBuilder(PhpFrontend::class)
1631
            ->onlyMethods(['getIdentifier', 'set', 'get', 'has', 'remove', 'flush', 'flushByTag', 'require'])
1632
            ->disableOriginalConstructor()
1633
            ->getMock();
1634
1635
        $mockCache->expects(self::once())->method('set')->with(self::anything(), self::anything(), self::equalTo([]));
1636
        $packageManager = $this->createMockPackageManagerWithMockPackage(StringUtility::getUniqueId());
1637
        $packageManager->setPackageCache(new PackageStatesPackageCache('vfs://Test/Configuration/PackageStates.php', $mockCache));
1638
        ExtensionManagementUtility::setPackageManager($packageManager);
1639
        ExtensionManagementUtilityAccessibleProxy::createExtTablesCacheEntry($mockCache);
1640
    }
1641
1642
    /////////////////////////////////////////
1643
    // Tests concerning getExtTablesCacheIdentifier
1644
    /////////////////////////////////////////
1645
    /**
1646
     * @test
1647
     */
1648
    public function getExtTablesCacheIdentifierCreatesSha1WithFourtyCharactersAndPrefix(): void
1649
    {
1650
        $prefix = 'ext_tables_';
1651
        $identifier = ExtensionManagementUtilityAccessibleProxy::getExtTablesCacheIdentifier();
1652
        self::assertStringStartsWith($prefix, $identifier);
1653
        $sha1 = str_replace($prefix, '', $identifier);
1654
        self::assertEquals(40, strlen($sha1));
1655
    }
1656
1657
    /////////////////////////////////////////
1658
    // Tests concerning getExtensionVersion
1659
    /////////////////////////////////////////
1660
    /**
1661
     * Data provider for negative getExtensionVersion() tests.
1662
     *
1663
     * @return array
1664
     */
1665
    public function getExtensionVersionFaultyDataProvider(): array
1666
    {
1667
        return [
1668
            [''],
1669
            [0],
1670
            [new \stdClass()],
1671
            [true],
1672
        ];
1673
    }
1674
1675
    /**
1676
     * @test
1677
     * @dataProvider getExtensionVersionFaultyDataProvider
1678
     * @param $key
1679
     * @throws \TYPO3\CMS\Core\Package\Exception
1680
     */
1681
    public function getExtensionVersionForFaultyExtensionKeyThrowsException($key): void
1682
    {
1683
        $this->expectException(\InvalidArgumentException::class);
1684
        $this->expectExceptionCode(1294586096);
1685
1686
        ExtensionManagementUtility::getExtensionVersion($key);
1687
    }
1688
1689
    /**
1690
     * @test
1691
     */
1692
    public function getExtensionVersionForNotLoadedExtensionReturnsEmptyString(): void
1693
    {
1694
        $uniqueSuffix = StringUtility::getUniqueId('test');
1695
        $extensionKey = 'unloadedextension' . $uniqueSuffix;
1696
        self::assertEquals('', ExtensionManagementUtility::getExtensionVersion($extensionKey));
1697
    }
1698
1699
    /**
1700
     * @test
1701
     */
1702
    public function getExtensionVersionForLoadedExtensionReturnsExtensionVersion(): void
1703
    {
1704
        $uniqueSuffix = StringUtility::getUniqueId('test');
1705
        $extensionKey = 'unloadedextension' . $uniqueSuffix;
1706
        $packageMetaData = $this->getMockBuilder(MetaData::class)
1707
            ->onlyMethods(['getVersion'])
1708
            ->setConstructorArgs([$extensionKey])
1709
            ->getMock();
1710
        $packageMetaData->method('getVersion')->willReturn('1.2.3');
1711
        $packageManager = $this->createMockPackageManagerWithMockPackage($extensionKey, ['getPackagePath', 'getPackageKey', 'getPackageMetaData']);
1712
        /** @var \PHPUnit\Framework\MockObject\MockObject $package */
1713
        $package = $packageManager->getPackage($extensionKey);
1714
        $package
1715
                ->method('getPackageMetaData')
1716
                ->willReturn($packageMetaData);
1717
        ExtensionManagementUtility::setPackageManager($packageManager);
1718
        self::assertEquals('1.2.3', ExtensionManagementUtility::getExtensionVersion($extensionKey));
1719
    }
1720
1721
    /////////////////////////////////////////
1722
    // Tests concerning loadExtension
1723
    /////////////////////////////////////////
1724
    /**
1725
     * @test
1726
     */
1727
    public function loadExtensionThrowsExceptionIfExtensionIsLoaded(): void
1728
    {
1729
        $this->expectException(\RuntimeException::class);
1730
        $this->expectExceptionCode(1342345486);
1731
1732
        $extensionKey = StringUtility::getUniqueId('test');
1733
        $packageManager = $this->createMockPackageManagerWithMockPackage($extensionKey);
1734
        ExtensionManagementUtility::setPackageManager($packageManager);
1735
        ExtensionManagementUtility::loadExtension($extensionKey);
1736
    }
1737
1738
    /////////////////////////////////////////
1739
    // Tests concerning unloadExtension
1740
    /////////////////////////////////////////
1741
    /**
1742
     * @test
1743
     */
1744
    public function unloadExtensionThrowsExceptionIfExtensionIsNotLoaded(): void
1745
    {
1746
        $this->expectException(\RuntimeException::class);
1747
        $this->expectExceptionCode(1342345487);
1748
1749
        $packageName = StringUtility::getUniqueId('foo');
1750
        /** @var PackageManager|\PHPUnit\Framework\MockObject\MockObject $packageManager */
1751
        $packageManager = $this->getMockBuilder(PackageManager::class)
1752
            ->onlyMethods(['isPackageActive'])
1753
            ->disableOriginalConstructor()
1754
            ->getMock();
1755
        $packageManager->expects(self::once())
1756
            ->method('isPackageActive')
1757
            ->with(self::equalTo($packageName))
1758
            ->willReturn(false);
1759
        ExtensionManagementUtility::setPackageManager($packageManager);
1760
        ExtensionManagementUtility::unloadExtension($packageName);
1761
    }
1762
1763
    /**
1764
     * @test
1765
     */
1766
    public function unloadExtensionCallsPackageManagerToDeactivatePackage(): void
1767
    {
1768
        $packageName = StringUtility::getUniqueId('foo');
1769
        /** @var PackageManager|\PHPUnit\Framework\MockObject\MockObject $packageManager */
1770
        $packageManager = $this->getMockBuilder(PackageManager::class)
1771
            ->onlyMethods(['isPackageActive', 'deactivatePackage'])
1772
            ->disableOriginalConstructor()
1773
            ->getMock();
1774
        $packageManager
1775
            ->method('isPackageActive')
1776
            ->willReturn(true);
1777
        $packageManager->expects(self::once())
1778
            ->method('deactivatePackage')
1779
            ->with($packageName);
1780
        ExtensionManagementUtility::setPackageManager($packageManager);
1781
        ExtensionManagementUtility::unloadExtension($packageName);
1782
    }
1783
1784
    ///////////////////////////////
1785
    // Tests concerning addPlugin
1786
    ///////////////////////////////
1787
1788
    /**
1789
     * @test
1790
     */
1791
    public function addPluginSetsTcaCorrectlyForGivenExtKeyAsParameter(): void
1792
    {
1793
        $extKey = 'indexed_search';
1794
        $expectedTCA = [
1795
            [
1796
                'label',
1797
                $extKey,
1798
                'EXT:' . $extKey . '/Resources/Public/Icons/Extension.png',
1799
                'default',
1800
            ],
1801
        ];
1802
        $GLOBALS['TCA']['tt_content']['columns']['list_type']['config']['items'] = [];
1803
        ExtensionManagementUtility::addPlugin(['label', $extKey], 'list_type', $extKey);
1804
        self::assertEquals($expectedTCA, $GLOBALS['TCA']['tt_content']['columns']['list_type']['config']['items']);
1805
    }
1806
1807
    /**
1808
     * @test
1809
     */
1810
    public function addPluginThrowsExceptionForMissingExtkey(): void
1811
    {
1812
        $this->expectException(\InvalidArgumentException::class);
1813
        $this->expectExceptionCode(1404068038);
1814
1815
        ExtensionManagementUtility::addPlugin('test');
0 ignored issues
show
Bug introduced by
'test' of type string is incompatible with the type array expected by parameter $itemArray of TYPO3\CMS\Core\Utility\E...entUtility::addPlugin(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

1815
        ExtensionManagementUtility::addPlugin(/** @scrutinizer ignore-type */ 'test');
Loading history...
1816
    }
1817
1818
    public function addTcaSelectItemGroupAddsGroupDataProvider(): array
1819
    {
1820
        return [
1821
            'add the first group' => [
1822
                'my_group',
1823
                'my_group_label',
1824
                null,
1825
                null,
1826
                [
1827
                    'my_group' => 'my_group_label',
1828
                ],
1829
            ],
1830
            'add a new group at the bottom' => [
1831
                'my_group',
1832
                'my_group_label',
1833
                'bottom',
1834
                [
1835
                    'default' => 'default_label',
1836
                ],
1837
                [
1838
                    'default' => 'default_label',
1839
                    'my_group' => 'my_group_label',
1840
                ],
1841
            ],
1842
            'add a new group at the top' => [
1843
                'my_group',
1844
                'my_group_label',
1845
                'top',
1846
                [
1847
                    'default' => 'default_label',
1848
                ],
1849
                [
1850
                    'my_group' => 'my_group_label',
1851
                    'default' => 'default_label',
1852
                ],
1853
            ],
1854
            'add a new group after an existing group' => [
1855
                'my_group',
1856
                'my_group_label',
1857
                'after:default',
1858
                [
1859
                    'default' => 'default_label',
1860
                    'special' => 'special_label',
1861
                ],
1862
                [
1863
                    'default' => 'default_label',
1864
                    'my_group' => 'my_group_label',
1865
                    'special' => 'special_label',
1866
                ],
1867
            ],
1868
            'add a new group before an existing group' => [
1869
                'my_group',
1870
                'my_group_label',
1871
                'before:default',
1872
                [
1873
                    'default' => 'default_label',
1874
                    'special' => 'special_label',
1875
                ],
1876
                [
1877
                    'my_group' => 'my_group_label',
1878
                    'default' => 'default_label',
1879
                    'special' => 'special_label',
1880
                ],
1881
            ],
1882
            'add a new group after a non-existing group moved to bottom' => [
1883
                'my_group',
1884
                'my_group_label',
1885
                'after:default2',
1886
                [
1887
                    'default' => 'default_label',
1888
                    'special' => 'special_label',
1889
                ],
1890
                [
1891
                    'default' => 'default_label',
1892
                    'special' => 'special_label',
1893
                    'my_group' => 'my_group_label',
1894
                ],
1895
            ],
1896
            'add a new group which already exists does nothing' => [
1897
                'my_group',
1898
                'my_group_label',
1899
                'does-not-matter',
1900
                [
1901
                    'default' => 'default_label',
1902
                    'my_group' => 'existing_label',
1903
                    'special' => 'special_label',
1904
                ],
1905
                [
1906
                    'default' => 'default_label',
1907
                    'my_group' => 'existing_label',
1908
                    'special' => 'special_label',
1909
                ],
1910
            ],
1911
        ];
1912
    }
1913
1914
    /**
1915
     * @test
1916
     * @param string $groupId
1917
     * @param string $groupLabel
1918
     * @param string $position
1919
     * @param array|null $existingGroups
1920
     * @param array $expectedGroups
1921
     * @dataProvider addTcaSelectItemGroupAddsGroupDataProvider
1922
     */
1923
    public function addTcaSelectItemGroupAddsGroup(string $groupId, string $groupLabel, ?string $position, ?array $existingGroups, array $expectedGroups): void
1924
    {
1925
        $GLOBALS['TCA']['tt_content']['columns']['CType']['config'] = [];
1926
        if (is_array($existingGroups)) {
0 ignored issues
show
introduced by
The condition is_array($existingGroups) is always true.
Loading history...
1927
            $GLOBALS['TCA']['tt_content']['columns']['CType']['config']['itemGroups'] = $existingGroups;
1928
        }
1929
        ExtensionManagementUtility::addTcaSelectItemGroup('tt_content', 'CType', $groupId, $groupLabel, $position);
1930
        self::assertEquals($expectedGroups, $GLOBALS['TCA']['tt_content']['columns']['CType']['config']['itemGroups']);
1931
    }
1932
}
1933