Commit | Line | Data |
---|---|---|
6a488035 TO |
1 | <?php |
2 | ||
aba1cd8b EM |
3 | /** |
4 | * Class CRM_Core_ManagedEntitiesTest | |
acb109b7 | 5 | * @group headless |
aba1cd8b | 6 | */ |
6a488035 | 7 | class CRM_Core_ManagedEntitiesTest extends CiviUnitTestCase { |
378e2654 TO |
8 | /** |
9 | * @var \Civi\API\Kernel | |
10 | */ | |
11 | protected $apiKernel; | |
12 | ||
13 | /** | |
14 | * @var \Civi\API\Provider\AdhocProvider | |
15 | */ | |
16 | protected $adhocProvider; | |
17 | ||
aba1cd8b | 18 | /** |
1d3260ea | 19 | * @var String[] |
aba1cd8b | 20 | */ |
bbf66e9c TO |
21 | protected $modules; |
22 | ||
6ea13979 TO |
23 | protected $fixtures; |
24 | ||
00be9182 | 25 | public function setUp() { |
e4ccda28 | 26 | $this->useTransaction(TRUE); |
6a488035 | 27 | parent::setUp(); |
9099cab3 | 28 | $this->modules = [ |
6a488035 TO |
29 | 'one' => new CRM_Core_Module('com.example.one', TRUE), |
30 | 'two' => new CRM_Core_Module('com.example.two', TRUE), | |
9099cab3 | 31 | ]; |
e4ccda28 TO |
32 | |
33 | // Testing on drupal-demo fails because some extensions have mgd ents. | |
34 | CRM_Core_DAO::singleValueQuery('DELETE FROM civicrm_managed'); | |
6ea13979 | 35 | |
9099cab3 | 36 | $this->fixtures['com.example.one-foo'] = [ |
6ea13979 TO |
37 | 'module' => 'com.example.one', |
38 | 'name' => 'foo', | |
39 | 'entity' => 'CustomSearch', | |
9099cab3 | 40 | 'params' => [ |
6ea13979 TO |
41 | 'version' => 3, |
42 | 'class_name' => 'CRM_Example_One_Foo', | |
43 | 'is_reserved' => 1, | |
9099cab3 CW |
44 | ], |
45 | ]; | |
46 | $this->fixtures['com.example.one-bar'] = [ | |
6ea13979 TO |
47 | 'module' => 'com.example.one', |
48 | 'name' => 'bar', | |
49 | 'entity' => 'CustomSearch', | |
9099cab3 | 50 | 'params' => [ |
6ea13979 TO |
51 | 'version' => 3, |
52 | 'class_name' => 'CRM_Example_One_Bar', | |
53 | 'is_reserved' => 1, | |
9099cab3 CW |
54 | ], |
55 | ]; | |
56 | $this->fixtures['com.example.one-CustomGroup'] = [ | |
ee8b9cee MM |
57 | 'module' => 'com.example.one', |
58 | 'name' => 'CustomGroup', | |
59 | 'entity' => 'CustomGroup', | |
9099cab3 | 60 | 'params' => [ |
ee8b9cee MM |
61 | 'version' => 3, |
62 | 'name' => 'test_custom_group', | |
63 | 'title' => 'Test custom group', | |
64 | 'extends' => 'Individual', | |
9099cab3 CW |
65 | ], |
66 | ]; | |
67 | $this->fixtures['com.example.one-CustomField'] = [ | |
ee8b9cee MM |
68 | 'module' => 'com.example.one', |
69 | 'name' => 'CustomField', | |
70 | 'entity' => 'CustomField', | |
9099cab3 | 71 | 'params' => [ |
ee8b9cee MM |
72 | 'version' => 3, |
73 | 'name' => 'test_custom_field', | |
74 | 'label' => 'Test custom field', | |
75 | 'custom_group_id' => 'test_custom_group', | |
76 | 'data_type' => 'String', | |
77 | 'html_type' => 'Text', | |
9099cab3 CW |
78 | ], |
79 | ]; | |
378e2654 | 80 | |
20429eb9 RL |
81 | $this->fixtures['com.example.one-Job'] = [ |
82 | 'module' => 'com.example.one', | |
83 | 'name' => 'Job', | |
84 | 'entity' => 'Job', | |
85 | 'params' => [ | |
86 | 'version' => 3, | |
87 | 'name' => 'test_job', | |
88 | 'run_frequency' => 'Daily', | |
89 | 'api_entity' => 'Job', | |
90 | 'api_action' => 'Get', | |
91 | 'parameters' => '', | |
92 | ], | |
93 | ]; | |
94 | ||
048222df | 95 | $this->apiKernel = \Civi::service('civi_api_kernel'); |
378e2654 TO |
96 | $this->adhocProvider = new \Civi\API\Provider\AdhocProvider(3, 'CustomSearch'); |
97 | $this->apiKernel->registerApiProvider($this->adhocProvider); | |
6a488035 TO |
98 | } |
99 | ||
00be9182 | 100 | public function tearDown() { |
6a488035 | 101 | parent::tearDown(); |
048222df | 102 | \Civi::reset(); |
6a488035 TO |
103 | } |
104 | ||
105 | /** | |
106 | * Set up an active module and, over time, the hook implementation changes | |
107 | * to (1) create 'foo' entity, (2) create 'bar' entity', (3) remove 'foo' | |
108 | * entity | |
109 | */ | |
00be9182 | 110 | public function testAddRemoveEntitiesModule_UpdateAlways_DeleteAlways() { |
9099cab3 | 111 | $decls = []; |
6a488035 TO |
112 | |
113 | // create first managed entity ('foo') | |
6ea13979 | 114 | $decls[] = $this->fixtures['com.example.one-foo']; |
6a488035 TO |
115 | $me = new CRM_Core_ManagedEntities($this->modules, $decls); |
116 | $me->reconcile(); | |
117 | $foo = $me->get('com.example.one', 'foo'); | |
118 | $this->assertEquals('CRM_Example_One_Foo', $foo['name']); | |
119 | $this->assertDBQuery(1, 'SELECT count(*) FROM civicrm_option_value WHERE name = "CRM_Example_One_Foo"'); | |
120 | ||
121 | // later on, hook returns an extra managed entity ('bar') | |
6ea13979 | 122 | $decls[] = $this->fixtures['com.example.one-bar']; |
6a488035 TO |
123 | $me = new CRM_Core_ManagedEntities($this->modules, $decls); |
124 | $me->reconcile(); | |
125 | $foo = $me->get('com.example.one', 'foo'); | |
126 | $this->assertEquals('CRM_Example_One_Foo', $foo['name']); | |
127 | $this->assertDBQuery(1, 'SELECT count(*) FROM civicrm_option_value WHERE name = "CRM_Example_One_Foo"'); | |
128 | $bar = $me->get('com.example.one', 'bar'); | |
129 | $this->assertEquals('CRM_Example_One_Bar', $bar['name']); | |
130 | $this->assertDBQuery(1, 'SELECT count(*) FROM civicrm_option_value WHERE name = "CRM_Example_One_Bar"'); | |
131 | ||
132 | // and then hook changes its mind, removing 'foo' (first of two entities) | |
133 | unset($decls[0]); | |
134 | $me = new CRM_Core_ManagedEntities($this->modules, $decls); | |
135 | $me->reconcile(); | |
136 | $foo = $me->get('com.example.one', 'foo'); | |
137 | $this->assertTrue($foo === NULL); | |
138 | $this->assertDBQuery(0, 'SELECT count(*) FROM civicrm_option_value WHERE name = "CRM_Example_One_Foo"'); | |
139 | $bar = $me->get('com.example.one', 'bar'); | |
140 | $this->assertEquals('CRM_Example_One_Bar', $bar['name']); | |
141 | $this->assertDBQuery(1, 'SELECT count(*) FROM civicrm_option_value WHERE name = "CRM_Example_One_Bar"'); | |
142 | ||
143 | // and then hook changes its mind, removing 'bar' (the last remaining entity) | |
144 | unset($decls[1]); | |
145 | $me = new CRM_Core_ManagedEntities($this->modules, $decls); | |
146 | $me->reconcile(); | |
147 | $foo = $me->get('com.example.one', 'foo'); | |
148 | $this->assertTrue($foo === NULL); | |
149 | $this->assertDBQuery(0, 'SELECT count(*) FROM civicrm_option_value WHERE name = "CRM_Example_One_Foo"'); | |
150 | $bar = $me->get('com.example.one', 'bar'); | |
151 | $this->assertTrue($bar === NULL); | |
152 | $this->assertDBQuery(0, 'SELECT count(*) FROM civicrm_option_value WHERE name = "CRM_Example_One_Bar"'); | |
153 | } | |
154 | ||
155 | /** | |
156 | * Set up an active module with one managed-entity and, over | |
157 | * time, the content of the entity changes | |
158 | */ | |
00be9182 | 159 | public function testModifyDeclaration_UpdateAlways() { |
9099cab3 | 160 | $decls = []; |
6a488035 TO |
161 | |
162 | // create first managed entity ('foo') | |
6ea13979 | 163 | $decls[] = $this->fixtures['com.example.one-foo']; |
6a488035 TO |
164 | $me = new CRM_Core_ManagedEntities($this->modules, $decls); |
165 | $me->reconcile(); | |
166 | $foo = $me->get('com.example.one', 'foo'); | |
167 | $this->assertEquals('CRM_Example_One_Foo', $foo['name']); | |
168 | $this->assertDBQuery(1, 'SELECT count(*) FROM civicrm_option_value WHERE name = "CRM_Example_One_Foo"'); | |
169 | ||
170 | // later on, hook specification changes | |
171 | $decls[0]['params']['class_name'] = 'CRM_Example_One_Foobar'; | |
172 | $me = new CRM_Core_ManagedEntities($this->modules, $decls); | |
173 | $me->reconcile(); | |
174 | $foo2 = $me->get('com.example.one', 'foo'); | |
175 | $this->assertEquals('CRM_Example_One_Foobar', $foo2['name']); | |
176 | $this->assertDBQuery(0, 'SELECT count(*) FROM civicrm_option_value WHERE name = "CRM_Example_One_Foo"'); | |
177 | $this->assertDBQuery(1, 'SELECT count(*) FROM civicrm_option_value WHERE name = "CRM_Example_One_FooBar"'); | |
178 | $this->assertEquals($foo['id'], $foo2['id']); | |
179 | } | |
180 | ||
0dd54586 TO |
181 | /** |
182 | * Set up an active module with one managed-entity and, over | |
183 | * time, the content of the entity changes | |
184 | */ | |
00be9182 | 185 | public function testModifyDeclaration_UpdateNever() { |
9099cab3 | 186 | $decls = []; |
0dd54586 TO |
187 | |
188 | // create first managed entity ('foo') | |
9099cab3 | 189 | $decls[] = array_merge($this->fixtures['com.example.one-foo'], [ |
39b959db SL |
190 | // Policy is to never update after initial creation |
191 | 'update' => 'never', | |
9099cab3 | 192 | ]); |
0dd54586 TO |
193 | $me = new CRM_Core_ManagedEntities($this->modules, $decls); |
194 | $me->reconcile(); | |
195 | $foo = $me->get('com.example.one', 'foo'); | |
196 | $this->assertEquals('CRM_Example_One_Foo', $foo['name']); | |
197 | $this->assertDBQuery(1, 'SELECT count(*) FROM civicrm_option_value WHERE name = "CRM_Example_One_Foo"'); | |
198 | ||
199 | // later on, hook specification changes | |
200 | $decls[0]['params']['class_name'] = 'CRM_Example_One_Foobar'; | |
201 | $me = new CRM_Core_ManagedEntities($this->modules, $decls); | |
202 | $me->reconcile(); | |
203 | $foo2 = $me->get('com.example.one', 'foo'); | |
204 | $this->assertEquals('CRM_Example_One_Foo', $foo2['name']); | |
205 | $this->assertDBQuery(1, 'SELECT count(*) FROM civicrm_option_value WHERE name = "CRM_Example_One_Foo"'); | |
206 | $this->assertDBQuery(0, 'SELECT count(*) FROM civicrm_option_value WHERE name = "CRM_Example_One_FooBar"'); | |
207 | $this->assertEquals($foo['id'], $foo2['id']); | |
208 | } | |
209 | ||
1f103dc4 TO |
210 | /** |
211 | * Set up an active module with one managed-entity using the | |
212 | * policy "cleanup=>never". When the managed-entity goes away, | |
213 | * ensure that the policy is followed (ie the entity is not | |
214 | * deleted). | |
215 | */ | |
00be9182 | 216 | public function testRemoveDeclaration_CleanupNever() { |
9099cab3 | 217 | $decls = []; |
1f103dc4 TO |
218 | |
219 | // create first managed entity ('foo') | |
9099cab3 | 220 | $decls[] = array_merge($this->fixtures['com.example.one-foo'], [ |
21dfd5f5 | 221 | 'cleanup' => 'never', |
9099cab3 | 222 | ]); |
1f103dc4 TO |
223 | $me = new CRM_Core_ManagedEntities($this->modules, $decls); |
224 | $me->reconcile(); | |
225 | $foo = $me->get('com.example.one', 'foo'); | |
226 | $this->assertEquals('CRM_Example_One_Foo', $foo['name']); | |
227 | $this->assertDBQuery(1, 'SELECT count(*) FROM civicrm_option_value WHERE name = "CRM_Example_One_Foo"'); | |
228 | ||
229 | // later on, entity definition disappears; but we decide not to do any cleanup (per policy) | |
9099cab3 | 230 | $decls = []; |
1f103dc4 TO |
231 | $me = new CRM_Core_ManagedEntities($this->modules, $decls); |
232 | $me->reconcile(); | |
233 | $foo2 = $me->get('com.example.one', 'foo'); | |
234 | $this->assertEquals('CRM_Example_One_Foo', $foo2['name']); | |
235 | $this->assertDBQuery(1, 'SELECT count(*) FROM civicrm_option_value WHERE name = "CRM_Example_One_Foo"'); | |
236 | $this->assertEquals($foo['id'], $foo2['id']); | |
237 | } | |
238 | ||
378e2654 TO |
239 | /** |
240 | * Set up an active module with one managed-entity using the | |
241 | * policy "cleanup=>never". When the managed-entity goes away, | |
242 | * ensure that the policy is followed (ie the entity is not | |
243 | * deleted). | |
244 | */ | |
00be9182 | 245 | public function testRemoveDeclaration_CleanupUnused() { |
9099cab3 | 246 | $decls = []; |
378e2654 TO |
247 | |
248 | // create first managed entity ('foo') | |
9099cab3 | 249 | $decls[] = array_merge($this->fixtures['com.example.one-foo'], [ |
21dfd5f5 | 250 | 'cleanup' => 'unused', |
9099cab3 | 251 | ]); |
378e2654 TO |
252 | $me = new CRM_Core_ManagedEntities($this->modules, $decls); |
253 | $me->reconcile(); | |
254 | $foo = $me->get('com.example.one', 'foo'); | |
255 | $this->assertEquals('CRM_Example_One_Foo', $foo['name']); | |
256 | $this->assertDBQuery(1, 'SELECT count(*) FROM civicrm_option_value WHERE name = "CRM_Example_One_Foo"'); | |
257 | ||
258 | // Override 'getrefcount' ==> The refcount is 1 | |
92915c55 | 259 | $this->adhocProvider->addAction('getrefcount', 'access CiviCRM', function ($apiRequest) { |
9099cab3 CW |
260 | return civicrm_api3_create_success([ |
261 | [ | |
378e2654 TO |
262 | 'name' => 'mock', |
263 | 'type' => 'mock', | |
264 | 'count' => 1, | |
9099cab3 CW |
265 | ], |
266 | ]); | |
378e2654 TO |
267 | }); |
268 | ||
269 | // Later on, entity definition disappears; but we decide not to do any cleanup (per policy) | |
9099cab3 | 270 | $decls = []; |
378e2654 TO |
271 | $me = new CRM_Core_ManagedEntities($this->modules, $decls); |
272 | $me->reconcile(); | |
273 | $foo2 = $me->get('com.example.one', 'foo'); | |
274 | $this->assertEquals('CRM_Example_One_Foo', $foo2['name']); | |
275 | $this->assertDBQuery(1, 'SELECT count(*) FROM civicrm_option_value WHERE name = "CRM_Example_One_Foo"'); | |
276 | $this->assertEquals($foo['id'], $foo2['id']); | |
277 | ||
378e2654 | 278 | // Override 'getrefcount' ==> The refcount is 0 |
92915c55 | 279 | $this->adhocProvider->addAction('getrefcount', 'access CiviCRM', function ($apiRequest) { |
9099cab3 | 280 | return civicrm_api3_create_success([]); |
378e2654 TO |
281 | }); |
282 | ||
283 | // The entity definition disappeared and there's no reference; we decide to cleanup (per policy) | |
9099cab3 | 284 | $decls = []; |
378e2654 TO |
285 | $me = new CRM_Core_ManagedEntities($this->modules, $decls); |
286 | $me->reconcile(); | |
287 | $foo3 = $me->get('com.example.one', 'foo'); | |
288 | $this->assertDBQuery(0, 'SELECT count(*) FROM civicrm_option_value WHERE name = "CRM_Example_One_Foo"'); | |
289 | $this->assertTrue($foo3 === NULL); | |
290 | } | |
291 | ||
6a488035 | 292 | /** |
eceb18cc | 293 | * Setup an active module with a malformed entity declaration. |
6a488035 | 294 | */ |
00be9182 | 295 | public function testInvalidDeclarationModule() { |
6a488035 | 296 | // create first managed entity ('foo') |
9099cab3 CW |
297 | $decls = []; |
298 | $decls[] = [ | |
39b959db SL |
299 | // erroneous |
300 | 'module' => 'com.example.unknown', | |
6a488035 TO |
301 | 'name' => 'foo', |
302 | 'entity' => 'CustomSearch', | |
9099cab3 | 303 | 'params' => [ |
6a488035 TO |
304 | 'version' => 3, |
305 | 'class_name' => 'CRM_Example_One_Foo', | |
306 | 'is_reserved' => 1, | |
9099cab3 CW |
307 | ], |
308 | ]; | |
6a488035 TO |
309 | $me = new CRM_Core_ManagedEntities($this->modules, $decls); |
310 | try { | |
311 | $me->reconcile(); | |
312 | $this->fail('Expected exception when using invalid declaration'); | |
0db6c3e1 TO |
313 | } |
314 | catch (Exception $e) { | |
6c6e6187 | 315 | // good |
6a488035 TO |
316 | } |
317 | } | |
318 | ||
319 | /** | |
eceb18cc | 320 | * Setup an active module with a malformed entity declaration. |
6a488035 | 321 | */ |
00be9182 | 322 | public function testMissingName() { |
6a488035 | 323 | // create first managed entity ('foo') |
9099cab3 CW |
324 | $decls = []; |
325 | $decls[] = [ | |
6a488035 | 326 | 'module' => 'com.example.unknown', |
39b959db SL |
327 | // erroneous |
328 | 'name' => NULL, | |
6a488035 | 329 | 'entity' => 'CustomSearch', |
9099cab3 | 330 | 'params' => [ |
6a488035 TO |
331 | 'version' => 3, |
332 | 'class_name' => 'CRM_Example_One_Foo', | |
333 | 'is_reserved' => 1, | |
9099cab3 CW |
334 | ], |
335 | ]; | |
6a488035 TO |
336 | $me = new CRM_Core_ManagedEntities($this->modules, $decls); |
337 | try { | |
338 | $me->reconcile(); | |
339 | $this->fail('Expected exception when using invalid declaration'); | |
0db6c3e1 TO |
340 | } |
341 | catch (Exception $e) { | |
6c6e6187 | 342 | // good |
6a488035 TO |
343 | } |
344 | } | |
345 | ||
346 | /** | |
eceb18cc | 347 | * Setup an active module with a malformed entity declaration. |
6a488035 | 348 | */ |
00be9182 | 349 | public function testMissingEntity() { |
6a488035 | 350 | // create first managed entity ('foo') |
9099cab3 CW |
351 | $decls = []; |
352 | $decls[] = [ | |
6a488035 TO |
353 | 'module' => 'com.example.unknown', |
354 | 'name' => 'foo', | |
39b959db SL |
355 | // erroneous |
356 | 'entity' => NULL, | |
9099cab3 | 357 | 'params' => [ |
6a488035 TO |
358 | 'version' => 3, |
359 | 'class_name' => 'CRM_Example_One_Foo', | |
360 | 'is_reserved' => 1, | |
9099cab3 CW |
361 | ], |
362 | ]; | |
6a488035 TO |
363 | $me = new CRM_Core_ManagedEntities($this->modules, $decls); |
364 | try { | |
365 | $me->reconcile(); | |
366 | $this->fail('Expected exception when using invalid declaration'); | |
0db6c3e1 TO |
367 | } |
368 | catch (Exception $e) { | |
6c6e6187 | 369 | // good |
6a488035 TO |
370 | } |
371 | } | |
372 | ||
373 | /** | |
374 | * Setup an active module with an entity -- then disable and re-enable the | |
375 | * module | |
376 | */ | |
00be9182 | 377 | public function testDeactivateReactivateModule() { |
20429eb9 RL |
378 | $manager = CRM_Extension_System::singleton()->getManager(); |
379 | ||
6a488035 | 380 | // create first managed entity ('foo') |
9099cab3 | 381 | $decls = []; |
6ea13979 | 382 | $decls[] = $this->fixtures['com.example.one-foo']; |
20429eb9 RL |
383 | // Mock the contextual process info that would be added by CRM_Extension_Manager::install |
384 | $manager->setProcessesForTesting(['com.example.one' => ['install']]); | |
6a488035 TO |
385 | $me = new CRM_Core_ManagedEntities($this->modules, $decls); |
386 | $me->reconcile(); | |
387 | $foo = $me->get('com.example.one', 'foo'); | |
388 | $this->assertEquals(1, $foo['is_active']); | |
389 | $this->assertEquals('CRM_Example_One_Foo', $foo['name']); | |
390 | $this->assertDBQuery(1, 'SELECT is_active FROM civicrm_option_value WHERE name = "CRM_Example_One_Foo"'); | |
391 | ||
392 | // now deactivate module, which has empty decls and which cascades to managed object | |
393 | $this->modules['one']->is_active = FALSE; | |
20429eb9 RL |
394 | // Mock the contextual process info that would be added by CRM_Extension_Manager::disable |
395 | $manager->setProcessesForTesting(['com.example.one' => ['disable']]); | |
9099cab3 | 396 | $me = new CRM_Core_ManagedEntities($this->modules, []); |
6a488035 TO |
397 | $me->reconcile(); |
398 | $foo = $me->get('com.example.one', 'foo'); | |
399 | $this->assertEquals(0, $foo['is_active']); | |
400 | $this->assertEquals('CRM_Example_One_Foo', $foo['name']); | |
401 | $this->assertDBQuery(0, 'SELECT is_active FROM civicrm_option_value WHERE name = "CRM_Example_One_Foo"'); | |
402 | ||
403 | // and reactivate module, which again provides decls and which cascades to managed object | |
404 | $this->modules['one']->is_active = TRUE; | |
20429eb9 RL |
405 | // Mock the contextual process info that would be added by CRM_Extension_Manager::enable |
406 | $manager->setProcessesForTesting(['com.example.one' => ['enable']]); | |
6a488035 TO |
407 | $me = new CRM_Core_ManagedEntities($this->modules, $decls); |
408 | $me->reconcile(); | |
409 | $foo = $me->get('com.example.one', 'foo'); | |
410 | $this->assertEquals(1, $foo['is_active']); | |
411 | $this->assertEquals('CRM_Example_One_Foo', $foo['name']); | |
412 | $this->assertDBQuery(1, 'SELECT is_active FROM civicrm_option_value WHERE name = "CRM_Example_One_Foo"'); | |
20429eb9 RL |
413 | |
414 | // Special case: Job entities. | |
415 | // | |
416 | // First we repeat the above steps, but adding the context that | |
417 | // CRM_Extension_Manager adds when installing/enabling extensions. | |
418 | // | |
419 | // The behaviour should be as above. | |
420 | $decls = [$this->fixtures['com.example.one-Job']]; | |
421 | // Mock the contextual process info that would be added by CRM_Extension_Manager::install | |
422 | $manager->setProcessesForTesting(['com.example.one' => ['install']]); | |
423 | $me = new CRM_Core_ManagedEntities($this->modules, $decls); | |
424 | $me->reconcile(); | |
425 | $job = $me->get('com.example.one', 'Job'); | |
426 | $this->assertEquals(1, $job['is_active']); | |
427 | $this->assertEquals('test_job', $job['name']); | |
428 | $this->assertDBQuery(1, 'SELECT is_active FROM civicrm_job WHERE name = "test_job"'); | |
429 | // Reset context. | |
430 | $manager->setProcessesForTesting([]); | |
431 | ||
432 | // now deactivate module, which has empty decls and which cascades to managed object | |
433 | $this->modules['one']->is_active = FALSE; | |
434 | // Mock the contextual process info that would be added by CRM_Extension_Manager::disable | |
435 | $manager->setProcessesForTesting(['com.example.one' => ['disable']]); | |
436 | $me = new CRM_Core_ManagedEntities($this->modules, []); | |
437 | $me->reconcile(); | |
438 | $job = $me->get('com.example.one', 'Job'); | |
439 | $this->assertEquals(0, $job['is_active']); | |
440 | $this->assertEquals('test_job', $job['name']); | |
441 | $this->assertDBQuery(0, 'SELECT is_active FROM civicrm_job WHERE name = "test_job"'); | |
442 | ||
443 | // and reactivate module, which again provides decls and which cascades to managed object | |
444 | $this->modules['one']->is_active = TRUE; | |
445 | $me = new CRM_Core_ManagedEntities($this->modules, $decls); | |
446 | // Mock the contextual process info that would be added by CRM_Extension_Manager::enable | |
447 | $manager->setProcessesForTesting(['com.example.one' => ['enable']]); | |
448 | $me->reconcile(); | |
449 | $job = $me->get('com.example.one', 'Job'); | |
450 | $this->assertEquals(1, $job['is_active']); | |
451 | $this->assertEquals('test_job', $job['name']); | |
452 | $this->assertDBQuery(1, 'SELECT is_active FROM civicrm_job WHERE name = "test_job"'); | |
453 | ||
454 | // Currently: module enabled, job enabled. | |
455 | // Test that if we now manually disable the job, calling reconcile in a | |
456 | // normal flush situation does NOT re-enable it. | |
457 | // ... manually disable job. | |
458 | $this->callAPISuccess('Job', 'create', ['id' => $job['id'], 'is_active' => 0]); | |
459 | ||
460 | // ... now call reconcile in the context of a normal flush operation. | |
461 | // Mock the contextual process info - there would not be any | |
462 | $manager->setProcessesForTesting([]); | |
463 | $me = new CRM_Core_ManagedEntities($this->modules, $decls); | |
464 | $me->reconcile(); | |
465 | $job = $me->get('com.example.one', 'Job'); | |
466 | $this->assertEquals(0, $job['is_active'], "Job that was manually set inactive should not have been set active again, but it was."); | |
467 | $this->assertDBQuery(0, 'SELECT is_active FROM civicrm_job WHERE name = "test_job"'); | |
468 | ||
469 | // Now call reconcile again, but in the context of the job's extension being installed/enabled. This should re-enable the job. | |
470 | foreach (['enable', 'install'] as $process) { | |
471 | // Manually disable the job | |
472 | $this->callAPISuccess('Job', 'create', ['id' => $job['id'], 'is_active' => 0]); | |
473 | // Mock the contextual process info that would be added by CRM_Extension_Manager::enable | |
474 | $manager->setProcessesForTesting(['com.example.one' => [$process]]); | |
475 | $me = new CRM_Core_ManagedEntities($this->modules, $decls); | |
476 | $me->reconcile(); | |
477 | $job = $me->get('com.example.one', 'Job'); | |
478 | $this->assertEquals(1, $job['is_active']); | |
479 | $this->assertEquals('test_job', $job['name']); | |
480 | $this->assertDBQuery(1, 'SELECT is_active FROM civicrm_job WHERE name = "test_job"'); | |
481 | } | |
482 | ||
483 | // Reset context. | |
484 | $manager->setProcessesForTesting([]); | |
6a488035 TO |
485 | } |
486 | ||
487 | /** | |
488 | * Setup an active module with an entity -- then entirely uninstall the | |
489 | * module | |
490 | */ | |
00be9182 | 491 | public function testUninstallModule() { |
6a488035 | 492 | // create first managed entity ('foo') |
9099cab3 | 493 | $decls = []; |
6ea13979 | 494 | $decls[] = $this->fixtures['com.example.one-foo']; |
6a488035 TO |
495 | $me = new CRM_Core_ManagedEntities($this->modules, $decls); |
496 | $me->reconcile(); | |
497 | $foo = $me->get('com.example.one', 'foo'); | |
498 | $this->assertEquals('CRM_Example_One_Foo', $foo['name']); | |
499 | $this->assertDBQuery(1, 'SELECT count(*) FROM civicrm_option_value WHERE name = "CRM_Example_One_Foo"'); | |
500 | ||
e4f46be0 | 501 | // then destroy module; note that decls go away |
6a488035 | 502 | unset($this->modules['one']); |
9099cab3 | 503 | $me = new CRM_Core_ManagedEntities($this->modules, []); |
6a488035 TO |
504 | $me->reconcile(); |
505 | $fooNew = $me->get('com.example.one', 'foo'); | |
506 | $this->assertTrue(NULL === $fooNew); | |
507 | $this->assertDBQuery(0, 'SELECT count(*) FROM civicrm_option_value WHERE name = "CRM_Example_One_Foo"'); | |
508 | } | |
96025800 | 509 | |
ee8b9cee MM |
510 | public function testDependentEntitiesUninstallCleanly() { |
511 | ||
512 | // Install a module with two dependent managed entities | |
9099cab3 | 513 | $decls = []; |
ee8b9cee MM |
514 | $decls[] = $this->fixtures['com.example.one-CustomGroup']; |
515 | $decls[] = $this->fixtures['com.example.one-CustomField']; | |
516 | $me = new CRM_Core_ManagedEntities($this->modules, $decls); | |
517 | $me->reconcile(); | |
518 | ||
519 | // Uninstall the module | |
520 | unset($this->modules['one']); | |
521 | $me = new CRM_Core_ManagedEntities($this->modules, []); | |
522 | $me->reconcile(); | |
523 | ||
524 | // Ensure that no managed entities remain in the civicrm_managed | |
525 | $this->assertDBQuery(0, 'SELECT count(*) FROM civicrm_managed'); | |
526 | ||
527 | // Ensure that com.example.one-CustomGroup is deleted | |
528 | $this->assertDBQuery(0, 'SELECT count(*) FROM civicrm_custom_group WHERE name = "test_custom_group"'); | |
529 | ||
530 | // Ensure that com.example.one-CustomField is deleted | |
531 | $this->assertDBQuery(0, 'SELECT count(*) FROM civicrm_custom_field WHERE name = "test_custom_field"'); | |
532 | ||
533 | } | |
534 | ||
6a488035 | 535 | } |