Commit | Line | Data |
---|---|---|
6a488035 | 1 | <?php |
b6708aeb | 2 | /* |
3 | +--------------------------------------------------------------------+ | |
7d61e75f TO |
4 | | Copyright CiviCRM LLC. All rights reserved. | |
5 | | | | |
6 | | This work is published under the GNU AGPLv3 license with some | | |
7 | | permitted exceptions and without any warranty. For full license | | |
8 | | and copyright information, see https://civicrm.org/licensing | | |
9 | +--------------------------------------------------------------------+ | |
e70a7fc0 | 10 | */ |
6a488035 | 11 | |
e9479dcf EM |
12 | /** |
13 | * Class CRM_Extension_ManagerTest | |
acb109b7 | 14 | * @group headless |
e9479dcf | 15 | */ |
6a488035 TO |
16 | class CRM_Extension_ManagerTest extends CiviUnitTestCase { |
17 | const TESTING_TYPE = 'report'; | |
18 | const OTHER_TESTING_TYPE = 'module'; | |
19 | ||
5d345864 | 20 | public function setUp(): void { |
6a488035 TO |
21 | parent::setUp(); |
22 | list ($this->basedir, $this->container) = $this->_createContainer(); | |
23 | $this->mapper = new CRM_Extension_Mapper($this->container); | |
24 | } | |
25 | ||
6a488035 | 26 | /** |
eceb18cc | 27 | * Install an extension with an invalid type name. |
6a488035 | 28 | */ |
00be9182 | 29 | public function testInstallInvalidType() { |
275686a3 | 30 | $this->expectException(CRM_Extension_Exception::class); |
ad42f150 | 31 | $testingTypeManager = $this->getMockBuilder('CRM_Extension_Manager_Interface')->getMock(); |
6a488035 TO |
32 | $testingTypeManager->expects($this->never()) |
33 | ->method('onPreInstall'); | |
9099cab3 | 34 | $manager = $this->_createManager([ |
6a488035 | 35 | self::OTHER_TESTING_TYPE => $testingTypeManager, |
9099cab3 CW |
36 | ]); |
37 | $manager->install(['test.foo.bar']); | |
6a488035 TO |
38 | } |
39 | ||
40 | /** | |
eceb18cc | 41 | * Install an extension with a valid type name. |
6a488035 TO |
42 | * |
43 | * Note: We initially install two extensions but then toggle only | |
44 | * the second. This controls for bad SQL queries which hit either | |
45 | * "the first row" or "all rows". | |
46 | */ | |
00be9182 | 47 | public function testInstall_Disable_Uninstall() { |
ad42f150 | 48 | $testingTypeManager = $this->getMockBuilder('CRM_Extension_Manager_Interface')->getMock(); |
9099cab3 | 49 | $manager = $this->_createManager([ |
6a488035 | 50 | self::TESTING_TYPE => $testingTypeManager, |
9099cab3 | 51 | ]); |
6a488035 TO |
52 | $this->assertEquals('uninstalled', $manager->getStatus('test.foo.bar')); |
53 | $this->assertEquals('uninstalled', $manager->getStatus('test.whiz.bang')); | |
54 | ||
55 | $testingTypeManager | |
56 | ->expects($this->exactly(2)) | |
57 | ->method('onPreInstall'); | |
58 | $testingTypeManager | |
59 | ->expects($this->exactly(2)) | |
60 | ->method('onPostInstall'); | |
9099cab3 | 61 | $manager->install(['test.whiz.bang', 'test.foo.bar']); |
6a488035 TO |
62 | $this->assertEquals('installed', $manager->getStatus('test.foo.bar')); |
63 | $this->assertEquals('installed', $manager->getStatus('test.whiz.bang')); | |
64 | ||
65 | $testingTypeManager | |
66 | ->expects($this->once()) | |
67 | ->method('onPreDisable'); | |
68 | $testingTypeManager | |
69 | ->expects($this->once()) | |
70 | ->method('onPostDisable'); | |
9099cab3 | 71 | $manager->disable(['test.foo.bar']); |
6a488035 | 72 | $this->assertEquals('disabled', $manager->getStatus('test.foo.bar')); |
39b959db SL |
73 | // no side-effect |
74 | $this->assertEquals('installed', $manager->getStatus('test.whiz.bang')); | |
6a488035 TO |
75 | |
76 | $testingTypeManager | |
77 | ->expects($this->once()) | |
78 | ->method('onPreUninstall'); | |
79 | $testingTypeManager | |
80 | ->expects($this->once()) | |
81 | ->method('onPostUninstall'); | |
9099cab3 | 82 | $manager->uninstall(['test.foo.bar']); |
6a488035 | 83 | $this->assertEquals('uninstalled', $manager->getStatus('test.foo.bar')); |
39b959db SL |
84 | // no side-effect |
85 | $this->assertEquals('installed', $manager->getStatus('test.whiz.bang')); | |
6a488035 TO |
86 | } |
87 | ||
f8a7cfff TO |
88 | /** |
89 | * This is the same as testInstall_Disable_Uninstall, but we also install and remove a dependency. | |
90 | * | |
91 | * @throws \CRM_Extension_Exception | |
92 | */ | |
93 | public function test_InstallAuto_DisableDownstream_UninstallDownstream() { | |
ad42f150 | 94 | $testingTypeManager = $this->getMockBuilder('CRM_Extension_Manager_Interface')->getMock(); |
9099cab3 | 95 | $manager = $this->_createManager([ |
f8a7cfff | 96 | self::TESTING_TYPE => $testingTypeManager, |
9099cab3 | 97 | ]); |
f8a7cfff TO |
98 | $this->assertEquals('uninstalled', $manager->getStatus('test.foo.bar')); |
99 | $this->assertEquals('uninstalled', $manager->getStatus('test.foo.downstream')); | |
100 | $this->assertEquals('uninstalled', $manager->getStatus('test.whiz.bang')); | |
101 | ||
102 | $testingTypeManager->expects($this->exactly(2))->method('onPreInstall'); | |
103 | $testingTypeManager->expects($this->exactly(2))->method('onPostInstall'); | |
9099cab3 CW |
104 | $this->assertEquals(['test.foo.bar', 'test.foo.downstream'], |
105 | $manager->findInstallRequirements(['test.foo.downstream'])); | |
f8a7cfff | 106 | $manager->install( |
9099cab3 | 107 | $manager->findInstallRequirements(['test.foo.downstream'])); |
f8a7cfff TO |
108 | $this->assertEquals('installed', $manager->getStatus('test.foo.bar')); |
109 | $this->assertEquals('installed', $manager->getStatus('test.foo.downstream')); | |
110 | $this->assertEquals('uninstalled', $manager->getStatus('test.whiz.bang')); | |
111 | ||
112 | $testingTypeManager->expects($this->once())->method('onPreDisable'); | |
113 | $testingTypeManager->expects($this->once())->method('onPostDisable'); | |
9099cab3 CW |
114 | $this->assertEquals(['test.foo.downstream'], |
115 | $manager->findDisableRequirements(['test.foo.downstream'])); | |
116 | $manager->disable(['test.foo.downstream']); | |
f8a7cfff TO |
117 | $this->assertEquals('installed', $manager->getStatus('test.foo.bar')); |
118 | $this->assertEquals('disabled', $manager->getStatus('test.foo.downstream')); | |
119 | $this->assertEquals('uninstalled', $manager->getStatus('test.whiz.bang')); | |
120 | ||
121 | $testingTypeManager->expects($this->once())->method('onPreUninstall'); | |
122 | $testingTypeManager->expects($this->once())->method('onPostUninstall'); | |
9099cab3 | 123 | $manager->uninstall(['test.foo.downstream']); |
f8a7cfff TO |
124 | $this->assertEquals('installed', $manager->getStatus('test.foo.bar')); |
125 | $this->assertEquals('uninstalled', $manager->getStatus('test.foo.downstream')); | |
126 | $this->assertEquals('uninstalled', $manager->getStatus('test.whiz.bang')); | |
127 | } | |
128 | ||
ca29efdc TO |
129 | /** |
130 | * This is the same as testInstallAuto_Twice | |
131 | * | |
132 | * @throws \CRM_Extension_Exception | |
133 | */ | |
134 | public function testInstallAuto_Twice() { | |
ad42f150 | 135 | $testingTypeManager = $this->getMockBuilder('CRM_Extension_Manager_Interface')->getMock(); |
9099cab3 | 136 | $manager = $this->_createManager([ |
ca29efdc | 137 | self::TESTING_TYPE => $testingTypeManager, |
9099cab3 | 138 | ]); |
ca29efdc TO |
139 | $this->assertEquals('uninstalled', $manager->getStatus('test.foo.bar')); |
140 | $this->assertEquals('uninstalled', $manager->getStatus('test.foo.downstream')); | |
141 | $this->assertEquals('uninstalled', $manager->getStatus('test.whiz.bang')); | |
142 | ||
143 | $testingTypeManager->expects($this->exactly(2))->method('onPreInstall'); | |
144 | $testingTypeManager->expects($this->exactly(2))->method('onPostInstall'); | |
9099cab3 CW |
145 | $this->assertEquals(['test.foo.bar', 'test.foo.downstream'], |
146 | $manager->findInstallRequirements(['test.foo.downstream'])); | |
ca29efdc | 147 | $manager->install( |
9099cab3 | 148 | $manager->findInstallRequirements(['test.foo.downstream'])); |
ca29efdc TO |
149 | $this->assertEquals('installed', $manager->getStatus('test.foo.bar')); |
150 | $this->assertEquals('installed', $manager->getStatus('test.foo.downstream')); | |
151 | $this->assertEquals('uninstalled', $manager->getStatus('test.whiz.bang')); | |
152 | ||
153 | // And install a second time... | |
154 | $testingTypeManager->expects($this->exactly(0))->method('onPreInstall'); | |
155 | $testingTypeManager->expects($this->exactly(0))->method('onPostInstall'); | |
156 | $manager->install( | |
9099cab3 | 157 | $manager->findInstallRequirements(['test.foo.downstream'])); |
ca29efdc TO |
158 | $this->assertEquals('installed', $manager->getStatus('test.foo.bar')); |
159 | $this->assertEquals('installed', $manager->getStatus('test.foo.downstream')); | |
160 | $this->assertEquals('uninstalled', $manager->getStatus('test.whiz.bang')); | |
161 | } | |
162 | ||
f8a7cfff | 163 | public function test_InstallAuto_DisableUpstream() { |
ad42f150 | 164 | $testingTypeManager = $this->getMockBuilder('CRM_Extension_Manager_Interface')->getMock(); |
9099cab3 | 165 | $manager = $this->_createManager([ |
f8a7cfff | 166 | self::TESTING_TYPE => $testingTypeManager, |
9099cab3 | 167 | ]); |
f8a7cfff TO |
168 | $this->assertEquals('uninstalled', $manager->getStatus('test.foo.bar')); |
169 | $this->assertEquals('uninstalled', $manager->getStatus('test.foo.downstream')); | |
170 | $this->assertEquals('uninstalled', $manager->getStatus('test.whiz.bang')); | |
171 | ||
172 | $testingTypeManager->expects($this->exactly(2))->method('onPreInstall'); | |
173 | $testingTypeManager->expects($this->exactly(2))->method('onPostInstall'); | |
9099cab3 CW |
174 | $this->assertEquals(['test.foo.bar', 'test.foo.downstream'], |
175 | $manager->findInstallRequirements(['test.foo.downstream'])); | |
f8a7cfff | 176 | $manager->install( |
9099cab3 | 177 | $manager->findInstallRequirements(['test.foo.downstream'])); |
f8a7cfff TO |
178 | $this->assertEquals('installed', $manager->getStatus('test.foo.bar')); |
179 | $this->assertEquals('installed', $manager->getStatus('test.foo.downstream')); | |
180 | $this->assertEquals('uninstalled', $manager->getStatus('test.whiz.bang')); | |
181 | ||
182 | $testingTypeManager->expects($this->never())->method('onPreDisable'); | |
183 | $testingTypeManager->expects($this->never())->method('onPostDisable'); | |
9099cab3 CW |
184 | $this->assertEquals(['test.foo.downstream', 'test.foo.bar'], |
185 | $manager->findDisableRequirements(['test.foo.bar'])); | |
f8a7cfff TO |
186 | |
187 | try { | |
9099cab3 | 188 | $manager->disable(['test.foo.bar']); |
f8a7cfff TO |
189 | $this->fail('Expected disable to fail due to dependency'); |
190 | } | |
191 | catch (CRM_Extension_Exception $e) { | |
192 | $this->assertRegExp('/test.foo.downstream/', $e->getMessage()); | |
193 | } | |
194 | ||
195 | // Status unchanged | |
196 | $this->assertEquals('installed', $manager->getStatus('test.foo.bar')); | |
197 | $this->assertEquals('installed', $manager->getStatus('test.foo.downstream')); | |
198 | $this->assertEquals('uninstalled', $manager->getStatus('test.whiz.bang')); | |
199 | } | |
200 | ||
6a488035 TO |
201 | /** |
202 | * Install an extension and then harshly remove the underlying source. | |
203 | * Subseuently disable and uninstall. | |
204 | */ | |
00be9182 | 205 | public function testInstall_DirtyRemove_Disable_Uninstall() { |
ad42f150 | 206 | $testingTypeManager = $this->getMockBuilder('CRM_Extension_Manager_Interface')->getMock(); |
9099cab3 | 207 | $manager = $this->_createManager([ |
6a488035 | 208 | self::TESTING_TYPE => $testingTypeManager, |
9099cab3 | 209 | ]); |
6a488035 TO |
210 | $this->assertEquals('uninstalled', $manager->getStatus('test.foo.bar')); |
211 | ||
9099cab3 | 212 | $manager->install(['test.foo.bar']); |
6a488035 TO |
213 | $this->assertEquals('installed', $manager->getStatus('test.foo.bar')); |
214 | ||
215 | $this->assertTrue(file_exists("{$this->basedir}/weird/foobar/info.xml")); | |
216 | CRM_Utils_File::cleanDir("{$this->basedir}/weird/foobar", TRUE, FALSE); | |
217 | $this->assertFalse(file_exists("{$this->basedir}/weird/foobar/info.xml")); | |
218 | $manager->refresh(); | |
219 | $this->assertEquals('installed-missing', $manager->getStatus('test.foo.bar')); | |
220 | ||
221 | $testingTypeManager | |
222 | ->expects($this->once()) | |
223 | ->method('onPreDisable'); | |
224 | $testingTypeManager | |
225 | ->expects($this->once()) | |
226 | ->method('onPostDisable'); | |
9099cab3 | 227 | $manager->disable(['test.foo.bar']); |
6a488035 TO |
228 | $this->assertEquals('disabled-missing', $manager->getStatus('test.foo.bar')); |
229 | ||
230 | $testingTypeManager | |
231 | ->expects($this->once()) | |
232 | ->method('onPreUninstall'); | |
233 | $testingTypeManager | |
234 | ->expects($this->once()) | |
235 | ->method('onPostUninstall'); | |
9099cab3 | 236 | $manager->uninstall(['test.foo.bar']); |
6a488035 TO |
237 | $this->assertEquals('unknown', $manager->getStatus('test.foo.bar')); |
238 | } | |
239 | ||
240 | /** | |
eceb18cc | 241 | * Install an extension with a valid type name. |
6a488035 | 242 | */ |
00be9182 | 243 | public function testInstall_Disable_Enable() { |
ad42f150 | 244 | $testingTypeManager = $this->getMockBuilder('CRM_Extension_Manager_Interface')->getMock(); |
9099cab3 | 245 | $manager = $this->_createManager([ |
6a488035 | 246 | self::TESTING_TYPE => $testingTypeManager, |
9099cab3 | 247 | ]); |
6a488035 TO |
248 | $this->assertEquals('uninstalled', $manager->getStatus('test.foo.bar')); |
249 | $this->assertEquals('uninstalled', $manager->getStatus('test.whiz.bang')); | |
250 | ||
251 | $testingTypeManager | |
252 | ->expects($this->exactly(2)) | |
253 | ->method('onPreInstall'); | |
254 | $testingTypeManager | |
255 | ->expects($this->exactly(2)) | |
256 | ->method('onPostInstall'); | |
9099cab3 | 257 | $manager->install(['test.whiz.bang', 'test.foo.bar']); |
6a488035 TO |
258 | $this->assertEquals('installed', $manager->getStatus('test.foo.bar')); |
259 | $this->assertEquals('installed', $manager->getStatus('test.whiz.bang')); | |
260 | ||
261 | $testingTypeManager | |
262 | ->expects($this->once()) | |
263 | ->method('onPreDisable'); | |
264 | $testingTypeManager | |
265 | ->expects($this->once()) | |
266 | ->method('onPostDisable'); | |
9099cab3 | 267 | $manager->disable(['test.foo.bar']); |
6a488035 TO |
268 | $this->assertEquals('disabled', $manager->getStatus('test.foo.bar')); |
269 | $this->assertEquals('installed', $manager->getStatus('test.whiz.bang')); | |
270 | ||
271 | $testingTypeManager | |
272 | ->expects($this->once()) | |
273 | ->method('onPreEnable'); | |
274 | $testingTypeManager | |
275 | ->expects($this->once()) | |
276 | ->method('onPostEnable'); | |
9099cab3 | 277 | $manager->enable(['test.foo.bar']); |
6a488035 TO |
278 | $this->assertEquals('installed', $manager->getStatus('test.foo.bar')); |
279 | $this->assertEquals('installed', $manager->getStatus('test.whiz.bang')); | |
280 | } | |
281 | ||
282 | /** | |
283 | * Performing 'install' on a 'disabled' extension performs an 'enable' | |
284 | */ | |
00be9182 | 285 | public function testInstall_Disable_Install() { |
ad42f150 | 286 | $testingTypeManager = $this->getMockBuilder('CRM_Extension_Manager_Interface')->getMock(); |
9099cab3 | 287 | $manager = $this->_createManager([ |
6a488035 | 288 | self::TESTING_TYPE => $testingTypeManager, |
9099cab3 | 289 | ]); |
6a488035 TO |
290 | $this->assertEquals('uninstalled', $manager->getStatus('test.foo.bar')); |
291 | ||
292 | $testingTypeManager | |
293 | ->expects($this->once()) | |
294 | ->method('onPreInstall'); | |
295 | $testingTypeManager | |
296 | ->expects($this->once()) | |
297 | ->method('onPostInstall'); | |
9099cab3 | 298 | $manager->install(['test.foo.bar']); |
6a488035 TO |
299 | $this->assertEquals('installed', $manager->getStatus('test.foo.bar')); |
300 | ||
301 | $testingTypeManager | |
302 | ->expects($this->once()) | |
303 | ->method('onPreDisable'); | |
304 | $testingTypeManager | |
305 | ->expects($this->once()) | |
306 | ->method('onPostDisable'); | |
9099cab3 | 307 | $manager->disable(['test.foo.bar']); |
6a488035 TO |
308 | $this->assertEquals('disabled', $manager->getStatus('test.foo.bar')); |
309 | ||
310 | $testingTypeManager | |
311 | ->expects($this->once()) | |
312 | ->method('onPreEnable'); | |
313 | $testingTypeManager | |
314 | ->expects($this->once()) | |
315 | ->method('onPostEnable'); | |
39b959db | 316 | // install() instead of enable() |
9099cab3 | 317 | $manager->install(['test.foo.bar']); |
6a488035 TO |
318 | $this->assertEquals('installed', $manager->getStatus('test.foo.bar')); |
319 | } | |
320 | ||
321 | /** | |
eceb18cc | 322 | * Install an extension with a valid type name. |
6a488035 | 323 | */ |
00be9182 | 324 | public function testEnableBare() { |
ad42f150 | 325 | $testingTypeManager = $this->getMockBuilder('CRM_Extension_Manager_Interface')->getMock(); |
9099cab3 | 326 | $manager = $this->_createManager([ |
6a488035 | 327 | self::TESTING_TYPE => $testingTypeManager, |
9099cab3 | 328 | ]); |
6a488035 TO |
329 | $this->assertEquals('uninstalled', $manager->getStatus('test.foo.bar')); |
330 | ||
331 | $testingTypeManager | |
332 | ->expects($this->once()) | |
333 | ->method('onPreInstall'); | |
334 | $testingTypeManager | |
335 | ->expects($this->once()) | |
336 | ->method('onPostInstall'); | |
337 | $testingTypeManager | |
338 | ->expects($this->never()) | |
339 | ->method('onPreEnable'); | |
340 | $testingTypeManager | |
341 | ->expects($this->never()) | |
342 | ->method('onPostEnable'); | |
39b959db | 343 | // enable not install |
9099cab3 | 344 | $manager->enable(['test.foo.bar']); |
6a488035 TO |
345 | $this->assertEquals('installed', $manager->getStatus('test.foo.bar')); |
346 | } | |
347 | ||
348 | /** | |
eceb18cc | 349 | * Get the status of an unknown extension. |
6a488035 | 350 | */ |
00be9182 | 351 | public function testStatusUnknownKey() { |
ad42f150 | 352 | $testingTypeManager = $this->getMockBuilder('CRM_Extension_Manager_Interface')->getMock(); |
6a488035 TO |
353 | $testingTypeManager->expects($this->never()) |
354 | ->method('onPreInstall'); | |
9099cab3 | 355 | $manager = $this->_createManager([ |
6a488035 | 356 | self::TESTING_TYPE => $testingTypeManager, |
9099cab3 | 357 | ]); |
6a488035 TO |
358 | $this->assertEquals('unknown', $manager->getStatus('test.foo.bar.whiz.bang')); |
359 | } | |
360 | ||
361 | /** | |
362 | * Replace code for an extension that doesn't exist in the container | |
363 | */ | |
00be9182 | 364 | public function testReplace_Unknown() { |
ad42f150 | 365 | $testingTypeManager = $this->getMockBuilder('CRM_Extension_Manager_Interface')->getMock(); |
9099cab3 | 366 | $manager = $this->_createManager([ |
6a488035 | 367 | self::TESTING_TYPE => $testingTypeManager, |
9099cab3 | 368 | ]); |
6a488035 TO |
369 | $this->assertEquals('unknown', $manager->getStatus('test.newextension')); |
370 | ||
371 | $this->download = $this->_createDownload('test.newextension', 'newextension'); | |
372 | ||
373 | $testingTypeManager | |
39b959db SL |
374 | // no data to replace |
375 | ->expects($this->never()) | |
6a488035 TO |
376 | ->method('onPreReplace'); |
377 | $testingTypeManager | |
39b959db SL |
378 | // no data to replace |
379 | ->expects($this->never()) | |
6a488035 TO |
380 | ->method('onPostReplace'); |
381 | $manager->replace($this->download); | |
382 | $this->assertEquals('uninstalled', $manager->getStatus('test.newextension')); | |
383 | $this->assertTrue(file_exists("{$this->basedir}/test.newextension/info.xml")); | |
384 | $this->assertTrue(file_exists("{$this->basedir}/test.newextension/newextension.php")); | |
385 | $this->assertEquals(self::TESTING_TYPE, $this->mapper->keyToInfo('test.newextension')->type); | |
386 | $this->assertEquals('newextension', $this->mapper->keyToInfo('test.newextension')->file); | |
387 | } | |
388 | ||
389 | /** | |
390 | * Replace code for an extension that doesn't exist in the container | |
391 | */ | |
00be9182 | 392 | public function testReplace_Uninstalled() { |
ad42f150 | 393 | $testingTypeManager = $this->getMockBuilder('CRM_Extension_Manager_Interface')->getMock(); |
9099cab3 | 394 | $manager = $this->_createManager([ |
6a488035 | 395 | self::TESTING_TYPE => $testingTypeManager, |
9099cab3 | 396 | ]); |
6a488035 TO |
397 | $this->assertEquals('uninstalled', $manager->getStatus('test.whiz.bang')); |
398 | $this->assertEquals('oddball', $this->mapper->keyToInfo('test.whiz.bang')->file); | |
399 | ||
400 | $this->download = $this->_createDownload('test.whiz.bang', 'newextension'); | |
401 | ||
402 | $testingTypeManager | |
39b959db SL |
403 | // no data to replace |
404 | ->expects($this->never()) | |
6a488035 TO |
405 | ->method('onPreReplace'); |
406 | $testingTypeManager | |
39b959db SL |
407 | // no data to replace |
408 | ->expects($this->never()) | |
6a488035 TO |
409 | ->method('onPostReplace'); |
410 | $manager->replace($this->download); | |
411 | $this->assertEquals('uninstalled', $manager->getStatus('test.whiz.bang')); | |
412 | $this->assertTrue(file_exists("{$this->basedir}/weird/whizbang/info.xml")); | |
413 | $this->assertTrue(file_exists("{$this->basedir}/weird/whizbang/newextension.php")); | |
414 | $this->assertFalse(file_exists("{$this->basedir}/weird/whizbang/oddball.php")); | |
415 | $this->assertEquals(self::TESTING_TYPE, $this->mapper->keyToInfo('test.whiz.bang')->type); | |
416 | $this->assertEquals('newextension', $this->mapper->keyToInfo('test.whiz.bang')->file); | |
417 | } | |
418 | ||
419 | /** | |
eceb18cc | 420 | * Install a module and then replace it with new code. |
6a488035 TO |
421 | * |
422 | * Note that some metadata changes between versions -- the original has | |
423 | * file="oddball", and the upgrade has file="newextension". | |
424 | */ | |
00be9182 | 425 | public function testReplace_Installed() { |
ad42f150 | 426 | $testingTypeManager = $this->getMockBuilder('CRM_Extension_Manager_Interface')->getMock(); |
9099cab3 | 427 | $manager = $this->_createManager([ |
6a488035 | 428 | self::TESTING_TYPE => $testingTypeManager, |
9099cab3 | 429 | ]); |
6a488035 TO |
430 | $this->assertEquals('uninstalled', $manager->getStatus('test.whiz.bang')); |
431 | $this->assertEquals('oddball', $this->mapper->keyToInfo('test.whiz.bang')->file); | |
432 | ||
9099cab3 | 433 | $manager->install(['test.whiz.bang']); |
6a488035 TO |
434 | $this->assertEquals('installed', $manager->getStatus('test.whiz.bang')); |
435 | $this->assertEquals('oddball', $this->mapper->keyToInfo('test.whiz.bang')->file); | |
436 | $this->assertDBQuery('oddball', 'SELECT file FROM civicrm_extension WHERE full_name ="test.whiz.bang"'); | |
437 | ||
438 | $this->download = $this->_createDownload('test.whiz.bang', 'newextension'); | |
439 | ||
440 | $testingTypeManager | |
441 | ->expects($this->once()) | |
442 | ->method('onPreReplace'); | |
443 | $testingTypeManager | |
444 | ->expects($this->once()) | |
445 | ->method('onPostReplace'); | |
446 | $manager->replace($this->download); | |
447 | $this->assertEquals('installed', $manager->getStatus('test.whiz.bang')); | |
448 | $this->assertTrue(file_exists("{$this->basedir}/weird/whizbang/info.xml")); | |
449 | $this->assertTrue(file_exists("{$this->basedir}/weird/whizbang/newextension.php")); | |
450 | $this->assertFalse(file_exists("{$this->basedir}/weird/whizbang/oddball.php")); | |
451 | $this->assertEquals('newextension', $this->mapper->keyToInfo('test.whiz.bang')->file); | |
452 | $this->assertDBQuery('newextension', 'SELECT file FROM civicrm_extension WHERE full_name ="test.whiz.bang"'); | |
453 | } | |
454 | ||
455 | /** | |
456 | * Install a module and then delete (leaving stale DB info); restore | |
457 | * the module by downloading new code. | |
458 | * | |
459 | * Note that some metadata changes between versions -- the original has | |
460 | * file="oddball", and the upgrade has file="newextension". | |
461 | */ | |
00be9182 | 462 | public function testReplace_InstalledMissing() { |
ad42f150 | 463 | $testingTypeManager = $this->getMockBuilder('CRM_Extension_Manager_Interface')->getMock(); |
9099cab3 | 464 | $manager = $this->_createManager([ |
6a488035 | 465 | self::TESTING_TYPE => $testingTypeManager, |
9099cab3 | 466 | ]); |
b6708aeb | 467 | |
6a488035 TO |
468 | // initial installation |
469 | $this->assertEquals('uninstalled', $manager->getStatus('test.whiz.bang')); | |
9099cab3 | 470 | $manager->install(['test.whiz.bang']); |
6a488035 TO |
471 | $this->assertEquals('installed', $manager->getStatus('test.whiz.bang')); |
472 | ||
473 | // dirty remove | |
474 | $this->assertTrue(file_exists("{$this->basedir}/weird/whizbang/info.xml")); | |
475 | CRM_Utils_File::cleanDir("{$this->basedir}/weird/whizbang", TRUE, FALSE); | |
476 | $this->assertFalse(file_exists("{$this->basedir}/weird/whizbang/info.xml")); | |
477 | $manager->refresh(); | |
478 | $this->assertEquals('installed-missing', $manager->getStatus('test.whiz.bang')); | |
479 | ||
480 | // download and reinstall | |
481 | $this->download = $this->_createDownload('test.whiz.bang', 'newextension'); | |
482 | ||
483 | $testingTypeManager | |
484 | ->expects($this->once()) | |
485 | ->method('onPreReplace'); | |
486 | $testingTypeManager | |
487 | ->expects($this->once()) | |
488 | ->method('onPostReplace'); | |
489 | $manager->replace($this->download); | |
490 | $this->assertEquals('installed', $manager->getStatus('test.whiz.bang')); | |
491 | $this->assertTrue(file_exists("{$this->basedir}/test.whiz.bang/info.xml")); | |
492 | $this->assertTrue(file_exists("{$this->basedir}/test.whiz.bang/newextension.php")); | |
493 | $this->assertEquals('newextension', $this->mapper->keyToInfo('test.whiz.bang')->file); | |
494 | $this->assertDBQuery('newextension', 'SELECT file FROM civicrm_extension WHERE full_name ="test.whiz.bang"'); | |
495 | } | |
496 | ||
4cbe18b8 EM |
497 | /** |
498 | * @param $typeManagers | |
499 | * | |
500 | * @return CRM_Extension_Manager | |
501 | */ | |
00be9182 | 502 | public function _createManager($typeManagers) { |
6a488035 TO |
503 | //list ($basedir, $c) = $this->_createContainer(); |
504 | $mapper = new CRM_Extension_Mapper($this->container); | |
505 | return new CRM_Extension_Manager($this->container, $this->container, $this->mapper, $typeManagers); | |
506 | } | |
507 | ||
4cbe18b8 EM |
508 | /** |
509 | * @param CRM_Utils_Cache_Interface $cache | |
510 | * @param null $cacheKey | |
511 | * | |
512 | * @return array | |
513 | */ | |
00be9182 | 514 | public function _createContainer(CRM_Utils_Cache_Interface $cache = NULL, $cacheKey = NULL) { |
6a488035 TO |
515 | $basedir = $this->createTempDir('ext-'); |
516 | mkdir("$basedir/weird"); | |
517 | mkdir("$basedir/weird/foobar"); | |
92fcb95f | 518 | file_put_contents("$basedir/weird/foobar/info.xml", "<extension key='test.foo.bar' type='" . self::TESTING_TYPE . "'><file>oddball</file></extension>"); |
6a488035 TO |
519 | // not needed for now // file_put_contents("$basedir/weird/bar/oddball.php", "<?php\n"); |
520 | mkdir("$basedir/weird/whizbang"); | |
92fcb95f | 521 | file_put_contents("$basedir/weird/whizbang/info.xml", "<extension key='test.whiz.bang' type='" . self::TESTING_TYPE . "'><file>oddball</file></extension>"); |
6a488035 | 522 | // not needed for now // file_put_contents("$basedir/weird/whizbang/oddball.php", "<?php\n"); |
f8a7cfff TO |
523 | mkdir("$basedir/weird/downstream"); |
524 | file_put_contents("$basedir/weird/downstream/info.xml", "<extension key='test.foo.downstream' type='" . self::TESTING_TYPE . "'><file>oddball</file><requires><ext>test.foo.bar</ext></requires></extension>"); | |
525 | // not needed for now // file_put_contents("$basedir/weird/downstream/oddball.php", "<?php\n"); | |
6a488035 | 526 | $c = new CRM_Extension_Container_Basic($basedir, 'http://example/basedir', $cache, $cacheKey); |
9099cab3 | 527 | return [$basedir, $c]; |
6a488035 TO |
528 | } |
529 | ||
4cbe18b8 EM |
530 | /** |
531 | * @param $key | |
532 | * @param $file | |
533 | * | |
534 | * @return string | |
535 | */ | |
00be9182 | 536 | public function _createDownload($key, $file) { |
6a488035 | 537 | $basedir = $this->createTempDir('ext-dl-'); |
92fcb95f | 538 | file_put_contents("$basedir/info.xml", "<extension key='$key' type='" . self::TESTING_TYPE . "'><file>$file</file></extension>"); |
6a488035 TO |
539 | file_put_contents("$basedir/$file.php", "<?php\n"); |
540 | return $basedir; | |
541 | } | |
96025800 | 542 | |
6a488035 | 543 | } |