test fix
[civicrm-core.git] / tests / phpunit / CRM / Core / ManagedEntitiesTest.php
CommitLineData
6a488035
TO
1<?php
2
3require_once 'CiviTest/CiviUnitTestCase.php';
4
aba1cd8b
EM
5/**
6 * Class CRM_Core_ManagedEntitiesTest
7 */
6a488035 8class CRM_Core_ManagedEntitiesTest extends CiviUnitTestCase {
378e2654
TO
9 /**
10 * @var \Civi\API\Kernel
11 */
12 protected $apiKernel;
13
14 /**
15 * @var \Civi\API\Provider\AdhocProvider
16 */
17 protected $adhocProvider;
18
aba1cd8b 19 /**
bbf66e9c 20 * @var array(string $shortName => CRM_Core_Module $module)
aba1cd8b 21 */
bbf66e9c
TO
22 protected $modules;
23
6ea13979
TO
24 protected $fixtures;
25
00be9182 26 public function setUp() {
e4ccda28 27 $this->useTransaction(TRUE);
6a488035
TO
28 parent::setUp();
29 $this->modules = array(
30 'one' => new CRM_Core_Module('com.example.one', TRUE),
31 'two' => new CRM_Core_Module('com.example.two', TRUE),
32 );
e4ccda28
TO
33
34 // Testing on drupal-demo fails because some extensions have mgd ents.
35 CRM_Core_DAO::singleValueQuery('DELETE FROM civicrm_managed');
6ea13979
TO
36
37 $this->fixtures['com.example.one-foo'] = array(
38 'module' => 'com.example.one',
39 'name' => 'foo',
40 'entity' => 'CustomSearch',
41 'params' => array(
42 'version' => 3,
43 'class_name' => 'CRM_Example_One_Foo',
44 'is_reserved' => 1,
45 ),
46 );
47 $this->fixtures['com.example.one-bar'] = array(
48 'module' => 'com.example.one',
49 'name' => 'bar',
50 'entity' => 'CustomSearch',
51 'params' => array(
52 'version' => 3,
53 'class_name' => 'CRM_Example_One_Bar',
54 'is_reserved' => 1,
55 ),
56 );
378e2654
TO
57
58 $this->apiKernel = \Civi\Core\Container::singleton()->get('civi_api_kernel');
59 $this->adhocProvider = new \Civi\API\Provider\AdhocProvider(3, 'CustomSearch');
60 $this->apiKernel->registerApiProvider($this->adhocProvider);
6a488035
TO
61 }
62
00be9182 63 public function tearDown() {
6a488035 64 parent::tearDown();
378e2654 65 \Civi\Core\Container::singleton(TRUE);
6a488035
TO
66 }
67
68 /**
69 * Set up an active module and, over time, the hook implementation changes
70 * to (1) create 'foo' entity, (2) create 'bar' entity', (3) remove 'foo'
71 * entity
72 */
00be9182 73 public function testAddRemoveEntitiesModule_UpdateAlways_DeleteAlways() {
6a488035
TO
74 $decls = array();
75
76 // create first managed entity ('foo')
6ea13979 77 $decls[] = $this->fixtures['com.example.one-foo'];
6a488035
TO
78 $me = new CRM_Core_ManagedEntities($this->modules, $decls);
79 $me->reconcile();
80 $foo = $me->get('com.example.one', 'foo');
81 $this->assertEquals('CRM_Example_One_Foo', $foo['name']);
82 $this->assertDBQuery(1, 'SELECT count(*) FROM civicrm_option_value WHERE name = "CRM_Example_One_Foo"');
83
84 // later on, hook returns an extra managed entity ('bar')
6ea13979 85 $decls[] = $this->fixtures['com.example.one-bar'];
6a488035
TO
86 $me = new CRM_Core_ManagedEntities($this->modules, $decls);
87 $me->reconcile();
88 $foo = $me->get('com.example.one', 'foo');
89 $this->assertEquals('CRM_Example_One_Foo', $foo['name']);
90 $this->assertDBQuery(1, 'SELECT count(*) FROM civicrm_option_value WHERE name = "CRM_Example_One_Foo"');
91 $bar = $me->get('com.example.one', 'bar');
92 $this->assertEquals('CRM_Example_One_Bar', $bar['name']);
93 $this->assertDBQuery(1, 'SELECT count(*) FROM civicrm_option_value WHERE name = "CRM_Example_One_Bar"');
94
95 // and then hook changes its mind, removing 'foo' (first of two entities)
96 unset($decls[0]);
97 $me = new CRM_Core_ManagedEntities($this->modules, $decls);
98 $me->reconcile();
99 $foo = $me->get('com.example.one', 'foo');
100 $this->assertTrue($foo === NULL);
101 $this->assertDBQuery(0, 'SELECT count(*) FROM civicrm_option_value WHERE name = "CRM_Example_One_Foo"');
102 $bar = $me->get('com.example.one', 'bar');
103 $this->assertEquals('CRM_Example_One_Bar', $bar['name']);
104 $this->assertDBQuery(1, 'SELECT count(*) FROM civicrm_option_value WHERE name = "CRM_Example_One_Bar"');
105
106 // and then hook changes its mind, removing 'bar' (the last remaining entity)
107 unset($decls[1]);
108 $me = new CRM_Core_ManagedEntities($this->modules, $decls);
109 $me->reconcile();
110 $foo = $me->get('com.example.one', 'foo');
111 $this->assertTrue($foo === NULL);
112 $this->assertDBQuery(0, 'SELECT count(*) FROM civicrm_option_value WHERE name = "CRM_Example_One_Foo"');
113 $bar = $me->get('com.example.one', 'bar');
114 $this->assertTrue($bar === NULL);
115 $this->assertDBQuery(0, 'SELECT count(*) FROM civicrm_option_value WHERE name = "CRM_Example_One_Bar"');
116 }
117
118 /**
119 * Set up an active module with one managed-entity and, over
120 * time, the content of the entity changes
121 */
00be9182 122 public function testModifyDeclaration_UpdateAlways() {
6a488035
TO
123 $decls = array();
124
125 // create first managed entity ('foo')
6ea13979 126 $decls[] = $this->fixtures['com.example.one-foo'];
6a488035
TO
127 $me = new CRM_Core_ManagedEntities($this->modules, $decls);
128 $me->reconcile();
129 $foo = $me->get('com.example.one', 'foo');
130 $this->assertEquals('CRM_Example_One_Foo', $foo['name']);
131 $this->assertDBQuery(1, 'SELECT count(*) FROM civicrm_option_value WHERE name = "CRM_Example_One_Foo"');
132
133 // later on, hook specification changes
134 $decls[0]['params']['class_name'] = 'CRM_Example_One_Foobar';
135 $me = new CRM_Core_ManagedEntities($this->modules, $decls);
136 $me->reconcile();
137 $foo2 = $me->get('com.example.one', 'foo');
138 $this->assertEquals('CRM_Example_One_Foobar', $foo2['name']);
139 $this->assertDBQuery(0, 'SELECT count(*) FROM civicrm_option_value WHERE name = "CRM_Example_One_Foo"');
140 $this->assertDBQuery(1, 'SELECT count(*) FROM civicrm_option_value WHERE name = "CRM_Example_One_FooBar"');
141 $this->assertEquals($foo['id'], $foo2['id']);
142 }
143
0dd54586
TO
144 /**
145 * Set up an active module with one managed-entity and, over
146 * time, the content of the entity changes
147 */
00be9182 148 public function testModifyDeclaration_UpdateNever() {
0dd54586
TO
149 $decls = array();
150
151 // create first managed entity ('foo')
152 $decls[] = array_merge($this->fixtures['com.example.one-foo'], array(
153 'update' => 'never', // Policy is to never update after initial creation
154 ));
155 $me = new CRM_Core_ManagedEntities($this->modules, $decls);
156 $me->reconcile();
157 $foo = $me->get('com.example.one', 'foo');
158 $this->assertEquals('CRM_Example_One_Foo', $foo['name']);
159 $this->assertDBQuery(1, 'SELECT count(*) FROM civicrm_option_value WHERE name = "CRM_Example_One_Foo"');
160
161 // later on, hook specification changes
162 $decls[0]['params']['class_name'] = 'CRM_Example_One_Foobar';
163 $me = new CRM_Core_ManagedEntities($this->modules, $decls);
164 $me->reconcile();
165 $foo2 = $me->get('com.example.one', 'foo');
166 $this->assertEquals('CRM_Example_One_Foo', $foo2['name']);
167 $this->assertDBQuery(1, 'SELECT count(*) FROM civicrm_option_value WHERE name = "CRM_Example_One_Foo"');
168 $this->assertDBQuery(0, 'SELECT count(*) FROM civicrm_option_value WHERE name = "CRM_Example_One_FooBar"');
169 $this->assertEquals($foo['id'], $foo2['id']);
170 }
171
1f103dc4
TO
172 /**
173 * Set up an active module with one managed-entity using the
174 * policy "cleanup=>never". When the managed-entity goes away,
175 * ensure that the policy is followed (ie the entity is not
176 * deleted).
177 */
00be9182 178 public function testRemoveDeclaration_CleanupNever() {
1f103dc4
TO
179 $decls = array();
180
181 // create first managed entity ('foo')
182 $decls[] = array_merge($this->fixtures['com.example.one-foo'], array(
21dfd5f5 183 'cleanup' => 'never',
1f103dc4
TO
184 ));
185 $me = new CRM_Core_ManagedEntities($this->modules, $decls);
186 $me->reconcile();
187 $foo = $me->get('com.example.one', 'foo');
188 $this->assertEquals('CRM_Example_One_Foo', $foo['name']);
189 $this->assertDBQuery(1, 'SELECT count(*) FROM civicrm_option_value WHERE name = "CRM_Example_One_Foo"');
190
191 // later on, entity definition disappears; but we decide not to do any cleanup (per policy)
192 $decls = array();
193 $me = new CRM_Core_ManagedEntities($this->modules, $decls);
194 $me->reconcile();
195 $foo2 = $me->get('com.example.one', 'foo');
196 $this->assertEquals('CRM_Example_One_Foo', $foo2['name']);
197 $this->assertDBQuery(1, 'SELECT count(*) FROM civicrm_option_value WHERE name = "CRM_Example_One_Foo"');
198 $this->assertEquals($foo['id'], $foo2['id']);
199 }
200
378e2654
TO
201 /**
202 * Set up an active module with one managed-entity using the
203 * policy "cleanup=>never". When the managed-entity goes away,
204 * ensure that the policy is followed (ie the entity is not
205 * deleted).
206 */
00be9182 207 public function testRemoveDeclaration_CleanupUnused() {
378e2654
TO
208 $decls = array();
209
210 // create first managed entity ('foo')
211 $decls[] = array_merge($this->fixtures['com.example.one-foo'], array(
21dfd5f5 212 'cleanup' => 'unused',
378e2654
TO
213 ));
214 $me = new CRM_Core_ManagedEntities($this->modules, $decls);
215 $me->reconcile();
216 $foo = $me->get('com.example.one', 'foo');
217 $this->assertEquals('CRM_Example_One_Foo', $foo['name']);
218 $this->assertDBQuery(1, 'SELECT count(*) FROM civicrm_option_value WHERE name = "CRM_Example_One_Foo"');
219
220 // Override 'getrefcount' ==> The refcount is 1
92915c55 221 $this->adhocProvider->addAction('getrefcount', 'access CiviCRM', function ($apiRequest) {
378e2654
TO
222 return civicrm_api3_create_success(array(
223 array(
224 'name' => 'mock',
225 'type' => 'mock',
226 'count' => 1,
21dfd5f5 227 ),
378e2654
TO
228 ));
229 });
230
231 // Later on, entity definition disappears; but we decide not to do any cleanup (per policy)
232 $decls = array();
233 $me = new CRM_Core_ManagedEntities($this->modules, $decls);
234 $me->reconcile();
235 $foo2 = $me->get('com.example.one', 'foo');
236 $this->assertEquals('CRM_Example_One_Foo', $foo2['name']);
237 $this->assertDBQuery(1, 'SELECT count(*) FROM civicrm_option_value WHERE name = "CRM_Example_One_Foo"');
238 $this->assertEquals($foo['id'], $foo2['id']);
239
378e2654 240 // Override 'getrefcount' ==> The refcount is 0
92915c55 241 $this->adhocProvider->addAction('getrefcount', 'access CiviCRM', function ($apiRequest) {
378e2654
TO
242 return civicrm_api3_create_success(array());
243 });
244
245 // The entity definition disappeared and there's no reference; we decide to cleanup (per policy)
246 $decls = array();
247 $me = new CRM_Core_ManagedEntities($this->modules, $decls);
248 $me->reconcile();
249 $foo3 = $me->get('com.example.one', 'foo');
250 $this->assertDBQuery(0, 'SELECT count(*) FROM civicrm_option_value WHERE name = "CRM_Example_One_Foo"');
251 $this->assertTrue($foo3 === NULL);
252 }
253
6a488035 254 /**
eceb18cc 255 * Setup an active module with a malformed entity declaration.
6a488035 256 */
00be9182 257 public function testInvalidDeclarationModule() {
6a488035
TO
258 // create first managed entity ('foo')
259 $decls = array();
260 $decls[] = array(
261 'module' => 'com.example.unknown', // erroneous
262 'name' => 'foo',
263 'entity' => 'CustomSearch',
264 'params' => array(
265 'version' => 3,
266 'class_name' => 'CRM_Example_One_Foo',
267 'is_reserved' => 1,
268 ),
269 );
270 $me = new CRM_Core_ManagedEntities($this->modules, $decls);
271 try {
272 $me->reconcile();
273 $this->fail('Expected exception when using invalid declaration');
0db6c3e1
TO
274 }
275 catch (Exception $e) {
6c6e6187 276 // good
6a488035
TO
277 }
278 }
279
280 /**
eceb18cc 281 * Setup an active module with a malformed entity declaration.
6a488035 282 */
00be9182 283 public function testMissingName() {
6a488035
TO
284 // create first managed entity ('foo')
285 $decls = array();
286 $decls[] = array(
287 'module' => 'com.example.unknown',
288 'name' => NULL, // erroneous
289 'entity' => 'CustomSearch',
290 'params' => array(
291 'version' => 3,
292 'class_name' => 'CRM_Example_One_Foo',
293 'is_reserved' => 1,
294 ),
295 );
296 $me = new CRM_Core_ManagedEntities($this->modules, $decls);
297 try {
298 $me->reconcile();
299 $this->fail('Expected exception when using invalid declaration');
0db6c3e1
TO
300 }
301 catch (Exception $e) {
6c6e6187 302 // good
6a488035
TO
303 }
304 }
305
306 /**
eceb18cc 307 * Setup an active module with a malformed entity declaration.
6a488035 308 */
00be9182 309 public function testMissingEntity() {
6a488035
TO
310 // create first managed entity ('foo')
311 $decls = array();
312 $decls[] = array(
313 'module' => 'com.example.unknown',
314 'name' => 'foo',
315 'entity' => NULL, // erroneous
316 'params' => array(
317 'version' => 3,
318 'class_name' => 'CRM_Example_One_Foo',
319 'is_reserved' => 1,
320 ),
321 );
322 $me = new CRM_Core_ManagedEntities($this->modules, $decls);
323 try {
324 $me->reconcile();
325 $this->fail('Expected exception when using invalid declaration');
0db6c3e1
TO
326 }
327 catch (Exception $e) {
6c6e6187 328 // good
6a488035
TO
329 }
330 }
331
332 /**
333 * Setup an active module with an entity -- then disable and re-enable the
334 * module
335 */
00be9182 336 public function testDeactivateReactivateModule() {
6a488035
TO
337 // create first managed entity ('foo')
338 $decls = array();
6ea13979 339 $decls[] = $this->fixtures['com.example.one-foo'];
6a488035
TO
340 $me = new CRM_Core_ManagedEntities($this->modules, $decls);
341 $me->reconcile();
342 $foo = $me->get('com.example.one', 'foo');
343 $this->assertEquals(1, $foo['is_active']);
344 $this->assertEquals('CRM_Example_One_Foo', $foo['name']);
345 $this->assertDBQuery(1, 'SELECT is_active FROM civicrm_option_value WHERE name = "CRM_Example_One_Foo"');
346
347 // now deactivate module, which has empty decls and which cascades to managed object
348 $this->modules['one']->is_active = FALSE;
349 $me = new CRM_Core_ManagedEntities($this->modules, array());
350 $me->reconcile();
351 $foo = $me->get('com.example.one', 'foo');
352 $this->assertEquals(0, $foo['is_active']);
353 $this->assertEquals('CRM_Example_One_Foo', $foo['name']);
354 $this->assertDBQuery(0, 'SELECT is_active FROM civicrm_option_value WHERE name = "CRM_Example_One_Foo"');
355
356 // and reactivate module, which again provides decls and which cascades to managed object
357 $this->modules['one']->is_active = TRUE;
358 $me = new CRM_Core_ManagedEntities($this->modules, $decls);
359 $me->reconcile();
360 $foo = $me->get('com.example.one', 'foo');
361 $this->assertEquals(1, $foo['is_active']);
362 $this->assertEquals('CRM_Example_One_Foo', $foo['name']);
363 $this->assertDBQuery(1, 'SELECT is_active FROM civicrm_option_value WHERE name = "CRM_Example_One_Foo"');
364 }
365
366 /**
367 * Setup an active module with an entity -- then entirely uninstall the
368 * module
369 */
00be9182 370 public function testUninstallModule() {
6a488035
TO
371 // create first managed entity ('foo')
372 $decls = array();
6ea13979 373 $decls[] = $this->fixtures['com.example.one-foo'];
6a488035
TO
374 $me = new CRM_Core_ManagedEntities($this->modules, $decls);
375 $me->reconcile();
376 $foo = $me->get('com.example.one', 'foo');
377 $this->assertEquals('CRM_Example_One_Foo', $foo['name']);
378 $this->assertDBQuery(1, 'SELECT count(*) FROM civicrm_option_value WHERE name = "CRM_Example_One_Foo"');
379
e4f46be0 380 // then destroy module; note that decls go away
6a488035
TO
381 unset($this->modules['one']);
382 $me = new CRM_Core_ManagedEntities($this->modules, array());
383 $me->reconcile();
384 $fooNew = $me->get('com.example.one', 'foo');
385 $this->assertTrue(NULL === $fooNew);
386 $this->assertDBQuery(0, 'SELECT count(*) FROM civicrm_option_value WHERE name = "CRM_Example_One_Foo"');
387 }
96025800 388
6a488035 389}