‪TYPO3CMS  ‪main
InstallUtilityTest.php
Go to the documentation of this file.
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 
19 
20 use PHPUnit\Framework\MockObject\MockObject;
21 use Psr\Container\ContainerInterface;
22 use Psr\EventDispatcher\EventDispatcherInterface;
23 use Symfony\Component\Yaml\Yaml;
36 use TYPO3\CMS\Core\Package\PackageManager;
42 use TYPO3\TestingFramework\Core\AccessibleObjectInterface;
43 use TYPO3\TestingFramework\Core\Unit\UnitTestCase;
44 
45 class ‪InstallUtilityTest extends UnitTestCase
46 {
47  protected string ‪$extensionKey;
48  protected array ‪$extensionData = [];
49 
53  protected array ‪$fakedExtensions = [];
54 
55  protected bool ‪$backupEnvironment = true;
56  protected bool ‪$resetSingletonInstances = true;
57 
58  protected ‪InstallUtility&MockObject&AccessibleObjectInterface ‪$installMock;
59 
60  protected function ‪setUp(): void
61  {
62  parent::setUp();
63  $this->extensionKey = 'dummy';
64  $this->extensionData = [
65  'key' => ‪$this->extensionKey,
66  'packagePath' => '',
67  ];
68  $this->installMock = $this->getAccessibleMock(
69  InstallUtility::class,
70  [
71  'loadExtension',
72  'unloadExtension',
73  'updateDatabase',
74  'importStaticSqlFile',
75  'importT3DFile',
76  'reloadCaches',
77  'processExtensionSetup',
78  'saveDefaultConfiguration',
79  'getExtensionArray',
80  'enrichExtensionWithDetails',
81  'importInitialFiles',
82  ]
83  );
84  $eventDispatcher = new ‪NoopEventDispatcher();
85  $this->installMock->injectEventDispatcher($eventDispatcher);
86  $this->installMock->injectBootService($this->createMock(BootService::class));
87  $containerMock = $this->createMock(ContainerInterface::class);
88  $containerMock->method('get')->with(EventDispatcherInterface::class)->willReturn($eventDispatcher);
89  $bootServiceMock = $this->createMock(BootService::class);
90  $bootServiceMock->method('getContainer')->with(false)->willReturn($containerMock);
91  $bootServiceMock->method('makeCurrent')->with(self::anything())->willReturn([]);
92  $this->installMock->injectBootService($bootServiceMock);
93  $this->installMock
94  ->method('getExtensionArray')
95  ->with($this->extensionKey)
96  ->willReturnCallback($this->‪getExtensionData(...));
97  $this->installMock
98  ->method('enrichExtensionWithDetails')
99  ->with($this->extensionKey)
100  ->willReturnCallback($this->‪getExtensionData(...));
101 
102  $cacheManagerMock = $this->createMock(CacheManager::class);
103  $cacheManagerMock->method('getCache')->with('core')->willReturn(new ‪NullFrontend('core'));
104  GeneralUtility::setSingletonInstance(CacheManager::class, $cacheManagerMock);
105  }
106 
107  protected function ‪tearDown(): void
108  {
109  foreach ($this->fakedExtensions as $fakeExtkey => $fakeExtension) {
110  $this->testFilesToDelete[] = ‪Environment::getVarPath() . '/tests/' . $fakeExtkey;
111  }
112  parent::tearDown();
113  }
114 
115  public function ‪getExtensionData(): array
116  {
118  }
119 
126  protected function ‪createFakeExtension(): string
127  {
128  $extKey = strtolower(‪StringUtility::getUniqueId('testing'));
129  $absExtPath = ‪Environment::getVarPath() . '/tests/' . $extKey;
130  ‪GeneralUtility::mkdir_deep($absExtPath);
131  $this->fakedExtensions[$extKey] = [
132  'packagePath' => $absExtPath,
133  ];
134  return $extKey;
135  }
136 
140  public function ‪installCallsUpdateDatabase(): void
141  {
142  $this->installMock->expects(self::once())->method('updateDatabase');
143 
144  $cacheManagerMock = $this->getMockBuilder(CacheManager::class)->getMock();
145  $this->installMock->_set('cacheManager', $cacheManagerMock);
146  $this->installMock->install($this->extensionKey);
147  }
148 
152  public function ‪installCallsLoadExtension(): void
153  {
154  $cacheManagerMock = $this->getMockBuilder(CacheManager::class)->getMock();
155  $this->installMock->_set('cacheManager', $cacheManagerMock);
156  $this->installMock->expects(self::once())->method('loadExtension');
157  $this->installMock->install($this->extensionKey);
158  }
159 
163  public function ‪installCallsFlushCaches(): void
164  {
165  $cacheManagerMock = $this->getMockBuilder(CacheManager::class)->getMock();
166  $cacheManagerMock->expects(self::once())->method('flushCaches');
167  $this->installMock->_set('cacheManager', $cacheManagerMock);
168  $this->installMock->install($this->extensionKey);
169  }
170 
174  public function ‪installCallsReloadCaches(): void
175  {
176  $cacheManagerMock = $this->getMockBuilder(CacheManager::class)->getMock();
177  $this->installMock->_set('cacheManager', $cacheManagerMock);
178  $this->installMock->expects(self::once())->method('reloadCaches');
179  $this->installMock->install($this->extensionKey);
180  }
181 
186  {
187  $cacheManagerMock = $this->getMockBuilder(CacheManager::class)->getMock();
188  $this->installMock->_set('cacheManager', $cacheManagerMock);
189  $this->installMock->expects(self::once())->method('saveDefaultConfiguration')->with($this->extensionKey);
190  $this->installMock->install($this->extensionKey);
191  }
192 
194  {
195  return [
196  'Import T3D file when T3D was imported before extension to XML' => [
197  'data.t3d',
198  'dataImported',
199  'data.t3d',
200  ],
201  'Import T3D file when a file was imported after extension to XML' => [
202  'data.t3d',
203  'data.t3d',
204  'dataImported',
205  ],
206  'Import XML file when T3D was imported before extension to XML' => [
207  'data.xml',
208  'dataImported',
209  'data.t3d',
210  ],
211  'Import XML file when a file was imported after extension to XML' => [
212  'data.xml',
213  'data.t3d',
214  'dataImported',
215  ],
216  ];
217  }
218 
226  public function ‪importT3DFileDoesNotImportFileIfAlreadyImported($fileName, $registryNameReturnsFalse, $registryNameReturnsTrue): void
227  {
228  $extKey = $this->‪createFakeExtension();
229  $absPath = $this->fakedExtensions[$extKey]['packagePath'];
230  $relPath = ‪PathUtility::stripPathSitePrefix($absPath);
231  ‪GeneralUtility::mkdir($absPath . 'Initialisation');
232  file_put_contents($absPath . 'Initialisation/' . $fileName, 'DUMMY');
233  $registryMock = $this->getMockBuilder(Registry::class)
234  ->onlyMethods(['get', 'set'])
235  ->getMock();
236  $registryMock
237  ->method('get')
238  ->willReturnMap(
239  [
240  ['extensionDataImport', $relPath . 'Initialisation/' . $registryNameReturnsFalse, null, false],
241  ['extensionDataImport', $relPath . 'Initialisation/' . $registryNameReturnsTrue, null, true],
242  ]
243  );
244  ‪$installMock = $this->getAccessibleMock(
245  InstallUtility::class,
246  ['getRegistry', 'getImportExportUtility'],
247  [],
248  '',
249  false
250  );
251  ‪$installMock->_set('registry', $registryMock);
252  ‪$installMock->expects(self::never())->method('getImportExportUtility');
253  ‪$installMock->_call('importT3DFile', $extKey, $this->fakedExtensions[$extKey]['packagePath']);
254  }
255 
260  public function ‪siteConfigGetsMovedIntoPlace(): void
261  {
262  // prepare an extension with a shipped site config
263  $extKey = $this->‪createFakeExtension();
264  $absPath = $this->fakedExtensions[$extKey]['packagePath'];
265  $config = Yaml::dump(['dummy' => true]);
266  ‪$siteIdentifier = 'site_identifier';
267  ‪GeneralUtility::mkdir_deep($absPath . 'Initialisation/Site/' . ‪$siteIdentifier);
268  file_put_contents($absPath . 'Initialisation/Site/' . ‪$siteIdentifier . '/config.yaml', $config);
269 
270  GeneralUtility::setSingletonInstance(
271  SiteConfiguration::class,
273  ‪Environment::getConfigPath() . '/sites',
274  new class () implements EventDispatcherInterface {
275  public function dispatch(object $event)
276  {
277  return $event;
278  }
279  },
280  new ‪NullFrontend('core')
281  )
282  );
283 
284  $packageMock = $this->getMockBuilder(Package::class)
285  ->disableOriginalConstructor()
286  ->getMock();
287  $packageManagerMock = $this->getMockBuilder(PackageManager::class)
288  ->disableOriginalConstructor()
289  ->getMock();
290  $packageMock
291  ->method('getPackagePath')
292  ->willReturn($absPath);
293  $packageManagerMock
294  ->method('getPackage')
295  ->with(self::equalTo($extKey))
296  ->willReturn($packageMock);
297 
298  $subject = new ‪InstallUtility();
299  $subject->injectEventDispatcher(new ‪NoopEventDispatcher());
300  $subject->injectPackageManager($packageManagerMock);
301 
302  $registry = $this->createMock(Registry::class);
303  $registry->method('get')->willReturnMap([
304  ['extensionDataImport', self::anything(), 'some folder name'],
305  ['siteConfigImport', self::anything(), null],
306  ]);
307  $registry->expects(self::atLeastOnce())->method('set')->withConsecutive(
308  ['extensionDataImport', self::anything()],
309  ['siteConfigImport', self::anything()],
310  ['siteConfigImport', ‪$siteIdentifier, 1],
311  );
312 
313  $subject->injectRegistry($registry);
314 
315  $providerConfigurationLoader = $this->createMock(ProviderConfigurationLoader::class);
316  GeneralUtility::addInstance(ProviderConfigurationLoader::class, $providerConfigurationLoader);
317  GeneralUtility::addInstance(ProviderConfigurationLoader::class, $providerConfigurationLoader);
318  $defaultProvider = new ‪DefaultProvider(new ‪Typo3Version(), new ‪Context(), new ‪Features());
319  GeneralUtility::addInstance(DefaultProvider::class, $defaultProvider);
320  GeneralUtility::addInstance(DefaultProvider::class, $defaultProvider);
321 
322  // provide function result inside test output folder
323  $environment = new ‪Environment();
324  $configDir = $absPath . 'Result/config';
325  if (!file_exists($configDir)) {
326  ‪GeneralUtility::mkdir_deep($configDir);
327  }
328  $environment::initialize(
335  $configDir,
337  'UNIX'
338  );
339  $subject->processExtensionSetup($extKey);
340 
341  $siteConfigFile = $configDir . '/sites/' . ‪$siteIdentifier . '/config.yaml';
342  self::assertFileExists($siteConfigFile);
343  self::assertStringEqualsFile($siteConfigFile, $config);
344  GeneralUtility::purgeInstances();
345  }
346 
352  {
353  // prepare an extension with a shipped site config
354  $extKey = $this->‪createFakeExtension();
355  $absPath = $this->fakedExtensions[$extKey]['packagePath'];
356  ‪$siteIdentifier = 'site_identifier';
357  ‪GeneralUtility::mkdir_deep($absPath . 'Initialisation/Site/' . ‪$siteIdentifier);
358  file_put_contents($absPath . 'Initialisation/Site/' . ‪$siteIdentifier . '/config.yaml', Yaml::dump(['dummy' => true]));
359 
360  // fake an already existing site config in test output folder
361  $configDir = $absPath . 'Result/config';
362  if (!file_exists($configDir)) {
363  ‪GeneralUtility::mkdir_deep($configDir);
364  }
365  $config = Yaml::dump(['foo' => 'bar']);
366  $existingSiteConfig = 'sites/' . ‪$siteIdentifier . '/config.yaml';
367  ‪GeneralUtility::mkdir_deep($configDir . '/sites/' . ‪$siteIdentifier);
368  file_put_contents($configDir . '/' . $existingSiteConfig, $config);
369 
370  GeneralUtility::setSingletonInstance(
371  SiteConfiguration::class,
373  ‪Environment::getConfigPath() . '/sites',
374  new class () implements EventDispatcherInterface {
375  public function dispatch(object $event)
376  {
377  return $event;
378  }
379  },
380  new ‪NullFrontend('core')
381  )
382  );
383  $packageMock = $this->getMockBuilder(Package::class)
384  ->disableOriginalConstructor()
385  ->getMock();
386  $packageManagerMock = $this->getMockBuilder(PackageManager::class)
387  ->disableOriginalConstructor()
388  ->getMock();
389  $packageMock
390  ->method('getPackagePath')
391  ->willReturn($absPath);
392  $packageManagerMock
393  ->method('getPackage')
394  ->with(self::equalTo($extKey))
395  ->willReturn($packageMock);
396 
397  $subject = new ‪InstallUtility();
398  $subject->injectEventDispatcher(new ‪NoopEventDispatcher());
399  $subject->injectPackageManager($packageManagerMock);
400 
401  $registry = $this->createMock(Registry::class);
402  $registry->method('get')->willReturnMap([
403  ['extensionDataImport', self::anything(), 'some folder name'],
404  ['siteConfigImport', self::anything(), null],
405  ]);
406  // Note, that test will fail if `set` is called with `siteConfigImport` as first argument.
407  $registry->expects(self::atLeastOnce())->method('set')->with('extensionDataImport', self::anything());
408  $subject->injectRegistry($registry);
409 
410  $providerConfigurationLoader = $this->createMock(ProviderConfigurationLoader::class);
411  GeneralUtility::addInstance(ProviderConfigurationLoader::class, $providerConfigurationLoader);
412  GeneralUtility::addInstance(ProviderConfigurationLoader::class, $providerConfigurationLoader);
413  $defaultProvider = new ‪DefaultProvider(new ‪Typo3Version(), new ‪Context(), new ‪Features());
414  GeneralUtility::addInstance(DefaultProvider::class, $defaultProvider);
415  GeneralUtility::addInstance(DefaultProvider::class, $defaultProvider);
416 
417  $environment = new ‪Environment();
418 
419  $environment::initialize(
426  $configDir,
428  'UNIX'
429  );
430  $subject->processExtensionSetup($extKey);
431 
432  $siteConfigFile = $configDir . '/sites/' . ‪$siteIdentifier . '/config.yaml';
433  self::assertFileExists($siteConfigFile);
434  self::assertStringEqualsFile($siteConfigFile, $config);
435  GeneralUtility::purgeInstances();
436  }
437 }
‪TYPO3\CMS\Extensionmanager\Tests\Unit\Utility\InstallUtilityTest\installCallsReloadCaches
‪installCallsReloadCaches()
Definition: InstallUtilityTest.php:174
‪TYPO3\CMS\Extensionmanager\Tests\Unit\Utility\InstallUtilityTest
Definition: InstallUtilityTest.php:46
‪TYPO3\CMS\Core\Utility\PathUtility\stripPathSitePrefix
‪static stripPathSitePrefix(string $path)
Definition: PathUtility.php:428
‪TYPO3\CMS\Core\Utility\PathUtility
Definition: PathUtility.php:27
‪TYPO3\CMS\Core\Information\Typo3Version
Definition: Typo3Version.php:21
‪TYPO3\CMS\Extensionmanager\Tests\Unit\Utility
Definition: DependencyUtilityTest.php:18
‪TYPO3\CMS\Core\Core\Environment\isComposerMode
‪static isComposerMode()
Definition: Environment.php:137
‪TYPO3\CMS\Core\Core\Environment\getPublicPath
‪static getPublicPath()
Definition: Environment.php:187
‪TYPO3\CMS\Core\Registry
Definition: Registry.php:33
‪TYPO3\CMS\Extensionmanager\Tests\Unit\Utility\InstallUtilityTest\installCallsSaveDefaultConfigurationWithExtensionKey
‪installCallsSaveDefaultConfigurationWithExtensionKey()
Definition: InstallUtilityTest.php:185
‪TYPO3\CMS\Core\ExpressionLanguage\DefaultProvider
Definition: DefaultProvider.php:33
‪TYPO3\CMS\Extensionmanager\Tests\Unit\Utility\InstallUtilityTest\$extensionKey
‪string $extensionKey
Definition: InstallUtilityTest.php:47
‪TYPO3\CMS\Extensionmanager\Tests\Unit\Utility\InstallUtilityTest\$resetSingletonInstances
‪bool $resetSingletonInstances
Definition: InstallUtilityTest.php:56
‪TYPO3\CMS\Core\Core\Environment\getCurrentScript
‪static getCurrentScript()
Definition: Environment.php:220
‪TYPO3\CMS\Extensionmanager\Tests\Unit\Utility\InstallUtilityTest\$installMock
‪InstallUtility &MockObject &AccessibleObjectInterface $installMock
Definition: InstallUtilityTest.php:58
‪TYPO3\CMS\Extensionmanager\Tests\Unit\Utility\InstallUtilityTest\importT3DFileDoesNotImportFileIfAlreadyImportedDataProvider
‪static importT3DFileDoesNotImportFileIfAlreadyImportedDataProvider()
Definition: InstallUtilityTest.php:193
‪TYPO3\CMS\Core\Cache\Frontend\NullFrontend
Definition: NullFrontend.php:30
‪TYPO3\CMS\Extensionmanager\Tests\Unit\Utility\InstallUtilityTest\importT3DFileDoesNotImportFileIfAlreadyImported
‪importT3DFileDoesNotImportFileIfAlreadyImported($fileName, $registryNameReturnsFalse, $registryNameReturnsTrue)
Definition: InstallUtilityTest.php:226
‪TYPO3\CMS\Extensionmanager\Tests\Unit\Utility\InstallUtilityTest\siteConfigGetsNotOverriddenIfExistsAlready
‪siteConfigGetsNotOverriddenIfExistsAlready()
Definition: InstallUtilityTest.php:351
‪TYPO3\CMS\Core\Core\Environment\getVarPath
‪static getVarPath()
Definition: Environment.php:197
‪TYPO3\CMS\Core\Core\BootService
Definition: BootService.php:32
‪TYPO3\CMS\Core\Context\Context
Definition: Context.php:55
‪TYPO3\CMS\Core\Configuration\SiteConfiguration
Definition: SiteConfiguration.php:47
‪TYPO3\CMS\Core\Core\Environment\getConfigPath
‪static getConfigPath()
Definition: Environment.php:212
‪TYPO3\CMS\Extensionmanager\Utility\InstallUtility
Definition: InstallUtility.php:55
‪TYPO3\CMS\Extensionmanager\Tests\Unit\Utility\InstallUtilityTest\installCallsLoadExtension
‪installCallsLoadExtension()
Definition: InstallUtilityTest.php:152
‪TYPO3\CMS\Core\Core\Environment\getProjectPath
‪static string getProjectPath()
Definition: Environment.php:160
‪TYPO3\CMS\Core\Utility\GeneralUtility\mkdir_deep
‪static mkdir_deep($directory)
Definition: GeneralUtility.php:1753
‪TYPO3\CMS\Extensionmanager\Tests\Unit\Utility\InstallUtilityTest\createFakeExtension
‪string createFakeExtension()
Definition: InstallUtilityTest.php:126
‪TYPO3\CMS\Extensionmanager\Tests\Unit\Utility\InstallUtilityTest\tearDown
‪tearDown()
Definition: InstallUtilityTest.php:107
‪TYPO3\CMS\Core\Package\Package
Definition: Package.php:28
‪TYPO3\CMS\Extensionmanager\Tests\Unit\Utility\InstallUtilityTest\$extensionData
‪array $extensionData
Definition: InstallUtilityTest.php:48
‪TYPO3\CMS\Core\Configuration\Features
Definition: Features.php:56
‪TYPO3\CMS\Extensionmanager\Tests\Unit\Utility\InstallUtilityTest\installCallsUpdateDatabase
‪installCallsUpdateDatabase()
Definition: InstallUtilityTest.php:140
‪TYPO3\CMS\Core\Cache\CacheManager
Definition: CacheManager.php:36
‪TYPO3\CMS\Core\Core\Environment\isCli
‪static isCli()
Definition: Environment.php:145
‪TYPO3\CMS\Extensionmanager\Tests\Unit\Utility\InstallUtilityTest\installCallsFlushCaches
‪installCallsFlushCaches()
Definition: InstallUtilityTest.php:163
‪TYPO3\CMS\Extensionmanager\Tests\Unit\Utility\InstallUtilityTest\setUp
‪setUp()
Definition: InstallUtilityTest.php:60
‪TYPO3\CMS\Core\ExpressionLanguage\ProviderConfigurationLoader
Definition: ProviderConfigurationLoader.php:28
‪TYPO3\CMS\Core\EventDispatcher\NoopEventDispatcher
Definition: NoopEventDispatcher.php:29
‪TYPO3\CMS\Core\Core\Environment
Definition: Environment.php:41
‪TYPO3\CMS\Extensionmanager\Tests\Unit\Utility\InstallUtilityTest\siteConfigGetsMovedIntoPlace
‪siteConfigGetsMovedIntoPlace()
Definition: InstallUtilityTest.php:260
‪TYPO3\CMS\Webhooks\Message\$siteIdentifier
‪identifier readonly int readonly array readonly string readonly string $siteIdentifier
Definition: PageModificationMessage.php:38
‪TYPO3\CMS\Extensionmanager\Tests\Unit\Utility\InstallUtilityTest\getExtensionData
‪getExtensionData()
Definition: InstallUtilityTest.php:115
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:51
‪TYPO3\CMS\Core\Utility\StringUtility
Definition: StringUtility.php:24
‪TYPO3\CMS\Extensionmanager\Tests\Unit\Utility\InstallUtilityTest\$fakedExtensions
‪array $fakedExtensions
Definition: InstallUtilityTest.php:53
‪TYPO3\CMS\Core\Utility\GeneralUtility\mkdir
‪static bool mkdir($newFolder)
Definition: GeneralUtility.php:1736
‪TYPO3\CMS\Extensionmanager\Tests\Unit\Utility\InstallUtilityTest\$backupEnvironment
‪bool $backupEnvironment
Definition: InstallUtilityTest.php:55
‪TYPO3\CMS\Core\Core\Environment\getContext
‪static getContext()
Definition: Environment.php:128
‪TYPO3\CMS\Core\Utility\StringUtility\getUniqueId
‪static getUniqueId(string $prefix='')
Definition: StringUtility.php:29