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