TYPO3 CMS  TYPO3_6-2
PackageManagerTest.php
Go to the documentation of this file.
1 <?php
3 
4 /* *
5  * This script belongs to the TYPO3 Flow framework. *
6  * *
7  * It is free software; you can redistribute it and/or modify it under *
8  * the terms of the GNU Lesser General Public License, either version 3 *
9  * of the License, or (at your option) any later version. *
10  * *
11  * The TYPO3 project - inspiring people to share! *
12  * */
13 
16 
22 
26  protected $packageManager;
27 
32  protected function setUp() {
33  vfsStream::setup('Test');
34  $mockBootstrap = $this->getMock('TYPO3\CMS\Core\Core\Bootstrap', array(), array(), '', FALSE);
35  $mockCache = $this->getMock('TYPO3\CMS\Core\Cache\Frontend\PhpFrontend', array('has', 'set', 'getBackend'), array(), '', FALSE);
36  $mockCacheBackend = $this->getMock('TYPO3\CMS\Core\Cache\Backend\SimpleFileBackend', array('has', 'set', 'getBackend'), array(), '', FALSE);
37  $mockCache->expects($this->any())->method('has')->will($this->returnValue(FALSE));
38  $mockCache->expects($this->any())->method('set')->will($this->returnValue(TRUE));
39  $mockCache->expects($this->any())->method('getBackend')->will($this->returnValue($mockCacheBackend));
40  $mockCacheBackend->expects($this->any())->method('getCacheDirectory')->will($this->returnValue('vfs://Test/Cache'));
41  $this->packageManager = $this->getAccessibleMock('TYPO3\\CMS\\Core\\Package\\PackageManager', array('sortAndSavePackageStates'));
42 
43  mkdir('vfs://Test/Packages/Application', 0700, TRUE);
44  mkdir('vfs://Test/Configuration');
45  file_put_contents('vfs://Test/Configuration/PackageStates.php', "<?php return array ('packages' => array(), 'version' => 4); ");
46 
47  $mockClassLoader = $this->getMock('TYPO3\CMS\Core\Core\ClassLoader', array(), array(\TYPO3\CMS\Core\Core\Bootstrap::getInstance()->getApplicationContext()));
48  $mockClassLoader->expects($this->any())->method('setCacheIdentifier')->will($this->returnSelf());
49 
50  $composerNameToPackageKeyMap = array(
51  'typo3/flow' => 'TYPO3.Flow'
52  );
53 
54  $this->packageManager->injectClassLoader($mockClassLoader);
55  $this->packageManager->injectCoreCache($mockCache);
56  $this->inject($this->packageManager, 'composerNameToPackageKeyMap', $composerNameToPackageKeyMap);
57  $this->packageManager->_set('packagesBasePath', 'vfs://Test/Packages/');
58  $this->packageManager->_set('packageStatesPathAndFilename', 'vfs://Test/Configuration/PackageStates.php');
59  $this->packageManager->initialize($mockBootstrap);
60  }
61 
66  $this->packageManager->createPackage('TYPO3.Flow');
67 
68  $package = $this->packageManager->getPackage('TYPO3.Flow');
69  $this->assertInstanceOf('TYPO3\Flow\Package\PackageInterface', $package, 'The result of getPackage() was no valid package object.');
70  }
71 
77  $this->packageManager->getPackage('PrettyUnlikelyThatThisPackageExists');
78  }
79 
80 
85  $mockFlowMetadata = $this->getMock('TYPO3\Flow\Package\MetaDataInterface');
86  $mockFlowMetadata->expects($this->any())->method('getConstraintsByType')->will($this->returnValue(array(
87  new \TYPO3\Flow\Package\MetaData\PackageConstraint('depends', 'TYPO3.Fluid'),
88  new \TYPO3\Flow\Package\MetaData\PackageConstraint('depends', 'Doctrine.ORM')
89  )));
90  $mockFlowPackage = $this->getMock('TYPO3\Flow\Package\PackageInterface');
91  $mockFlowPackage->expects($this->any())->method('getPackageMetaData')->will($this->returnValue($mockFlowMetadata));
92 
93  $mockFluidMetadata = $this->getMock('TYPO3\Flow\Package\MetaDataInterface');
94  $mockFluidMetadata->expects($this->any())->method('getConstraintsByType')->will($this->returnValue(array(
95  new \TYPO3\Flow\Package\MetaData\PackageConstraint('depends', 'TYPO3.Flow')
96  )));
97  $mockFluidPackage = $this->getMock('TYPO3\Flow\Package\PackageInterface');
98  $mockFluidPackage->expects($this->any())->method('getPackageMetaData')->will($this->returnValue($mockFluidMetadata));
99 
100  $mockOrmMetadata = $this->getMock('TYPO3\Flow\Package\MetaDataInterface');
101  $mockOrmMetadata->expects($this->any())->method('getConstraintsByType')->will($this->returnValue(array(
102  new \TYPO3\Flow\Package\MetaData\PackageConstraint('depends', 'Doctrine.DBAL')
103  )));
104  $mockOrmPackage = $this->getMock('TYPO3\Flow\Package\PackageInterface');
105  $mockOrmPackage->expects($this->any())->method('getPackageMetaData')->will($this->returnValue($mockOrmMetadata));
106 
107  $mockDbalMetadata = $this->getMock('TYPO3\Flow\Package\MetaDataInterface');
108  $mockDbalMetadata->expects($this->any())->method('getConstraintsByType')->will($this->returnValue(array(
109  new \TYPO3\Flow\Package\MetaData\PackageConstraint('depends', 'Doctrine.Common')
110  )));
111  $mockDbalPackage = $this->getMock('TYPO3\Flow\Package\PackageInterface');
112  $mockDbalPackage->expects($this->any())->method('getPackageMetaData')->will($this->returnValue($mockDbalMetadata));
113 
114  $mockCommonMetadata = $this->getMock('TYPO3\Flow\Package\MetaDataInterface');
115  $mockCommonMetadata->expects($this->any())->method('getConstraintsByType')->will($this->returnValue(array()));
116  $mockCommonPackage = $this->getMock('TYPO3\Flow\Package\PackageInterface');
117  $mockCommonPackage->expects($this->any())->method('getPackageMetaData')->will($this->returnValue($mockCommonMetadata));
118 
119  $packages = array(
120  'TYPO3.Flow' => $mockFlowPackage,
121  'TYPO3.Fluid' => $mockFluidPackage,
122  'Doctrine.ORM' => $mockOrmPackage,
123  'Doctrine.DBAL' => $mockDbalPackage,
124  'Doctrine.Common' => $mockCommonPackage
125  );
126 
127  $packageManager = $this->getAccessibleMock('\TYPO3\Flow\Package\PackageManager', array('dummy'));
128  $packageManager->_set('packages', $packages);
129  $dependencyArray = $packageManager->_call('getDependencyArrayForPackage', 'TYPO3.Flow');
130 
131  $this->assertEquals(array('Doctrine.Common', 'Doctrine.DBAL', 'Doctrine.ORM', 'TYPO3.Fluid'), $dependencyArray);
132  }
133 
138  $packageManager = $this->getAccessibleMock('TYPO3\Flow\Package\PackageManager', array('dummy'));
139  $packageManager->_set('packageKeys', array('acme.testpackage' => 'Acme.TestPackage'));
140  $this->assertEquals('Acme.TestPackage', $packageManager->getCaseSensitivePackageKey('acme.testpackage'));
141  }
142 
147  $expectedPackageKeys = array(
148  $this->getUniqueId('TYPO3.Flow'),
149  $this->getUniqueId('TYPO3.Flow.Test'),
150  $this->getUniqueId('TYPO3.YetAnotherTestPackage'),
151  $this->getUniqueId('RobertLemke.Flow.NothingElse')
152  );
153 
154  foreach ($expectedPackageKeys as $packageKey) {
155  $packagePath = 'vfs://Test/Packages/Application/' . $packageKey . '/';
156 
157  mkdir($packagePath, 0770, TRUE);
158  mkdir($packagePath . 'Classes');
159  file_put_contents($packagePath . 'composer.json', '{"name": "' . $packageKey . '", "type": "flow-test"}');
160  }
161 
162  $packageManager = $this->getAccessibleMock('TYPO3\Flow\Package\PackageManager', array('dummy'));
163  $packageManager->_set('packagesBasePath', 'vfs://Test/Packages/');
164  $packageManager->_set('packageStatesPathAndFilename', 'vfs://Test/Configuration/PackageStates.php');
165 
166  $packageFactory = new \TYPO3\Flow\Package\PackageFactory($packageManager);
167  $this->inject($packageManager, 'packageFactory', $packageFactory);
168 
169  $packageManager->_set('packages', array());
170  $packageManager->_call('scanAvailablePackages');
171 
172  $packageStates = require('vfs://Test/Configuration/PackageStates.php');
173  $actualPackageKeys = array_keys($packageStates['packages']);
174  $this->assertEquals(sort($expectedPackageKeys), sort($actualPackageKeys));
175  }
176 
181  $expectedPackageKeys = array(
182  $this->getUniqueId('TYPO3.Flow'),
183  $this->getUniqueId('TYPO3.Flow.Test'),
184  $this->getUniqueId('TYPO3.YetAnotherTestPackage'),
185  $this->getUniqueId('RobertLemke.Flow.NothingElse')
186  );
187 
188  foreach ($expectedPackageKeys as $packageKey) {
189  $packagePath = 'vfs://Test/Packages/Application/' . $packageKey . '/';
190 
191  mkdir($packagePath, 0770, TRUE);
192  mkdir($packagePath . 'Classes');
193  file_put_contents($packagePath . 'composer.json', '{"name": "' . $packageKey . '", "type": "flow-test"}');
194  }
195 
196  $packageManager = $this->getAccessibleMock('TYPO3\Flow\Package\PackageManager', array('dummy'));
197  $packageManager->_set('packagesBasePath', 'vfs://Test/Packages/');
198  $packageManager->_set('packageStatesPathAndFilename', 'vfs://Test/Configuration/PackageStates.php');
199 
200  $packageFactory = new \TYPO3\Flow\Package\PackageFactory($packageManager);
201  $this->inject($packageManager, 'packageFactory', $packageFactory);
202 
203  $packageManager->_set('packageStatesConfiguration', array(
204  'packages' => array(
205  $packageKey => array(
206  'state' => 'inactive',
207  'frozen' => FALSE,
208  'packagePath' => 'Application/' . $packageKey . '/',
209  'classesPath' => 'Classes/'
210  )
211  ),
212  'version' => 2
213  ));
214  $packageManager->_call('scanAvailablePackages');
215  $packageManager->_call('sortAndsavePackageStates');
216 
217  $packageStates = require('vfs://Test/Configuration/PackageStates.php');
218  $this->assertEquals('inactive', $packageStates['packages'][$packageKey]['state']);
219  }
220 
221 
226  if (version_compare(phpversion(), '5.4.0', '<')) {
227  $this->markTestSkipped('This test is not reliable with PHP version below 5.4.0');
228  }
229 
230  $packageKeys = array(
231  $this->getUniqueId('RobertLemke.Flow.NothingElse'),
232  $this->getUniqueId('TYPO3.Flow'),
233  $this->getUniqueId('TYPO3.YetAnotherTestPackage')
234  );
235 
236  foreach ($packageKeys as $packageKey) {
237  $packagePath = 'vfs://Test/Packages/Application/' . $packageKey . '/';
238 
239  mkdir($packagePath, 0770, TRUE);
240  mkdir($packagePath . 'Classes');
241  file_put_contents($packagePath . 'composer.json', '{"name": "' . $packageKey . '", "type": "flow-test"}');
242  }
243 
244  $packageManager = $this->getAccessibleMock('TYPO3\Flow\Package\PackageManager', array('updateShortcuts'), array(), '', FALSE);
245  $packageManager->_set('packagesBasePath', 'vfs://Test/Packages/');
246  $packageManager->_set('packageStatesPathAndFilename', 'vfs://Test/Configuration/PackageStates.php');
247 
248  $packageFactory = new \TYPO3\Flow\Package\PackageFactory($packageManager);
249  $this->inject($packageManager, 'packageFactory', $packageFactory);
250 
251  $packageManager->_set('packages', array());
252  $packageManager->_call('scanAvailablePackages');
253 
254  $expectedPackageStatesConfiguration = array();
255  foreach ($packageKeys as $packageKey) {
256  $expectedPackageStatesConfiguration[$packageKey] = array(
257  'state' => 'active',
258  'packagePath' => 'Application/' . $packageKey . '/',
259  'classesPath' => 'Classes/',
260  'manifestPath' => '',
261  'composerName' => $packageKey
262  );
263  }
264 
265  $actualPackageStatesConfiguration = $packageManager->_get('packageStatesConfiguration');
266  $this->assertEquals($expectedPackageStatesConfiguration, $actualPackageStatesConfiguration['packages']);
267  }
268 
274  public function packageKeysAndPaths() {
275  return array(
276  array('TYPO3.YetAnotherTestPackage', 'vfs://Test/Packages/Application/TYPO3.YetAnotherTestPackage/'),
277  array('RobertLemke.Flow.NothingElse', 'vfs://Test/Packages/Application/RobertLemke.Flow.NothingElse/')
278  );
279  }
280 
285  public function createPackageCreatesPackageFolderAndReturnsPackage($packageKey, $expectedPackagePath) {
286  $actualPackage = $this->packageManager->createPackage($packageKey);
287  $actualPackagePath = $actualPackage->getPackagePath();
288 
289  $this->assertEquals($expectedPackagePath, $actualPackagePath);
290  $this->assertTrue(is_dir($actualPackagePath), 'Package path should exist after createPackage()');
291  $this->assertEquals($packageKey, $actualPackage->getPackageKey());
292  $this->assertTrue($this->packageManager->isPackageAvailable($packageKey));
293  }
294 
299  $metaData = new \TYPO3\Flow\Package\MetaData('Acme.YetAnotherTestPackage');
300  $metaData->setDescription('Yet Another Test Package');
301 
302  $package = $this->packageManager->createPackage('Acme.YetAnotherTestPackage', $metaData);
303 
304  $json = file_get_contents($package->getPackagePath() . '/composer.json');
305  $composerManifest = json_decode($json);
306 
307  $this->assertEquals('acme/yetanothertestpackage', $composerManifest->name);
308  $this->assertEquals('Yet Another Test Package', $composerManifest->description);
309  }
310 
315  $metaData = new \TYPO3\Flow\Package\MetaData('Acme.YetAnotherTestPackage2');
316  $metaData->setDescription('Yet Another Test Package');
317  $metaData->setPackageType('flow-custom-package');
318 
319  $package = $this->packageManager->createPackage('Acme.YetAnotherTestPackage2', $metaData);
320 
321  $json = file_get_contents($package->getPackagePath() . '/composer.json');
322  $composerManifest = json_decode($json);
323 
324  $this->assertEquals('flow-custom-package', $composerManifest->type);
325  }
326 
333  $package = $this->packageManager->createPackage('Acme.YetAnotherTestPackage');
334  $packagePath = $package->getPackagePath();
335 
336  $this->assertTrue(is_dir($packagePath . PackageInterface::DIRECTORY_CLASSES), "Classes directory was not created");
337  $this->assertTrue(is_dir($packagePath . PackageInterface::DIRECTORY_CONFIGURATION), "Configuration directory was not created");
338  $this->assertTrue(is_dir($packagePath . PackageInterface::DIRECTORY_DOCUMENTATION), "Documentation directory was not created");
339  $this->assertTrue(is_dir($packagePath . PackageInterface::DIRECTORY_RESOURCES), "Resources directory was not created");
340  $this->assertTrue(is_dir($packagePath . PackageInterface::DIRECTORY_TESTS_UNIT), "Tests/Unit directory was not created");
341  $this->assertTrue(is_dir($packagePath . PackageInterface::DIRECTORY_TESTS_FUNCTIONAL), "Tests/Functional directory was not created");
342  $this->assertTrue(is_dir($packagePath . PackageInterface::DIRECTORY_METADATA), "Metadata directory was not created");
343  }
344 
351  try {
352  $this->packageManager->createPackage('Invalid.PackageKey');
353  } catch (\TYPO3\Flow\Package\Exception\InvalidPackageKeyException $exception) {
354  }
355  $this->assertFalse(is_dir('vfs://Test/Packages/Application/Invalid_PackageKey'), 'Package folder with invalid package key was created');
356  }
357 
365  $this->packageManager->createPackage('Acme.YetAnotherTestPackage');
366  $this->packageManager->createPackage('Acme.YetAnotherTestPackage');
367  }
368 
373  $this->packageManager->createPackage('Acme.YetAnotherTestPackage');
374  $this->assertTrue($this->packageManager->isPackageActive('Acme.YetAnotherTestPackage'));
375  }
376 
381  $packageKey = 'Acme.YetAnotherTestPackage';
382 
383  $this->packageManager->createPackage($packageKey);
384 
385  $this->packageManager->deactivatePackage($packageKey);
386  $this->assertFalse($this->packageManager->isPackageActive($packageKey));
387 
388  $this->packageManager->activatePackage($packageKey);
389  $this->assertTrue($this->packageManager->isPackageActive($packageKey));
390  }
391 
397  $package = $this->packageManager->createPackage('Acme.YetAnotherTestPackage');
398  $package->setProtected(TRUE);
399  $this->packageManager->deactivatePackage('Acme.YetAnotherTestPackage');
400  }
401 
407  $this->packageManager->deletePackage('PrettyUnlikelyThatThisPackageExists');
408  }
409 
415  $package = $this->packageManager->createPackage('Acme.YetAnotherTestPackage');
416  $package->setProtected(TRUE);
417  $this->packageManager->deletePackage('Acme.YetAnotherTestPackage');
418  }
419 
424  $package = $this->packageManager->createPackage('Acme.YetAnotherTestPackage');
425  $packagePath = $package->getPackagePath();
426 
427  $this->assertTrue(is_dir($packagePath . PackageInterface::DIRECTORY_METADATA));
428  $this->assertTrue($this->packageManager->isPackageActive('Acme.YetAnotherTestPackage'));
429  $this->assertTrue($this->packageManager->isPackageAvailable('Acme.YetAnotherTestPackage'));
430 
431  $this->packageManager->deletePackage('Acme.YetAnotherTestPackage');
432 
433  $this->assertFalse(is_dir($packagePath . PackageInterface::DIRECTORY_METADATA));
434  $this->assertFalse($this->packageManager->isPackageActive('Acme.YetAnotherTestPackage'));
435  $this->assertFalse($this->packageManager->isPackageAvailable('Acme.YetAnotherTestPackage'));
436  }
437 
441  public function composerNamesAndPackageKeys() {
442  return array(
443  array('imagine/Imagine', 'imagine.Imagine'),
444  array('imagine/imagine', 'imagine.Imagine'),
445  array('typo3/flow', 'TYPO3.Flow'),
446  array('TYPO3/Flow', 'TYPO3.Flow')
447  );
448  }
449 
454  public function getPackageKeyFromComposerNameIgnoresCaseDifferences($composerName, $packageKey) {
455  $packageStatesConfiguration = array('packages' =>
456  array(
457  'TYPO3.Flow' => array(
458  'composerName' => 'typo3/flow'
459  ),
460  'imagine.Imagine' => array(
461  'composerName' => 'imagine/Imagine'
462  )
463  )
464  );
465 
466  $packageManager = $this->getAccessibleMock('\TYPO3\Flow\Package\PackageManager', array('resolvePackageDependencies'));
467  $packageManager->_set('packageStatesConfiguration', $packageStatesConfiguration);
468 
469  $this->assertEquals($packageKey, $packageManager->_call('getPackageKeyFromComposerName', $composerName));
470  }
471 }
inject($target, $name, $dependency)
createPackageCreatesPackageFolderAndReturnsPackage($packageKey, $expectedPackagePath)
getAccessibleMock( $originalClassName, array $methods=array(), array $arguments=array(), $mockClassName='', $callOriginalConstructor=TRUE, $callOriginalClone=TRUE, $callAutoload=TRUE)
getPackageKeyFromComposerNameIgnoresCaseDifferences($composerName, $packageKey)