Merge remote-tracking branch 'upstream/4.6' into 4.6-master-2015-10-14-11-04-09
[civicrm-core.git] / tests / phpunit / CRM / Extension / Manager / ModuleTest.php
1 <?php
2
3 require_once 'CiviTest/CiviUnitTestCase.php';
4
5 /**
6 * Class CRM_Extension_Manager_ModuleTest
7 */
8 class CRM_Extension_Manager_ModuleTest extends CiviUnitTestCase {
9
10 public function setUp() {
11 parent::setUp();
12 // $query = "INSERT INTO civicrm_domain ( name, version ) VALUES ( 'domain', 3 )";
13 // $result = CRM_Core_DAO::executeQuery($query);
14 global $_test_extension_manager_moduletest_counts;
15 $_test_extension_manager_moduletest_counts = array();
16 $this->basedir = $this->createTempDir('ext-');
17 $this->system = new CRM_Extension_System(array(
18 'extensionsDir' => $this->basedir,
19 'extensionsURL' => 'http://testbase/',
20 ));
21 $this->setExtensionSystem($this->system);
22 }
23
24 public function tearDown() {
25 parent::tearDown();
26 $this->system = NULL;
27 }
28
29 /**
30 * Install an extension with a valid type name.
31 */
32 public function testInstallDisableUninstall() {
33 $manager = $this->system->getManager();
34 $this->assertModuleActiveByName(FALSE, 'moduletest');
35
36 $manager->install(array('test.extension.manager.moduletest'));
37 $this->assertHookCounts('moduletest', array(
38 'install' => 1,
39 'postInstall' => 1,
40 'enable' => 1,
41 'disable' => 0,
42 'uninstall' => 0,
43 ));
44 $this->assertModuleActiveByName(TRUE, 'moduletest');
45 $this->assertModuleActiveByKey(TRUE, 'test.extension.manager.moduletest');
46
47 $manager->disable(array('test.extension.manager.moduletest'));
48 $this->assertHookCounts('moduletest', array(
49 'install' => 1,
50 'postInstall' => 1,
51 'enable' => 1,
52 'disable' => 1,
53 'uninstall' => 0,
54 ));
55 $this->assertModuleActiveByName(FALSE, 'moduletest');
56 $this->assertModuleActiveByKey(FALSE, 'test.extension.manager.moduletest');
57
58 $manager->uninstall(array('test.extension.manager.moduletest'));
59 $this->assertHookCounts('moduletest', array(
60 'install' => 1,
61 'postInstall' => 1,
62 'enable' => 1,
63 'disable' => 1,
64 'uninstall' => 1,
65 ));
66 $this->assertModuleActiveByName(FALSE, 'moduletest');
67 $this->assertModuleActiveByKey(FALSE, 'test.extension.manager.moduletest');
68 }
69
70 /**
71 * Install an extension with a valid type name.
72 */
73 public function testInstallDisableEnable() {
74 $manager = $this->system->getManager();
75 $this->assertModuleActiveByName(FALSE, 'moduletest');
76 $this->assertModuleActiveByKey(FALSE, 'test.extension.manager.moduletest');
77
78 $manager->install(array('test.extension.manager.moduletest'));
79 $this->assertHookCounts('moduletest', array(
80 'install' => 1,
81 'enable' => 1,
82 'disable' => 0,
83 'uninstall' => 0,
84 ));
85 $this->assertModuleActiveByName(TRUE, 'moduletest');
86 $this->assertModuleActiveByKey(TRUE, 'test.extension.manager.moduletest');
87
88 $manager->disable(array('test.extension.manager.moduletest'));
89 $this->assertHookCounts('moduletest', array(
90 'install' => 1,
91 'enable' => 1,
92 'disable' => 1,
93 'uninstall' => 0,
94 ));
95 $this->assertModuleActiveByName(FALSE, 'moduletest');
96 $this->assertModuleActiveByKey(FALSE, 'test.extension.manager.moduletest');
97
98 $manager->enable(array('test.extension.manager.moduletest'));
99 $this->assertHookCounts('moduletest', array(
100 'install' => 1,
101 'enable' => 2,
102 'disable' => 1,
103 'uninstall' => 0,
104 ));
105 $this->assertModuleActiveByName(TRUE, 'moduletest');
106 $this->assertModuleActiveByKey(TRUE, 'test.extension.manager.moduletest');
107 }
108
109 /**
110 * Install an extension then forcibly remove the code and cleanup DB afterwards.
111 */
112 public function testInstall_DirtyRemove_Disable_Uninstall() {
113 // create temporary extension (which can dirtily remove later)
114 $this->_createExtension('test.extension.manager.module.auto1', 'module', 'test_extension_manager_module_auto1');
115 $mainfile = $this->basedir . '/test.extension.manager.module.auto1/test_extension_manager_module_auto1.php';
116 $this->assertTrue(file_exists($mainfile));
117 $manager = $this->system->getManager();
118 $this->assertModuleActiveByName(FALSE, 'test_extension_manager_module_auto1');
119 $this->assertModuleActiveByKey(FALSE, 'test.extension.manager.module.auto1');
120
121 // install it
122 $manager->install(array('test.extension.manager.module.auto1'));
123 $this->assertEquals('installed', $manager->getStatus('test.extension.manager.module.auto1'));
124 $this->assertHookCounts('test_extension_manager_module_auto1', array(
125 'install' => 1,
126 'enable' => 1,
127 'disable' => 0,
128 'uninstall' => 0,
129 ));
130 $this->assertModuleActiveByName(TRUE, 'test_extension_manager_module_auto1');
131 $this->assertModuleActiveByKey(TRUE, 'test.extension.manager.module.auto1');
132
133 // dirty removal
134 CRM_Utils_File::cleanDir($this->basedir . '/test.extension.manager.module.auto1', TRUE, FALSE);
135 $manager->refresh();
136 $this->assertEquals('installed-missing', $manager->getStatus('test.extension.manager.module.auto1'));
137
138 // disable while missing
139 $manager->disable(array('test.extension.manager.module.auto1'));
140 $this->assertEquals('disabled-missing', $manager->getStatus('test.extension.manager.module.auto1'));
141 $this->assertHookCounts('test_extension_manager_module_auto1', array(
142 'install' => 1,
143 'enable' => 1,
144 'disable' => 0, // normally called -- but not for missing modules!
145 'uninstall' => 0,
146 ));
147 $this->assertModuleActiveByName(FALSE, 'test_extension_manager_module_auto1');
148 $this->assertModuleActiveByKey(FALSE, 'test.extension.manager.moduletest');
149
150 $manager->uninstall(array('test.extension.manager.module.auto1'));
151 $this->assertHookCounts('test_extension_manager_module_auto1', array(
152 'install' => 1,
153 'enable' => 1,
154 'disable' => 0, // normally called -- but not for missing modules!
155 'uninstall' => 0, // normally called -- but not for missing modules!
156 ));
157 $this->assertEquals('unknown', $manager->getStatus('test.extension.manager.module.auto1'));
158 $this->assertModuleActiveByName(FALSE, 'test_extension_manager_module_auto1');
159 $this->assertModuleActiveByKey(FALSE, 'test.extension.manager.module.auto1');
160 }
161
162 /**
163 * Install an extension then forcibly remove the code and cleanup DB afterwards.
164 */
165 public function testInstall_DirtyRemove_Disable_Restore() {
166 // create temporary extension (which can dirtily remove later)
167 $this->_createExtension('test.extension.manager.module.auto2', 'module', 'test_extension_manager_module_auto2');
168 $mainfile = $this->basedir . '/test.extension.manager.module.auto2/test_extension_manager_module_auto2.php';
169 $this->assertTrue(file_exists($mainfile));
170 $manager = $this->system->getManager();
171 $this->assertModuleActiveByName(FALSE, 'test_extension_manager_module_auto2');
172 $this->assertModuleActiveByKey(FALSE, 'test.extension.manager.module.auto2');
173
174 // install it
175 $manager->install(array('test.extension.manager.module.auto2'));
176 $this->assertEquals('installed', $manager->getStatus('test.extension.manager.module.auto2'));
177 $this->assertHookCounts('test_extension_manager_module_auto2', array(
178 'install' => 1,
179 'enable' => 1,
180 'disable' => 0,
181 'uninstall' => 0,
182 ));
183 $this->assertModuleActiveByName(TRUE, 'test_extension_manager_module_auto2');
184 $this->assertModuleActiveByKey(TRUE, 'test.extension.manager.module.auto2');
185
186 // dirty removal
187 CRM_Utils_File::cleanDir($this->basedir . '/test.extension.manager.module.auto2', TRUE, FALSE);
188 $manager->refresh();
189 $this->assertEquals('installed-missing', $manager->getStatus('test.extension.manager.module.auto2'));
190
191 // disable while missing
192 $manager->disable(array('test.extension.manager.module.auto2'));
193 $this->assertEquals('disabled-missing', $manager->getStatus('test.extension.manager.module.auto2'));
194 $this->assertHookCounts('test_extension_manager_module_auto2', array(
195 'install' => 1,
196 'enable' => 1,
197 'disable' => 0, // normally called -- but not for missing modules!
198 'uninstall' => 0,
199 ));
200 $this->assertModuleActiveByName(FALSE, 'test_extension_manager_module_auto2');
201 $this->assertModuleActiveByKey(FALSE, 'test.extension.manager.moduletest');
202
203 // restore the code
204 $this->_createExtension('test.extension.manager.module.auto2', 'module', 'test_extension_manager_module_auto2');
205 $manager->refresh();
206 $this->assertHookCounts('test_extension_manager_module_auto2', array(
207 'install' => 1,
208 'enable' => 1,
209 'disable' => 0,
210 'uninstall' => 0,
211 ));
212 $this->assertEquals('disabled', $manager->getStatus('test.extension.manager.module.auto2'));
213 $this->assertModuleActiveByName(FALSE, 'test_extension_manager_module_auto2');
214 $this->assertModuleActiveByKey(FALSE, 'test.extension.manager.module.auto2');
215 }
216
217 /**
218 * @param $module
219 * @param array $counts
220 * Expected hook invocation counts ($hookName => $count).
221 */
222 public function assertHookCounts($module, $counts) {
223 global $_test_extension_manager_moduletest_counts;
224 foreach ($counts as $key => $expected) {
225 $actual = @$_test_extension_manager_moduletest_counts[$module][$key];
226 $this->assertEquals($expected, $actual,
227 sprintf('Expected %d call(s) to hook_civicrm_%s -- found %d', $expected, $key, $actual)
228 );
229 }
230 }
231
232 /**
233 * @param $expectedIsActive
234 * @param $prefix
235 */
236 public function assertModuleActiveByName($expectedIsActive, $prefix) {
237 $activeModules = CRM_Core_PseudoConstant::getModuleExtensions(TRUE); // FIXME
238 foreach ($activeModules as $activeModule) {
239 if ($activeModule['prefix'] == $prefix) {
240 $this->assertEquals($expectedIsActive, TRUE);
241 return;
242 }
243 }
244 $this->assertEquals($expectedIsActive, FALSE);
245 }
246
247 /**
248 * @param $expectedIsActive
249 * @param $key
250 */
251 public function assertModuleActiveByKey($expectedIsActive, $key) {
252 foreach (CRM_Core_Module::getAll() as $module) {
253 if ($module->name == $key) {
254 $this->assertEquals((bool) $expectedIsActive, (bool) $module->is_active);
255 return;
256 }
257 }
258 $this->assertEquals($expectedIsActive, FALSE);
259 }
260
261 /**
262 * @param $key
263 * @param $type
264 * @param $file
265 * @param string $template
266 */
267 public function _createExtension($key, $type, $file, $template = self::MODULE_TEMPLATE) {
268 $basedir = $this->basedir;
269 mkdir("$basedir/$key");
270 file_put_contents("$basedir/$key/info.xml", "<extension key='$key' type='$type'><file>$file</file></extension>");
271 file_put_contents("$basedir/$key/$file.php", strtr($template, array('_FILE_' => $file)));
272 $this->system->getCache()->flush();
273 $this->system->getManager()->refresh();
274 }
275
276 /**
277 * @param $module
278 * @param string $name
279 */
280 public static function incHookCount($module, $name) {
281 global $_test_extension_manager_moduletest_counts;
282 if (!isset($_test_extension_manager_moduletest_counts[$module][$name])) {
283 $_test_extension_manager_moduletest_counts[$module][$name] = 0;
284 }
285 $_test_extension_manager_moduletest_counts[$module][$name] = 1 + (int) $_test_extension_manager_moduletest_counts[$module][$name];
286 }
287
288 const MODULE_TEMPLATE = "
289 <?php
290 function _FILE__civicrm_install() {
291 CRM_Extension_Manager_ModuleTest::incHookCount('_FILE_', 'install');
292 }
293
294 function _FILE__civicrm_postInstall() {
295 CRM_Extension_Manager_ModuleTest::incHookCount('_FILE_', 'postInstall');
296 }
297
298 function _FILE__civicrm_uninstall() {
299 CRM_Extension_Manager_ModuleTest::incHookCount('_FILE_', 'uninstall');
300 }
301
302 function _FILE__civicrm_enable() {
303 CRM_Extension_Manager_ModuleTest::incHookCount('_FILE_', 'enable');
304 }
305
306 function _FILE__civicrm_disable() {
307 CRM_Extension_Manager_ModuleTest::incHookCount('_FILE_', 'disable');
308 }
309 ";
310
311 }