Commit | Line | Data |
---|---|---|
6a488035 TO |
1 | <?php |
2 | /* | |
7d61e75f TO |
3 | +--------------------------------------------------------------------+ |
4 | | Copyright CiviCRM LLC. All rights reserved. | | |
5 | | | | |
6 | | This work is published under the GNU AGPLv3 license with some | | |
7 | | permitted exceptions and without any warranty. For full license | | |
8 | | and copyright information, see https://civicrm.org/licensing | | |
9 | +--------------------------------------------------------------------+ | |
6a488035 TO |
10 | */ |
11 | ||
6a488035 TO |
12 | /** |
13 | * Test class for CRM_Contact_BAO_Group BAO | |
14 | * | |
6c6e6187 | 15 | * @package CiviCRM |
acb109b7 | 16 | * @group headless |
6a488035 TO |
17 | */ |
18 | class CRM_Contact_BAO_GroupTest extends CiviUnitTestCase { | |
19 | ||
6a488035 TO |
20 | /** |
21 | * Tears down the fixture, for example, closes a network connection. | |
9b1e4469 | 22 | * |
6a488035 | 23 | * This method is called after a test is executed. |
6a488035 | 24 | */ |
594a9328 | 25 | protected function tearDown(): void { |
9099cab3 | 26 | $this->quickCleanup(['civicrm_mapping_field', 'civicrm_mapping', 'civicrm_group', 'civicrm_saved_search']); |
959528d2 | 27 | } |
6a488035 TO |
28 | |
29 | /** | |
9b1e4469 | 30 | * Test case for add( ). |
6a488035 | 31 | */ |
00be9182 | 32 | public function testAddSimple() { |
6a488035 | 33 | |
9099cab3 | 34 | $checkParams = $params = [ |
6a488035 TO |
35 | 'title' => 'Group Uno', |
36 | 'description' => 'Group One', | |
37 | 'visibility' => 'User and User Admin Only', | |
38 | 'is_active' => 1, | |
9099cab3 | 39 | ]; |
6a488035 TO |
40 | |
41 | $group = CRM_Contact_BAO_Group::create($params); | |
42 | ||
43 | $this->assertDBCompareValues( | |
44 | 'CRM_Contact_DAO_Group', | |
9099cab3 | 45 | ['id' => $group->id], |
6a488035 TO |
46 | $checkParams |
47 | ); | |
48 | } | |
49 | ||
b901b84e | 50 | /** |
51 | * Test case to ensure child group is present in the hierarchy | |
52 | * if it has multiple parent groups and not all are disabled. | |
53 | */ | |
54 | public function testGroupHirearchy() { | |
55 | // Use-case : | |
56 | // 1. Create two parent group A and B and disable B | |
57 | // 2. Create a child group C | |
58 | // 3. Ensure that Group C is present in the group hierarchy | |
9099cab3 | 59 | $params = [ |
b901b84e | 60 | 'name' => uniqid(), |
61 | 'title' => 'Parent Group A', | |
62 | 'description' => 'Parent Group One', | |
63 | 'visibility' => 'User and User Admin Only', | |
64 | 'is_active' => 1, | |
9099cab3 | 65 | ]; |
b901b84e | 66 | $group1 = CRM_Contact_BAO_Group::create($params); |
67 | ||
9099cab3 | 68 | $params = array_merge($params, [ |
b901b84e | 69 | 'name' => uniqid(), |
70 | 'title' => 'Parent Group B', | |
71 | 'description' => 'Parent Group Two', | |
39b959db SL |
72 | // disable |
73 | 'is_active' => 0, | |
9099cab3 | 74 | ]); |
b901b84e | 75 | $group2 = CRM_Contact_BAO_Group::create($params); |
76 | ||
9099cab3 | 77 | $params = array_merge($params, [ |
b901b84e | 78 | 'name' => uniqid(), |
79 | 'title' => 'Child Group C', | |
80 | 'description' => 'Child Group C', | |
9099cab3 | 81 | 'parents' => [ |
b901b84e | 82 | $group1->id => 1, |
83 | $group2->id => 1, | |
9099cab3 CW |
84 | ], |
85 | ]); | |
b901b84e | 86 | $group3 = CRM_Contact_BAO_Group::create($params); |
87 | ||
9099cab3 | 88 | $params = [ |
b901b84e | 89 | $group1->id => 1, |
90 | $group3->id => 1, | |
9099cab3 | 91 | ]; |
b901b84e | 92 | $groupsHierarchy = CRM_Contact_BAO_Group::getGroupsHierarchy($params, NULL, ' ', TRUE); |
93 | // check if child group is present in the tree with formatted group title prepended with spacer ' ' | |
94 | $this->assertEquals(' Child Group C', $groupsHierarchy[$group3->id]); | |
95 | ||
96 | // Disable parent group A and ensure that child group C is not present as both of its parent groups are disabled | |
97 | $group1->is_active = 0; | |
98 | $group1->save(); | |
99 | $groupsHierarchy = CRM_Contact_BAO_Group::getGroupsHierarchy($params, NULL, ' ', TRUE); | |
100 | $this->assertFalse(array_key_exists($group3->id, $groupsHierarchy)); | |
101 | } | |
102 | ||
c6fe32d7 | 103 | /** |
104 | * Test nestedGroup pseudoconstant | |
105 | */ | |
106 | public function testNestedGroup() { | |
107 | $params = [ | |
108 | 'name' => 'groupa', | |
109 | 'title' => 'Parent Group A', | |
110 | 'description' => 'Parent Group One', | |
111 | 'visibility' => 'User and User Admin Only', | |
112 | 'is_active' => 1, | |
113 | // mailing group | |
114 | 'group_type' => ['2' => 1], | |
115 | ]; | |
116 | $group1 = CRM_Contact_BAO_Group::create($params); | |
117 | ||
118 | $params = [ | |
119 | 'name' => 'groupb', | |
120 | 'title' => 'Parent Group B', | |
121 | 'description' => 'Parent Group Two', | |
122 | 'visibility' => 'User and User Admin Only', | |
123 | 'is_active' => 1, | |
124 | ]; | |
125 | $group2 = CRM_Contact_BAO_Group::create($params); | |
126 | ||
127 | $params = [ | |
128 | 'name' => 'groupc', | |
129 | 'title' => 'Child Group C', | |
130 | 'description' => 'Child Group C', | |
131 | 'visibility' => 'User and User Admin Only', | |
132 | 'is_active' => 1, | |
133 | 'parents' => [ | |
134 | $group2->id => 1, | |
135 | ], | |
f5be1f3a | 136 | 'group_type' => ['2' => 1], |
c6fe32d7 | 137 | ]; |
138 | $group3 = CRM_Contact_BAO_Group::create($params); | |
139 | ||
7ffbc14e | 140 | unset(Civi::$statics['CRM_Core_Permission_Base']); |
c6fe32d7 | 141 | // Check with no group type restriction |
142 | $nestedGroup = CRM_Core_PseudoConstant::nestedGroup(); | |
143 | $this->assertEquals([ | |
144 | $group1->id => 'Parent Group A', | |
145 | $group2->id => 'Parent Group B', | |
146 | $group3->id => ' Child Group C', | |
147 | ], $nestedGroup); | |
148 | ||
149 | // Check restrict to mailing groups | |
150 | $nestedGroup = CRM_Core_PseudoConstant::nestedGroup(TRUE, 'Mailing'); | |
f5be1f3a SL |
151 | $this->assertSame([ |
152 | $group1->id => 'Parent Group A', | |
153 | $group3->id => ' Child Group C', | |
154 | ], $nestedGroup); | |
c6fe32d7 | 155 | } |
156 | ||
9b1e4469 | 157 | /** |
158 | * Test adding a smart group. | |
159 | */ | |
00be9182 | 160 | public function testAddSmart() { |
6a488035 | 161 | |
9099cab3 | 162 | $checkParams = $params = [ |
6a488035 TO |
163 | 'title' => 'Group Dos', |
164 | 'description' => 'Group Two', | |
165 | 'visibility' => 'User and User Admin Only', | |
166 | 'is_active' => 1, | |
9099cab3 CW |
167 | 'formValues' => ['sort_name' => 'Adams'], |
168 | ]; | |
6a488035 TO |
169 | |
170 | $group = CRM_Contact_BAO_Group::createSmartGroup($params); | |
171 | ||
172 | unset($checkParams['formValues']); | |
173 | $this->assertDBCompareValues( | |
174 | 'CRM_Contact_DAO_Group', | |
9099cab3 | 175 | ['id' => $group->id], |
6a488035 TO |
176 | $checkParams |
177 | ); | |
178 | } | |
959528d2 EM |
179 | |
180 | /** | |
9b1e4469 | 181 | * Load all sql data sets & return an array of saved searches. |
182 | * | |
959528d2 EM |
183 | * @return array |
184 | */ | |
00be9182 | 185 | public function dataProviderSavedSearch() { |
959528d2 EM |
186 | |
187 | $this->loadSavedSearches(); | |
188 | $results = CRM_Core_DAO::singleValueQuery('SELECT GROUP_CONCAT(id) FROM civicrm_group WHERE saved_search_id IS NOT NULL'); | |
9099cab3 | 189 | return [explode(',', $results)]; |
959528d2 EM |
190 | } |
191 | ||
192 | /** | |
eceb18cc | 193 | * Load saved search sql files into the DB. |
959528d2 | 194 | */ |
00be9182 | 195 | public function loadSavedSearches() { |
959528d2 | 196 | foreach (glob(dirname(__FILE__) . "/SavedSearchDataSets/*.sql") as $file) { |
e95fbe72 | 197 | CRM_Utils_File::sourceSQLFile(NULL, $file); |
959528d2 EM |
198 | } |
199 | } | |
200 | ||
201 | /** | |
9b1e4469 | 202 | * Check we can load smart groups based on config from 'real DBs' without fatal errors. |
203 | * | |
204 | * Note that we are only testing lack of errors at this stage | |
959528d2 EM |
205 | * @todo - for some reason the data was getting truncated from the group table using dataprovider - would be preferable to get that working |
206 | * //@notdataProvider dataProviderSavedSearch | |
207 | * //@notparam integer $groupID | |
208 | * | |
209 | * To add to this dataset do | |
210 | * | |
211 | * SET @groupID = x; | |
212 | * SELECT mapping_id FROM civicrm_group g LEFT JOIN civicrm_saved_search s ON saved_search_id = s.id WHERE g.id = @groupID INTO @mappingID; | |
959528d2 EM |
213 | * SELECT * FROM civicrm_mapping WHERE id = @mappingID; |
214 | * SELECT * FROM civicrm_mapping_field WHERE mapping_id = @mappingID; | |
215 | * SELECT * FROM civicrm_saved_search WHERE mapping_id = @mappingID; | |
216 | * SELECT g.* FROM civicrm_saved_search s LEFT JOIN civicrm_group g ON g.saved_search_id = s.id WHERE mapping_id = @mappingID; | |
217 | * | |
a455be55 | 218 | * Copy the output to a single sql file and place in the SavedSearchDataSets folder - use the group number as the prefix. |
959528d2 EM |
219 | * Try to keep as much of the real world irregular glory as you can! Don't change the table ids to be number 1 as this can hide errors |
220 | */ | |
00be9182 | 221 | public function testGroupData() { |
959528d2 EM |
222 | $groups = $this->dataProviderSavedSearch(); |
223 | foreach ($groups[0] as $groupID) { | |
224 | $group = new CRM_Contact_BAO_Group(); | |
225 | $group->id = $groupID; | |
226 | $group->find(TRUE); | |
a455be55 | 227 | |
4f39b1e6 | 228 | CRM_Contact_BAO_GroupContactCache::load($group); |
959528d2 EM |
229 | } |
230 | } | |
96025800 | 231 | |
1321b65b SL |
232 | /** |
233 | * Ensure that when updating a group with a linked organisation record even tho that record's id doesn't match the group id no db error is produced | |
234 | */ | |
235 | public function testGroupUpdateWithOrganization() { | |
9099cab3 | 236 | $params = [ |
1321b65b SL |
237 | 'name' => uniqid(), |
238 | 'title' => 'Group A', | |
239 | 'description' => 'Group One', | |
240 | 'visibility' => 'User and User Admin Only', | |
241 | 'is_active' => 1, | |
9099cab3 | 242 | ]; |
1321b65b SL |
243 | $group1 = CRM_Contact_BAO_Group::create($params); |
244 | ||
245 | $domain1 = $this->callAPISuccess('Domain', 'get', ['id' => 1]); | |
9099cab3 | 246 | $params2 = [ |
1321b65b SL |
247 | 'name' => uniqid(), |
248 | 'title' => 'Group B', | |
249 | 'description' => 'Group Two', | |
250 | 'visibility' => 'User and User Admin Only', | |
251 | 'is_active' => 1, | |
252 | 'organization_id' => $domain1['values'][1]['contact_id'], | |
9099cab3 | 253 | ]; |
1321b65b SL |
254 | $group2 = CRM_Contact_BAO_Group::create($params2); |
255 | ||
256 | $domain2 = $this->callAPISuccess('Domain', 'get', ['id' => 2]); | |
9099cab3 | 257 | $params3 = [ |
1321b65b SL |
258 | 'name' => uniqid(), |
259 | 'title' => 'Group C', | |
260 | 'description' => 'Group Three', | |
261 | 'visibility' => 'User and User Admin Only', | |
262 | 'is_active' => 1, | |
263 | 'organization_id' => $domain2['values'][2]['contact_id'], | |
9099cab3 | 264 | ]; |
1321b65b SL |
265 | $group3 = CRM_Contact_BAO_Group::create($params3); |
266 | $params2['id'] = $group2->id; | |
267 | $testUpdate = CRM_Contact_BAO_Group::create($params2); | |
268 | } | |
269 | ||
4f3d62b9 MD |
270 | /** |
271 | * Ensure that when hidden smart group is created, wildcard string value is not ignored | |
272 | */ | |
273 | public function testHiddenSmartGroup() { | |
274 | $customGroup = $this->customGroupCreate(); | |
9099cab3 | 275 | $fields = [ |
4f3d62b9 MD |
276 | 'label' => 'testFld', |
277 | 'data_type' => 'String', | |
278 | 'html_type' => 'Text', | |
279 | 'custom_group_id' => $customGroup['id'], | |
9099cab3 | 280 | ]; |
4f3d62b9 MD |
281 | $customFieldID = CRM_Core_BAO_CustomField::create($fields)->id; |
282 | ||
283 | $contactID = $this->individualCreate(['custom_' . $customFieldID => 'abc']); | |
284 | ||
285 | $hiddenSmartParams = [ | |
286 | 'group_type' => ['2' => 1], | |
24d5a341 | 287 | 'form_values' => ['custom_' . $customFieldID => ['LIKE' => '%a%']], |
4f3d62b9 MD |
288 | 'saved_search_id' => NULL, |
289 | 'search_custom_id' => NULL, | |
290 | 'search_context' => 'advanced', | |
291 | ]; | |
292 | list($smartGroupID, $savedSearchID) = CRM_Contact_BAO_Group::createHiddenSmartGroup($hiddenSmartParams); | |
293 | ||
294 | $mailingID = $this->callAPISuccess('Mailing', 'create', [])['id']; | |
9099cab3 | 295 | $this->callAPISuccess('MailingGroup', 'create', [ |
4f3d62b9 MD |
296 | 'mailing_id' => $mailingID, |
297 | 'group_type' => 'Include', | |
298 | 'entity_table' => 'civicrm_group', | |
299 | 'entity_id' => $smartGroupID, | |
9099cab3 | 300 | ]); |
4f3d62b9 MD |
301 | |
302 | CRM_Mailing_BAO_Mailing::getRecipients($mailingID); | |
303 | $recipients = $this->callAPISuccess('MailingRecipients', 'get', ['mailing_id' => $mailingID]); | |
304 | $this->assertEquals(1, $recipients['count'], 'Check recipient count'); | |
305 | } | |
306 | ||
e616e67d | 307 | /** |
308 | * Test updating a group with just description and check the recent items | |
309 | * list has the right title. | |
310 | */ | |
311 | public function testGroupUpdateDescription() { | |
312 | // Create a group. Copied from $this->testAddSimple(). | |
313 | // Note we need $checkParams because the function call changes $params. | |
314 | $checkParams = $params = [ | |
315 | 'title' => 'Group Uno', | |
316 | 'description' => 'Group One', | |
317 | 'visibility' => 'User and User Admin Only', | |
318 | 'is_active' => 1, | |
319 | ]; | |
320 | $group = CRM_Contact_BAO_Group::create($params); | |
321 | ||
322 | // Update the group with just id and description. | |
323 | $newParams = [ | |
324 | 'id' => $group->id, | |
325 | 'description' => 'The first group', | |
326 | ]; | |
327 | CRM_Contact_BAO_Group::create($newParams); | |
328 | ||
329 | // Check it against original array, except description. | |
330 | $result = $this->callAPISuccess('Group', 'getsingle', ['id' => $group->id]); | |
331 | foreach ($checkParams as $key => $value) { | |
332 | if ($key === 'description') { | |
333 | $this->assertEquals($newParams[$key], $result[$key], "$key doesn't match"); | |
334 | } | |
335 | else { | |
336 | $this->assertEquals($checkParams[$key], $result[$key], "$key doesn't match"); | |
337 | } | |
338 | } | |
339 | ||
340 | // Check recent items list. | |
341 | $recentItems = CRM_Utils_Recent::get(); | |
342 | $this->assertEquals($checkParams['title'], $recentItems[0]['title']); | |
343 | } | |
344 | ||
6a488035 | 345 | } |