4 * Class CRM_Extension_Manager_ModuleTest
7 class CRM_Extension_Manager_ModuleTest
extends CiviUnitTestCase
{
9 public function setUp() {
11 // $query = "INSERT INTO civicrm_domain ( name, version ) VALUES ( 'domain', 3 )";
12 // $result = CRM_Core_DAO::executeQuery($query);
13 global $_test_extension_manager_moduletest_counts;
14 $_test_extension_manager_moduletest_counts = [];
15 $this->basedir
= $this->createTempDir('ext-');
16 $this->system
= new CRM_Extension_System([
17 'extensionsDir' => $this->basedir
,
18 'extensionsURL' => 'http://testbase/',
20 $this->setExtensionSystem($this->system
);
23 public function tearDown() {
29 * Install an extension with a valid type name.
31 public function testInstallDisableUninstall() {
32 $manager = $this->system
->getManager();
33 $this->assertModuleActiveByName(FALSE, 'moduletest');
35 $manager->install(['test.extension.manager.moduletest']);
36 $this->assertHookCounts('moduletest', [
43 $this->assertModuleActiveByName(TRUE, 'moduletest');
44 $this->assertModuleActiveByKey(TRUE, 'test.extension.manager.moduletest');
46 $manager->disable(['test.extension.manager.moduletest']);
47 $this->assertHookCounts('moduletest', [
54 $this->assertModuleActiveByName(FALSE, 'moduletest');
55 $this->assertModuleActiveByKey(FALSE, 'test.extension.manager.moduletest');
57 $manager->uninstall(['test.extension.manager.moduletest']);
58 $this->assertHookCounts('moduletest', [
65 $this->assertModuleActiveByName(FALSE, 'moduletest');
66 $this->assertModuleActiveByKey(FALSE, 'test.extension.manager.moduletest');
70 * Install an extension with a valid type name.
72 public function testInstallDisableEnable() {
73 $manager = $this->system
->getManager();
74 $this->assertModuleActiveByName(FALSE, 'moduletest');
75 $this->assertModuleActiveByKey(FALSE, 'test.extension.manager.moduletest');
77 $manager->install(['test.extension.manager.moduletest']);
78 $this->assertHookCounts('moduletest', [
84 $this->assertModuleActiveByName(TRUE, 'moduletest');
85 $this->assertModuleActiveByKey(TRUE, 'test.extension.manager.moduletest');
87 $manager->disable(['test.extension.manager.moduletest']);
88 $this->assertHookCounts('moduletest', [
94 $this->assertModuleActiveByName(FALSE, 'moduletest');
95 $this->assertModuleActiveByKey(FALSE, 'test.extension.manager.moduletest');
97 $manager->enable(['test.extension.manager.moduletest']);
98 $this->assertHookCounts('moduletest', [
104 $this->assertModuleActiveByName(TRUE, 'moduletest');
105 $this->assertModuleActiveByKey(TRUE, 'test.extension.manager.moduletest');
109 * Install an extension then forcibly remove the code and cleanup DB afterwards.
111 public function testInstall_DirtyRemove_Disable_Uninstall() {
112 // create temporary extension (which can dirtily remove later)
113 $this->_createExtension('test.extension.manager.module.auto1', 'module', 'test_extension_manager_module_auto1');
114 $mainfile = $this->basedir
. '/test.extension.manager.module.auto1/test_extension_manager_module_auto1.php';
115 $this->assertTrue(file_exists($mainfile));
116 $manager = $this->system
->getManager();
117 $this->assertModuleActiveByName(FALSE, 'test_extension_manager_module_auto1');
118 $this->assertModuleActiveByKey(FALSE, 'test.extension.manager.module.auto1');
121 $manager->install(['test.extension.manager.module.auto1']);
122 $this->assertEquals('installed', $manager->getStatus('test.extension.manager.module.auto1'));
123 $this->assertHookCounts('test_extension_manager_module_auto1', [
129 $this->assertModuleActiveByName(TRUE, 'test_extension_manager_module_auto1');
130 $this->assertModuleActiveByKey(TRUE, 'test.extension.manager.module.auto1');
133 CRM_Utils_File
::cleanDir($this->basedir
. '/test.extension.manager.module.auto1', TRUE, FALSE);
135 $this->assertEquals('installed-missing', $manager->getStatus('test.extension.manager.module.auto1'));
137 // disable while missing
138 $manager->disable(['test.extension.manager.module.auto1']);
139 $this->assertEquals('disabled-missing', $manager->getStatus('test.extension.manager.module.auto1'));
140 $this->assertHookCounts('test_extension_manager_module_auto1', [
143 // normally called -- but not for missing modules!
147 $this->assertModuleActiveByName(FALSE, 'test_extension_manager_module_auto1');
148 $this->assertModuleActiveByKey(FALSE, 'test.extension.manager.moduletest');
150 $manager->uninstall(['test.extension.manager.module.auto1']);
151 $this->assertHookCounts('test_extension_manager_module_auto1', [
154 // normally called -- but not for missing modules!
156 // normally called -- but not for missing modules!
159 $this->assertEquals('unknown', $manager->getStatus('test.extension.manager.module.auto1'));
160 $this->assertModuleActiveByName(FALSE, 'test_extension_manager_module_auto1');
161 $this->assertModuleActiveByKey(FALSE, 'test.extension.manager.module.auto1');
165 * Install an extension then forcibly remove the code and cleanup DB afterwards.
167 public function testInstall_DirtyRemove_Disable_Restore() {
168 // create temporary extension (which can dirtily remove later)
169 $this->_createExtension('test.extension.manager.module.auto2', 'module', 'test_extension_manager_module_auto2');
170 $mainfile = $this->basedir
. '/test.extension.manager.module.auto2/test_extension_manager_module_auto2.php';
171 $this->assertTrue(file_exists($mainfile));
172 $manager = $this->system
->getManager();
173 $this->assertModuleActiveByName(FALSE, 'test_extension_manager_module_auto2');
174 $this->assertModuleActiveByKey(FALSE, 'test.extension.manager.module.auto2');
177 $manager->install(['test.extension.manager.module.auto2']);
178 $this->assertEquals('installed', $manager->getStatus('test.extension.manager.module.auto2'));
179 $this->assertHookCounts('test_extension_manager_module_auto2', [
185 $this->assertModuleActiveByName(TRUE, 'test_extension_manager_module_auto2');
186 $this->assertModuleActiveByKey(TRUE, 'test.extension.manager.module.auto2');
189 CRM_Utils_File
::cleanDir($this->basedir
. '/test.extension.manager.module.auto2', TRUE, FALSE);
191 $this->assertEquals('installed-missing', $manager->getStatus('test.extension.manager.module.auto2'));
193 // disable while missing
194 $manager->disable(['test.extension.manager.module.auto2']);
195 $this->assertEquals('disabled-missing', $manager->getStatus('test.extension.manager.module.auto2'));
196 $this->assertHookCounts('test_extension_manager_module_auto2', [
199 // normally called -- but not for missing modules!
203 $this->assertModuleActiveByName(FALSE, 'test_extension_manager_module_auto2');
204 $this->assertModuleActiveByKey(FALSE, 'test.extension.manager.moduletest');
207 $this->_createExtension('test.extension.manager.module.auto2', 'module', 'test_extension_manager_module_auto2');
209 $this->assertHookCounts('test_extension_manager_module_auto2', [
215 $this->assertEquals('disabled', $manager->getStatus('test.extension.manager.module.auto2'));
216 $this->assertModuleActiveByName(FALSE, 'test_extension_manager_module_auto2');
217 $this->assertModuleActiveByKey(FALSE, 'test.extension.manager.module.auto2');
222 * @param array $counts
223 * Expected hook invocation counts ($hookName => $count).
225 public function assertHookCounts($module, $counts) {
226 global $_test_extension_manager_moduletest_counts;
227 foreach ($counts as $key => $expected) {
228 $actual = @$_test_extension_manager_moduletest_counts[$module][$key];
229 $this->assertEquals($expected, $actual,
230 sprintf('Expected %d call(s) to hook_civicrm_%s -- found %d', $expected, $key, $actual)
236 * @param $expectedIsActive
239 public function assertModuleActiveByName($expectedIsActive, $prefix) {
241 $activeModules = CRM_Core_PseudoConstant
::getModuleExtensions(TRUE);
242 foreach ($activeModules as $activeModule) {
243 if ($activeModule['prefix'] == $prefix) {
244 $this->assertEquals($expectedIsActive, TRUE);
248 $this->assertEquals($expectedIsActive, FALSE);
252 * @param $expectedIsActive
255 public function assertModuleActiveByKey($expectedIsActive, $key) {
256 foreach (CRM_Core_Module
::getAll() as $module) {
257 if ($module->name
== $key) {
258 $this->assertEquals((bool) $expectedIsActive, (bool) $module->is_active
);
262 $this->assertEquals($expectedIsActive, FALSE);
269 * @param string $template
271 public function _createExtension($key, $type, $file, $template = self
::MODULE_TEMPLATE
) {
272 $basedir = $this->basedir
;
273 mkdir("$basedir/$key");
274 file_put_contents("$basedir/$key/info.xml", "<extension key='$key' type='$type'><file>$file</file></extension>");
275 file_put_contents("$basedir/$key/$file.php", strtr($template, ['_FILE_' => $file]));
276 $this->system
->getCache()->flush();
277 $this->system
->getManager()->refresh();
282 * @param string $name
284 public static function incHookCount($module, $name) {
285 global $_test_extension_manager_moduletest_counts;
286 if (!isset($_test_extension_manager_moduletest_counts[$module][$name])) {
287 $_test_extension_manager_moduletest_counts[$module][$name] = 0;
289 $_test_extension_manager_moduletest_counts[$module][$name] = 1 +
(int) $_test_extension_manager_moduletest_counts[$module][$name];
292 const MODULE_TEMPLATE
= "<?php
293 function _FILE__civicrm_install() {
294 CRM_Extension_Manager_ModuleTest::incHookCount('_FILE_', 'install');
297 function _FILE__civicrm_postInstall() {
298 CRM_Extension_Manager_ModuleTest::incHookCount('_FILE_', 'postInstall');
301 function _FILE__civicrm_uninstall() {
302 CRM_Extension_Manager_ModuleTest::incHookCount('_FILE_', 'uninstall');
305 function _FILE__civicrm_enable() {
306 CRM_Extension_Manager_ModuleTest::incHookCount('_FILE_', 'enable');
309 function _FILE__civicrm_disable() {
310 CRM_Extension_Manager_ModuleTest::incHookCount('_FILE_', 'disable');