[TASK] Use Environment API instead of PATH_site in em
[Packages/TYPO3.CMS.git] / typo3 / sysext / extensionmanager / Tests / Unit / Utility / InstallUtilityTest.php
1 <?php
2 declare(strict_types = 1);
3 namespace TYPO3\CMS\Extensionmanager\Tests\Unit\Utility;
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 use TYPO3\CMS\Core\Cache\CacheManager;
19 use TYPO3\CMS\Core\Core\Environment;
20 use TYPO3\CMS\Core\Registry;
21 use TYPO3\CMS\Core\Utility\GeneralUtility;
22 use TYPO3\CMS\Extensionmanager\Utility\DependencyUtility;
23 use TYPO3\CMS\Extensionmanager\Utility\InstallUtility;
24 use TYPO3\TestingFramework\Core\Unit\UnitTestCase;
25
26 /**
27 * Test case
28 */
29 class InstallUtilityTest extends UnitTestCase
30 {
31 /**
32 * @var string
33 */
34 protected $extensionKey;
35
36 /**
37 * @var array
38 */
39 protected $extensionData = [];
40
41 /**
42 * @var array List of created fake extensions to be deleted in tearDown() again
43 */
44 protected $fakedExtensions = [];
45
46 /**
47 * @var \PHPUnit_Framework_MockObject_MockObject|InstallUtility|\TYPO3\TestingFramework\Core\AccessibleObjectInterface
48 */
49 protected $installMock;
50
51 /**
52 */
53 protected function setUp()
54 {
55 $this->extensionKey = 'dummy';
56 $this->extensionData = [
57 'key' => $this->extensionKey
58 ];
59 $this->installMock = $this->getAccessibleMock(
60 InstallUtility::class,
61 [
62 'isLoaded',
63 'loadExtension',
64 'unloadExtension',
65 'processDatabaseUpdates',
66 'processRuntimeDatabaseUpdates',
67 'reloadCaches',
68 'processCachingFrameworkUpdates',
69 'saveDefaultConfiguration',
70 'getExtensionArray',
71 'enrichExtensionWithDetails',
72 'ensureConfiguredDirectoriesExist',
73 'importInitialFiles',
74 'emitAfterExtensionInstallSignal'
75 ],
76 [],
77 '',
78 false
79 );
80 $dependencyUtility = $this->getMockBuilder(DependencyUtility::class)->getMock();
81 $this->installMock->_set('dependencyUtility', $dependencyUtility);
82 $this->installMock->expects($this->any())
83 ->method('getExtensionArray')
84 ->with($this->extensionKey)
85 ->will($this->returnCallback([$this, 'getExtensionData']));
86 $this->installMock->expects($this->any())
87 ->method('enrichExtensionWithDetails')
88 ->with($this->extensionKey)
89 ->will($this->returnCallback([$this, 'getExtensionData']));
90 }
91
92 /**
93 * @return array
94 */
95 public function getExtensionData(): array
96 {
97 return $this->extensionData;
98 }
99
100 /**
101 */
102 protected function tearDown()
103 {
104 foreach ($this->fakedExtensions as $fakeExtkey => $fakeExtension) {
105 $this->testFilesToDelete[] = Environment::getVarPath() . '/tests/' . $fakeExtkey;
106 }
107 parent::tearDown();
108 }
109
110 /**
111 * Creates a fake extension inside typo3temp/. No configuration is created,
112 * just the folder
113 *
114 * @return string The extension key
115 */
116 protected function createFakeExtension(): string
117 {
118 $extKey = strtolower($this->getUniqueId('testing'));
119 $absExtPath = Environment::getVarPath() . '/tests/' . $extKey;
120 $relPath = 'typo3temp/var/tests/' . $extKey . '/';
121 GeneralUtility::mkdir($absExtPath);
122 $this->fakedExtensions[$extKey] = [
123 'siteRelPath' => $relPath
124 ];
125 return $extKey;
126 }
127
128 /**
129 * @test
130 */
131 public function installCallsProcessRuntimeDatabaseUpdates()
132 {
133 $this->installMock->expects($this->once())
134 ->method('processRuntimeDatabaseUpdates')
135 ->with($this->extensionKey);
136
137 $cacheManagerMock = $this->getMockBuilder(CacheManager::class)->getMock();
138 $cacheManagerMock->expects($this->once())->method('flushCachesInGroup');
139 $this->installMock->_set('cacheManager', $cacheManagerMock);
140 $this->installMock->install($this->extensionKey);
141 }
142
143 /**
144 * @test
145 */
146 public function installCallsLoadExtension()
147 {
148 $cacheManagerMock = $this->getMockBuilder(CacheManager::class)->getMock();
149 $cacheManagerMock->expects($this->once())->method('flushCachesInGroup');
150 $this->installMock->_set('cacheManager', $cacheManagerMock);
151 $this->installMock->expects($this->once())->method('loadExtension');
152 $this->installMock->install($this->extensionKey);
153 }
154
155 /**
156 * @test
157 */
158 public function installCallsFlushCachesIfClearCacheOnLoadIsSet()
159 {
160 $this->extensionData['clearcacheonload'] = true;
161 $cacheManagerMock = $this->getMockBuilder(CacheManager::class)->getMock();
162 $cacheManagerMock->expects($this->once())->method('flushCaches');
163 $this->installMock->_set('cacheManager', $cacheManagerMock);
164 $this->installMock->install($this->extensionKey);
165 }
166
167 /**
168 * @test
169 */
170 public function installCallsFlushCachesIfClearCacheOnLoadCamelCasedIsSet()
171 {
172 $this->extensionData['clearCacheOnLoad'] = true;
173 $cacheManagerMock = $this->getMockBuilder(CacheManager::class)->getMock();
174 $cacheManagerMock->expects($this->once())->method('flushCaches');
175 $this->installMock->_set('cacheManager', $cacheManagerMock);
176 $this->installMock->install($this->extensionKey);
177 }
178
179 /**
180 * @test
181 */
182 public function installationOfAnExtensionWillCallEnsureThatDirectoriesExist()
183 {
184 $cacheManagerMock = $this->getMockBuilder(CacheManager::class)->getMock();
185 $cacheManagerMock->expects($this->once())->method('flushCachesInGroup');
186 $this->installMock->_set('cacheManager', $cacheManagerMock);
187 $this->installMock->expects($this->once())->method('ensureConfiguredDirectoriesExist');
188 $this->installMock->install($this->extensionKey);
189 }
190
191 /**
192 * @test
193 */
194 public function installCallsReloadCaches()
195 {
196 $cacheManagerMock = $this->getMockBuilder(CacheManager::class)->getMock();
197 $cacheManagerMock->expects($this->once())->method('flushCachesInGroup');
198 $this->installMock->_set('cacheManager', $cacheManagerMock);
199 $this->installMock->expects($this->once())->method('reloadCaches');
200 $this->installMock->install('dummy');
201 }
202
203 /**
204 * @test
205 */
206 public function installCallsSaveDefaultConfigurationWithExtensionKey()
207 {
208 $cacheManagerMock = $this->getMockBuilder(CacheManager::class)->getMock();
209 $cacheManagerMock->expects($this->once())->method('flushCachesInGroup');
210 $this->installMock->_set('cacheManager', $cacheManagerMock);
211 $this->installMock->expects($this->once())->method('saveDefaultConfiguration')->with('dummy');
212 $this->installMock->install('dummy');
213 }
214
215 /**
216 * @test
217 */
218 public function uninstallCallsUnloadExtension()
219 {
220 $this->installMock->expects($this->once())->method('unloadExtension');
221 $this->installMock->uninstall($this->extensionKey);
222 }
223
224 /**
225 * @test
226 */
227 public function processDatabaseUpdatesCallsUpdateDbWithExtTablesSql()
228 {
229 $extKey = $this->createFakeExtension();
230 $extPath = Environment::getVarPath() . '/tests/' . $extKey . '/';
231 $extTablesFile = $extPath . 'ext_tables.sql';
232 $fileContent = 'DUMMY TEXT TO COMPARE';
233 file_put_contents($extTablesFile, $fileContent);
234 $installMock = $this->getAccessibleMock(
235 InstallUtility::class,
236 ['updateDbWithExtTablesSql', 'importStaticSqlFile', 'importT3DFile'],
237 [],
238 '',
239 false
240 );
241 $dependencyUtility = $this->getMockBuilder(DependencyUtility::class)->getMock();
242 $installMock->_set('dependencyUtility', $dependencyUtility);
243
244 $installMock->expects($this->once())->method('updateDbWithExtTablesSql')->with($this->stringStartsWith($fileContent));
245 $installMock->processDatabaseUpdates($this->fakedExtensions[$extKey]);
246 }
247
248 /**
249 * @test
250 */
251 public function processDatabaseUpdatesCallsImportStaticSqlFile()
252 {
253 $extKey = $this->createFakeExtension();
254 $extensionSiteRelPath = 'typo3temp/var/tests/' . $extKey . '/';
255 $installMock = $this->getAccessibleMock(
256 InstallUtility::class,
257 ['importStaticSqlFile', 'updateDbWithExtTablesSql', 'importT3DFile'],
258 [],
259 '',
260 false
261 );
262 $dependencyUtility = $this->getMockBuilder(DependencyUtility::class)->getMock();
263 $installMock->_set('dependencyUtility', $dependencyUtility);
264 $installMock->expects($this->once())->method('importStaticSqlFile')->with($extensionSiteRelPath);
265 $installMock->processDatabaseUpdates($this->fakedExtensions[$extKey]);
266 }
267
268 /**
269 * @return array
270 */
271 public function processDatabaseUpdatesCallsImportFileDataProvider(): array
272 {
273 return [
274 'T3D file' => [
275 'data.t3d'
276 ],
277 'XML file' => [
278 'data.xml'
279 ]
280 ];
281 }
282
283 /**
284 * @param string $fileName
285 * @test
286 * @dataProvider processDatabaseUpdatesCallsImportFileDataProvider
287 */
288 public function processDatabaseUpdatesCallsImportFile($fileName)
289 {
290 $extKey = $this->createFakeExtension();
291 $absPath = Environment::getPublicPath() . '/' . $this->fakedExtensions[$extKey]['siteRelPath'];
292 GeneralUtility::mkdir($absPath . '/Initialisation');
293 file_put_contents($absPath . '/Initialisation/' . $fileName, 'DUMMY');
294 $installMock = $this->getAccessibleMock(
295 InstallUtility::class,
296 ['updateDbWithExtTablesSql', 'importStaticSqlFile', 'importT3DFile'],
297 [],
298 '',
299 false
300 );
301 $dependencyUtility = $this->getMockBuilder(DependencyUtility::class)->getMock();
302 $installMock->_set('dependencyUtility', $dependencyUtility);
303 $installMock->expects($this->once())->method('importT3DFile')->with($this->fakedExtensions[$extKey]['siteRelPath']);
304 $installMock->processDatabaseUpdates($this->fakedExtensions[$extKey]);
305 }
306
307 /**
308 * @return array
309 */
310 public function importT3DFileDoesNotImportFileIfAlreadyImportedDataProvider(): array
311 {
312 return [
313 'Import T3D file when T3D was imported before extension to XML' => [
314 'data.t3d',
315 'dataImported',
316 'data.t3d',
317 ],
318 'Import T3D file when a file was imported after extension to XML' => [
319 'data.t3d',
320 'data.t3d',
321 'dataImported'
322 ],
323 'Import XML file when T3D was imported before extension to XML' => [
324 'data.xml',
325 'dataImported',
326 'data.t3d'
327 ],
328 'Import XML file when a file was imported after extension to XML' => [
329 'data.xml',
330 'data.t3d',
331 'dataImported'
332 ]
333 ];
334 }
335
336 /**
337 * @param string $fileName
338 * @param string $registryNameReturnsFalse
339 * @param string $registryNameReturnsTrue
340 * @test
341 * @dataProvider importT3DFileDoesNotImportFileIfAlreadyImportedDataProvider
342 */
343 public function importT3DFileDoesNotImportFileIfAlreadyImported($fileName, $registryNameReturnsFalse, $registryNameReturnsTrue)
344 {
345 $extKey = $this->createFakeExtension();
346 $absPath = Environment::getPublicPath() . '/' . $this->fakedExtensions[$extKey]['siteRelPath'];
347 GeneralUtility::mkdir($absPath . 'Initialisation');
348 file_put_contents($absPath . 'Initialisation/' . $fileName, 'DUMMY');
349 $registryMock = $this->getMockBuilder(Registry::class)
350 ->setMethods(['get', 'set'])
351 ->getMock();
352 $registryMock
353 ->expects($this->any())
354 ->method('get')
355 ->will($this->returnValueMap(
356 [
357 ['extensionDataImport', $this->fakedExtensions[$extKey]['siteRelPath'] . 'Initialisation/' . $registryNameReturnsFalse, null, false],
358 ['extensionDataImport', $this->fakedExtensions[$extKey]['siteRelPath'] . 'Initialisation/' . $registryNameReturnsTrue, null, true],
359 ]
360 ));
361 $installMock = $this->getAccessibleMock(
362 InstallUtility::class,
363 ['getRegistry', 'getImportExportUtility'],
364 [],
365 '',
366 false
367 );
368 $dependencyUtility = $this->getMockBuilder(DependencyUtility::class)->getMock();
369 $installMock->_set('dependencyUtility', $dependencyUtility);
370 $installMock->_set('registry', $registryMock);
371 $installMock->expects($this->never())->method('getImportExportUtility');
372 $installMock->_call('importT3DFile', $this->fakedExtensions[$extKey]['siteRelPath']);
373 }
374 }