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