Merge pull request #15970 from eileenmcnaughton/ex_easy
[civicrm-core.git] / tests / phpunit / CRM / Contact / BAO / GroupContactTest.php
1 <?php
2 /*
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 +--------------------------------------------------------------------+
10 */
11
12 /**
13 * Test class for CRM_Contact_BAO_GroupContact BAO
14 *
15 * @package CiviCRM
16 * @group headless
17 */
18 class CRM_Contact_BAO_GroupContactTest extends CiviUnitTestCase {
19
20 /**
21 * Sets up the fixture, for example, opens a network connection.
22 * This method is called before a test is executed.
23 */
24 protected function setUp() {
25 parent::setUp();
26 }
27
28 /**
29 * Tears down the fixture, for example, closes a network connection.
30 *
31 * This method is called after a test is executed.
32 */
33 protected function tearDown() {
34 }
35
36 /**
37 * Test case for add( ).
38 */
39 public function testAdd() {
40
41 //creates a test group contact by recursively creation
42 //lets create 10 groupContacts for fun
43 $groupContacts = CRM_Core_DAO::createTestObject('CRM_Contact_DAO_GroupContact', NULL, 10);
44
45 //check the group contact id is not null for each of them
46 foreach ($groupContacts as $gc) {
47 $this->assertNotNull($gc->id);
48 }
49
50 //cleanup
51 foreach ($groupContacts as $gc) {
52 $gc->deleteTestObjects('CRM_Contact_DAO_GroupContact');
53 }
54 }
55
56 /**
57 * Test case for getGroupId( )
58 */
59 public function testGetGroupId() {
60
61 //creates a test groupContact object
62 //force group_id to 1 so we can compare
63 $groupContact = CRM_Core_DAO::createTestObject('CRM_Contact_DAO_GroupContact');
64
65 //check the group contact id is not null
66 $this->assertNotNull($groupContact->id);
67
68 $groupId = CRM_Core_DAO::singleValueQuery('select max(id) from civicrm_group');
69
70 $this->assertEquals($groupContact->group_id, $groupId, 'Check for group_id');
71
72 //cleanup
73 $groupContact->deleteTestObjects('CRM_Contact_DAO_GroupContact');
74 }
75
76 /**
77 * Test case for contact search: CRM-6706, CRM-6586 Parent Group search should return contacts from child groups too.
78 *
79 * @throws \Exception
80 */
81 public function testContactSearchByParentGroup() {
82 // create a parent group
83 $parentGroup = $this->callAPISuccess('Group', 'create', [
84 'title' => 'Parent Group',
85 'description' => 'Parent Group',
86 'visibility' => 'User and User Admin Only',
87 'is_active' => 1,
88 ]);
89
90 // create a child group
91 $childGroup = $this->callAPISuccess('Group', 'create', [
92 'title' => 'Child Group',
93 'description' => 'Child Group',
94 'visibility' => 'User and User Admin Only',
95 'parents' => $parentGroup['id'],
96 'is_active' => 1,
97 ]);
98
99 // create smart group based on saved criteria Gender = Male
100 $batch = $this->callAPISuccess('SavedSearch', 'create', [
101 'form_values' => 'a:1:{i:0;a:5:{i:0;s:9:"gender_id";i:1;s:1:"=";i:2;i:2;i:3;i:0;i:4;i:0;}}',
102 ]);
103 // Create contact with Gender - Male
104 $childSmartGroupContact = $this->individualCreate([
105 'gender_id' => "Male",
106 'first_name' => 'C',
107 ], 1);
108 // then create smart group
109 $childSmartGroup = $this->callAPISuccess('Group', 'create', [
110 'title' => 'Child Smart Group',
111 'description' => 'Child Smart Group',
112 'visibility' => 'User and User Admin Only',
113 'saved_search_id' => $batch['id'],
114 'is_active' => 1,
115 'parents' => $parentGroup['id'],
116 ]);
117
118 $this->callAPISuccess('Group', 'create', [
119 'id' => $parentGroup['id'],
120 'children' => implode(',', [$childGroup['id'], $childSmartGroup['id']]),
121 ]);
122
123 // Create a contact within parent group
124 $parentContactParams = [
125 'first_name' => 'Parent1 Fname',
126 'last_name' => 'Parent1 Lname',
127 'group' => [$parentGroup['id'] => 1],
128 ];
129 $parentContact = $this->individualCreate($parentContactParams);
130
131 // create a contact within child dgroup
132 $childContactParams = [
133 'first_name' => 'Child1 Fname',
134 'last_name' => 'Child2 Lname',
135 'group' => [$childGroup['id'] => 1],
136 ];
137 $childContact = $this->individualCreate($childContactParams);
138
139 // Check if searching by parent group returns both parent and child group contacts
140 $result = $this->callAPISuccess('contact', 'get', [
141 'group' => $parentGroup['id'],
142 ]);
143 $validContactIds = [$parentContact, $childContact];
144 $resultContactIds = [];
145 foreach ($result['values'] as $k => $v) {
146 $resultContactIds[] = $v['contact_id'];
147 }
148 $this->assertEquals(3, count($resultContactIds), 'Check the count of returned values');
149 $this->assertEquals([], array_diff($validContactIds, $resultContactIds), 'Check that the difference between two arrays should be blank array');
150
151 // Check if searching by child group returns just child group contacts
152 $result = $this->callAPISuccess('contact', 'get', [
153 'group' => $childGroup['id'],
154 ]);
155 $validChildContactIds = [$childContact];
156 $resultChildContactIds = [];
157 foreach ($result['values'] as $k => $v) {
158 $resultChildContactIds[] = $v['contact_id'];
159 }
160 $this->assertEquals(1, count($resultChildContactIds), 'Check the count of returned values');
161 $this->assertEquals([], array_diff($validChildContactIds, $resultChildContactIds), 'Check that the difference between two arrays should be blank array');
162
163 // Check if searching by smart child group returns just smart child group contacts
164 $result = $this->callAPISuccess('contact', 'get', [
165 'group' => $childSmartGroup['id'],
166 ]);
167 $validChildContactIds = [$childSmartGroupContact];
168 $resultChildContactIds = [];
169 foreach ($result['values'] as $k => $v) {
170 $resultChildContactIds[] = $v['contact_id'];
171 }
172 $this->assertEquals(1, count($resultChildContactIds), 'Check the count of returned values');
173 $this->assertEquals([], array_diff($validChildContactIds, $resultChildContactIds), 'Check that the difference between two arrays should be blank array');
174
175 //cleanup
176 $this->callAPISuccess('Contact', 'delete', ['id' => $parentContact]);
177 $this->callAPISuccess('Contact', 'delete', ['id' => $childContact]);
178 $this->callAPISuccess('Contact', 'delete', ['id' => $childSmartGroupContact]);
179 }
180
181 /**
182 * CRM-19698: Test case for combine contact search in regular and smart group
183 */
184 public function testContactCombineGroupSearch() {
185 // create regular group based
186 $regularGroup = $this->callAPISuccess('Group', 'create', [
187 'title' => 'Regular Group',
188 'description' => 'Regular Group',
189 'visibility' => 'User and User Admin Only',
190 'is_active' => 1,
191 ]);
192
193 // Create contact with Gender - Male
194 $contact1 = $this->individualCreate([
195 'gender_id' => "Male",
196 'first_name' => 'A',
197 ]);
198
199 // Create contact with Gender - Male and in regular group
200 $contact2 = $this->individualCreate([
201 'group' => [$regularGroup['id'] => 1],
202 'gender_id' => "Male",
203 'first_name' => 'B',
204 ], 1);
205
206 // Create contact with Gender - Female and in regular group
207 $contact3 = $this->individualCreate([
208 'group' => [$regularGroup['id'] => 1],
209 'gender_id' => "Female",
210 'first_name' => 'C',
211 ], 1);
212
213 // create smart group based on saved criteria Gender = Male
214 $batch = $this->callAPISuccess('SavedSearch', 'create', [
215 'form_values' => 'a:1:{i:0;a:5:{i:0;s:9:"gender_id";i:1;s:1:"=";i:2;i:2;i:3;i:0;i:4;i:0;}}',
216 ]);
217 $smartGroup = $this->callAPISuccess('Group', 'create', [
218 'title' => 'Smart Group',
219 'description' => 'Smart Group',
220 'visibility' => 'User and User Admin Only',
221 'saved_search_id' => $batch['id'],
222 'is_active' => 1,
223 ]);
224
225 $useCases = [
226 //Case 1: Find all contacts in regular group
227 [
228 'form_value' => ['group' => $regularGroup['id']],
229 'expected_count' => 2,
230 'expected_contact' => [$contact2, $contact3],
231 ],
232 //Case 2: Find all contacts in smart group
233 [
234 'form_value' => ['group' => $smartGroup['id']],
235 'expected_count' => 2,
236 'expected_contact' => [$contact1, $contact2],
237 ],
238 //Case 3: Find all contacts in regular group and smart group
239 [
240 'form_value' => ['group' => ['IN' => [$regularGroup['id'], $smartGroup['id']]]],
241 'expected_count' => 3,
242 'expected_contact' => [$contact1, $contact2, $contact3],
243 ],
244 ];
245 foreach ($useCases as $case) {
246 $query = new CRM_Contact_BAO_Query(CRM_Contact_BAO_Query::convertFormValues($case['form_value']));
247 list($select, $from, $where, $having) = $query->query();
248 $groupContacts = CRM_Core_DAO::executeQuery("SELECT DISTINCT contact_a.* $from $where ORDER BY contact_a.first_name")->fetchAll();
249 foreach ($groupContacts as $key => $value) {
250 $groupContacts[$key] = $value['id'];
251 }
252 $this->assertEquals($case['expected_count'], count($groupContacts));
253 $this->checkArrayEquals($case['expected_contact'], $groupContacts);
254 }
255 }
256
257 /**
258 * CRM-19333: Test case for contact search on basis of group type
259 */
260 public function testbyGroupType() {
261 $groupTypes = CRM_Core_BAO_OptionValue::getOptionValuesAssocArrayFromName('group_type');
262 $mailingListGT = array_search('Mailing List', $groupTypes);
263 $accessControlGT = array_search('Access Control', $groupTypes);
264
265 // create group with group type - Mailing list
266 $group1 = $this->callAPISuccess('Group', 'create', [
267 'title' => 'Group 1',
268 'visibility' => 'User and User Admin Only',
269 'is_active' => 1,
270 'group_type' => $mailingListGT,
271 ]);
272
273 // create group with group type - Access Control
274 $group2 = $this->callAPISuccess('Group', 'create', [
275 'title' => 'Group 2',
276 'visibility' => 'User and User Admin Only',
277 'is_active' => 1,
278 'group_type' => $accessControlGT,
279 ]);
280
281 // create contact in 'Group 1'
282 $contact1 = $this->individualCreate([
283 'group' => [$group1['id'] => 1],
284 'first_name' => 'A',
285 ]);
286
287 // create contact in 'Group 2'
288 $contact2 = $this->individualCreate([
289 'group' => [$group2['id'] => 1],
290 'first_name' => 'B',
291 ], 1);
292
293 $useCases = [
294 //Case 1: Find contacts in group type - Mailing List
295 [
296 'form_value' => ['group_type' => [$mailingListGT]],
297 'expected_count' => 1,
298 'expected_contact' => [$contact1],
299 ],
300 //Case 2: Find contacts in group type - Access Control
301 [
302 'form_value' => ['group_type' => [$accessControlGT]],
303 'expected_count' => 1,
304 'expected_contact' => [$contact2],
305 ],
306 //Case 3: Find contacts in group type - Mailing List or Access List
307 [
308 'form_value' => ['group_type' => [$mailingListGT, $accessControlGT]],
309 'expected_count' => 2,
310 'expected_contact' => [$contact1, $contact2],
311 ],
312 ];
313
314 foreach ($useCases as $case) {
315 $query = new CRM_Contact_BAO_Query(CRM_Contact_BAO_Query::convertFormValues($case['form_value']));
316 list($select, $from, $where, $having) = $query->query();
317 $groupContacts = CRM_Core_DAO::executeQuery("SELECT DISTINCT contact_a.id, contact_a.first_name $from $where ORDER BY contact_a.first_name")->fetchAll();
318 foreach ($groupContacts as $key => $value) {
319 $groupContacts[$key] = $value['id'];
320 }
321 $this->assertEquals($case['expected_count'], count($groupContacts));
322 $this->checkArrayEquals($case['expected_contact'], $groupContacts);
323 }
324 }
325
326 }