2 declare(strict_types = 1);
15 use org\bovigo\vfs\vfsStream;
23 use TYPO3\CMS\Core\Package\PackageManager;
25 use TYPO3\TestingFramework\Core\Unit\UnitTestCase;
40 protected function setUp()
42 vfsStream::setup(
'Test');
45 $mockCache = $this->getMockBuilder(PhpFrontend::class)
46 ->setMethods([
'has',
'set',
'getBackend'])
47 ->disableOriginalConstructor()
49 $mockCacheBackend = $this->getMockBuilder(SimpleFileBackend::class)
50 ->setMethods([
'has',
'set',
'getBackend',
'getCacheDirectory'])
51 ->disableOriginalConstructor()
53 $mockCache->expects($this->any())->method(
'has')->will($this->returnValue(
false));
54 $mockCache->expects($this->any())->method(
'set')->will($this->returnValue(
true));
55 $mockCache->expects($this->any())->method(
'getBackend')->will($this->returnValue($mockCacheBackend));
56 $mockCacheBackend->expects($this->any())->method(
'getCacheDirectory')->will($this->returnValue(
'vfs://Test/Cache'));
57 $this->packageManager = $this->getAccessibleMock(
58 PackageManager::class,
59 [
'sortAndSavePackageStates',
'sortActivePackagesByDependencies',
'registerTransientClassLoadingInformationForPackage'],
63 mkdir(
'vfs://Test/Packages/Application', 0700,
true);
64 mkdir(
'vfs://Test/Configuration');
65 file_put_contents(
'vfs://Test/Configuration/PackageStates.php',
"<?php return array ('packages' => array(), 'version' => 5); ");
67 $composerNameToPackageKeyMap = [
68 'typo3/flow' =>
'TYPO3.Flow'
71 $this->packageManager->injectCoreCache($mockCache);
72 $this->inject($this->packageManager,
'composerNameToPackageKeyMap', $composerNameToPackageKeyMap);
73 $this->packageManager->_set(
'packagesBasePath',
'vfs://Test/Packages/');
74 $this->packageManager->_set(
'packageStatesPathAndFilename',
'vfs://Test/Configuration/PackageStates.php');
84 $packagePath =
'vfs://Test/Packages/Application/' . $packageKey .
'/';
85 mkdir($packagePath, 0770,
true);
86 file_put_contents($packagePath .
'ext_emconf.php',
'<?php' . LF .
'$EM_CONF[$_EXTKEY] = [];');
87 file_put_contents($packagePath .
'composer.json',
'{}');
88 $package =
new Package($this->packageManager, $packageKey, $packagePath);
89 $this->packageManager->registerPackage($package);
90 $this->packageManager->activatePackage($packageKey);
103 $package = $this->packageManager->getPackage(
'TYPO3.MyPackage');
105 $this->assertInstanceOf(Package::class, $package,
'The result of getPackage() was no valid package object.');
114 $this->expectException(UnknownPackageException::class);
115 $this->expectExceptionCode(1166546734);
117 $this->packageManager->getPackage(
'PrettyUnlikelyThatThisPackageExists');
125 $expectedPackageKeys = [
126 $this->getUniqueId(
'TYPO3.CMS'),
127 $this->getUniqueId(
'TYPO3.CMS.Test'),
128 $this->getUniqueId(
'TYPO3.YetAnotherTestPackage'),
129 $this->getUniqueId(
'Lolli.Pop.NothingElse')
132 foreach ($expectedPackageKeys as $packageKey) {
133 $packagePath =
'vfs://Test/Packages/Application/' . $packageKey .
'/';
135 mkdir($packagePath, 0770,
true);
136 file_put_contents($packagePath .
'composer.json',
'{"name": "' . $packageKey .
'", "type": "typo3-test"}');
141 $packageManager->_set(
'packageStatesPathAndFilename',
'vfs://Test/Configuration/PackageStates.php');
146 $packageStates = require
'vfs://Test/Configuration/PackageStates.php';
147 $actualPackageKeys = array_keys($packageStates[
'packages']);
148 $this->assertEquals(sort($expectedPackageKeys), sort($actualPackageKeys));
156 $expectedPackageKeys = [
157 $this->getUniqueId(
'TYPO3.CMS'),
158 $this->getUniqueId(
'TYPO3.CMS.Test'),
159 $this->getUniqueId(
'TYPO3.YetAnotherTestPackage'),
160 $this->getUniqueId(
'Lolli.Pop.NothingElse')
164 foreach ($expectedPackageKeys as $packageKey) {
165 $packagePath =
'vfs://Test/Packages/Application/' . $packageKey .
'/';
166 $packagePaths[] = $packagePath;
168 mkdir($packagePath, 0770,
true);
169 file_put_contents($packagePath .
'composer.json',
'{"name": "' . $packageKey .
'", "type": "typo3-cms-test"}');
170 file_put_contents($packagePath .
'ext_emconf.php',
'<?php' . LF .
'$EM_CONF[$_EXTKEY] = [];');
177 $packageManager->_set(
'packageStatesPathAndFilename',
'vfs://Test/Configuration/PackageStates.php');
179 $packageKey = $expectedPackageKeys[0];
183 'packagePath' =>
'Application/' . $packageKey .
'/'
191 $packageStates = require
'vfs://Test/Configuration/PackageStates.php';
192 $this->assertEquals(
'Application/' . $packageKey .
'/', $packageStates[
'packages'][$packageKey][
'packagePath']);
201 $this->getUniqueId(
'Lolli.Pop.NothingElse'),
202 $this->getUniqueId(
'TYPO3.Package'),
203 $this->getUniqueId(
'TYPO3.YetAnotherTestPackage')
207 foreach ($packageKeys as $packageKey) {
208 $packagePath =
'vfs://Test/Packages/Application/' . $packageKey .
'/';
210 mkdir($packagePath, 0770,
true);
211 file_put_contents($packagePath .
'composer.json',
'{"name": "' . $packageKey .
'", "type": "typo3-cms-test"}');
212 file_put_contents($packagePath .
'ext_emconf.php',
'<?php' . LF .
'$EM_CONF[$_EXTKEY] = [];');
213 $packagePaths[] = $packagePath;
220 $packageManager->_set(
'packageStatesPathAndFilename',
'vfs://Test/Configuration/PackageStates.php');
225 $expectedPackageStatesConfiguration = [];
226 foreach ($packageKeys as $packageKey) {
227 $expectedPackageStatesConfiguration[$packageKey] = [
228 'packagePath' =>
'Application/' . $packageKey .
'/'
233 $actualPackageStatesConfiguration =
$packageManager->_get(
'packageStatesConfiguration');
234 $this->assertEquals($expectedPackageStatesConfiguration, $actualPackageStatesConfiguration[
'packages']);
245 [
'TYPO3.YetAnotherTestPackage',
'vfs://Test/Packages/Application/TYPO3.YetAnotherTestPackage/'],
246 [
'Lolli.Pop.NothingElse',
'vfs://Test/Packages/Application/Lolli.Pop.NothingElse/']
258 $actualPackagePath = $actualPackage->getPackagePath();
260 $this->assertEquals($expectedPackagePath, $actualPackagePath);
261 $this->assertTrue(is_dir($actualPackagePath),
'Package path should exist after createPackage()');
262 $this->assertEquals($packageKey, $actualPackage->getPackageKey());
263 $this->assertTrue($this->packageManager->isPackageAvailable($packageKey));
275 $packageKey =
'Acme.YetAnotherTestPackage';
279 $this->packageManager->expects($this->any())->method(
'sortActivePackagesByDependencies')->will($this->returnValue([]));
281 $this->packageManager->deactivatePackage($packageKey);
282 $this->assertFalse($this->packageManager->isPackageActive($packageKey));
284 $this->packageManager->activatePackage($packageKey);
285 $this->assertTrue($this->packageManager->isPackageActive($packageKey));
297 $this->expectException(ProtectedPackageKeyException::class);
298 $this->expectExceptionCode(1308662891);
301 $package->setProtected(
true);
302 $this->packageManager->expects($this->any())->method(
'sortActivePackagesByDependencies')->will($this->returnValue([]));
303 $this->packageManager->deactivatePackage(
'Acme.YetAnotherTestPackage');
314 $this->expectException(UnknownPackageException::class);
315 $this->expectExceptionCode(1166543253);
317 $this->packageManager->expects($this->any())->method(
'sortActivePackagesByDependencies')->will($this->returnValue([]));
318 $this->packageManager->deletePackage(
'PrettyUnlikelyThatThisPackageExists');
330 $this->expectException(ProtectedPackageKeyException::class);
331 $this->expectExceptionCode(1220722120);
334 $package->setProtected(
true);
335 $this->packageManager->deletePackage(
'Acme.YetAnotherTestPackage');
349 $this->packageManager->expects($this->any())->method(
'sortActivePackagesByDependencies')->will($this->returnValue([]));
351 $this->assertTrue($this->packageManager->isPackageActive(
'Acme.YetAnotherTestPackage'));
352 $this->assertTrue($this->packageManager->isPackageAvailable(
'Acme.YetAnotherTestPackage'));
354 $this->packageManager->deletePackage(
'Acme.YetAnotherTestPackage');
356 $this->assertFalse($this->packageManager->isPackageActive(
'Acme.YetAnotherTestPackage'));
357 $this->assertFalse($this->packageManager->isPackageAvailable(
'Acme.YetAnotherTestPackage'));
366 [
'imagine/Imagine',
'imagine.Imagine'],
367 [
'imagine/imagine',
'imagine.Imagine'],
368 [
'typo3/cms',
'TYPO3.CMS'],
369 [
'TYPO3/CMS',
'TYPO3.CMS']
381 $packageStatesConfiguration = [
387 $composerNameToPackageKeyMap = [
388 'typo3/cms' =>
'TYPO3.CMS',
389 'imagine/imagine' =>
'imagine.Imagine'
393 $packageManager->_set(
'packageStatesConfiguration', $packageStatesConfiguration);
394 $packageManager->_set(
'composerNameToPackageKeyMap', $composerNameToPackageKeyMap);
396 $this->assertEquals($packageKey,
$packageManager->_call(
'getPackageKeyFromComposerName', $composerName));
405 'TYPO3 Flow Packages' => [
408 'dependencies' => [
'Symfony.Component.Yaml',
'Doctrine.Common',
'Doctrine.DBAL',
'Doctrine.ORM']
411 'dependencies' => [
'Doctrine.Common',
'Doctrine.DBAL']
413 'Doctrine.Common' => [
417 'dependencies' => [
'Doctrine.Common']
419 'Symfony.Component.Yaml' => [
428 'TYPO3.Flow' =>
false,
429 'Doctrine.ORM' =>
true,
430 'Doctrine.Common' =>
true,
431 'Doctrine.DBAL' =>
true,
432 'Symfony.Component.Yaml' =>
true,
435 'TYPO3.Flow' =>
false,
436 'Doctrine.ORM' =>
false,
437 'Doctrine.Common' =>
true,
438 'Doctrine.DBAL' =>
true,
439 'Symfony.Component.Yaml' =>
false,
441 'Doctrine.Common' => [
442 'TYPO3.Flow' =>
false,
443 'Doctrine.ORM' =>
false,
444 'Doctrine.Common' =>
false,
445 'Doctrine.DBAL' =>
false,
446 'Symfony.Component.Yaml' =>
false,
449 'TYPO3.Flow' =>
false,
450 'Doctrine.ORM' =>
false,
451 'Doctrine.Common' =>
true,
452 'Doctrine.DBAL' =>
false,
453 'Symfony.Component.Yaml' =>
false,
455 'Symfony.Component.Yaml' => [
456 'TYPO3.Flow' =>
false,
457 'Doctrine.ORM' =>
false,
458 'Doctrine.Common' =>
true,
459 'Doctrine.DBAL' =>
false,
460 'Symfony.Component.Yaml' =>
false,
464 'TYPO3 CMS Extensions' => [
467 'dependencies' => [],
470 'dependencies' => [
'core'],
473 'dependencies' => [
'core',
'setup']
476 'dependencies' => [
'extbase'],
479 'dependencies' => [
'core'],
482 'dependencies' => [
'extbase'],
485 'dependencies' => [],
501 'pt_extbase' =>
false,
510 'pt_extbase' =>
false,
519 'pt_extbase' =>
false,
528 'pt_extbase' =>
false,
537 'pt_extbase' =>
false,
546 'pt_extbase' =>
false,
555 'pt_extbase' =>
false,
560 'Dummy Packages' => [
563 'dependencies' => [
'B',
'D',
'C'],
569 'dependencies' => [
'E']
572 'dependencies' => [
'E'],
575 'dependencies' => [],
578 'dependencies' => [],
650 $packageManager->expects($this->any())->method(
'findFrameworkPackages')->willReturn($frameworkPackageKeys);
652 $dependencyGraph =
$packageManager->_call(
'buildDependencyGraph', $unsortedPackageStatesConfiguration);
654 $this->assertEquals($expectedGraph, $dependencyGraph);
663 'TYPO3 Flow Packages' => [
666 'dependencies' => [
'Symfony.Component.Yaml',
'Doctrine.Common',
'Doctrine.DBAL',
'Doctrine.ORM']
669 'dependencies' => [
'Doctrine.Common',
'Doctrine.DBAL']
671 'Doctrine.Common' => [
675 'dependencies' => [
'Doctrine.Common']
677 'Symfony.Component.Yaml' => [
688 'Symfony.Component.Yaml',
692 'TYPO3 CMS Extensions' => [
695 'dependencies' => [],
698 'dependencies' => [
'core'],
701 'dependencies' => [
'core',
'setup']
704 'dependencies' => [
'extbase'],
707 'dependencies' => [
'core'],
710 'dependencies' => [
'extbase'],
713 'dependencies' => [],
732 'Dummy Packages' => [
735 'dependencies' => [
'B',
'D',
'C'],
741 'dependencies' => [
'E']
744 'dependencies' => [
'E'],
747 'dependencies' => [],
750 'dependencies' => [],
779 $packageManager->expects($this->any())->method(
'findFrameworkPackages')->willReturn($frameworkPackageKeys);
781 $sortedPackageKeys =
$packageManager->_call(
'sortPackageStatesConfigurationByDependency', $unsortedPackageStatesConfiguration);
783 $this->assertEquals($expectedSortedPackageKeys, $sortedPackageKeys,
'The package states configurations have not been ordered according to their dependencies!');
791 $unsortedPackageStatesConfiguration = [
793 'dependencies' => [
'B'],
796 'dependencies' => [
'A']
800 $this->expectException(\UnexpectedValueException::class);
801 $this->expectExceptionCode(1381960494);
804 $packageManager->expects($this->any())->method(
'findFrameworkPackages')->willReturn([]);
806 $packageManager->_call(
'sortPackageStatesConfigurationByDependency', $unsortedPackageStatesConfiguration);