Merge pull request #23101 from MegaphoneJon/core-1836-js
[civicrm-core.git] / tests / phpunit / api / v4 / Entity / SavedSearchTest.php
1 <?php
2
3 /*
4 +--------------------------------------------------------------------+
5 | Copyright CiviCRM LLC. All rights reserved. |
6 | |
7 | This work is published under the GNU AGPLv3 license with some |
8 | permitted exceptions and without any warranty. For full license |
9 | and copyright information, see https://civicrm.org/licensing |
10 +--------------------------------------------------------------------+
11 */
12
13 /**
14 *
15 * @package CRM
16 * @copyright CiviCRM LLC https://civicrm.org/licensing
17 */
18
19
20 namespace api\v4\Entity;
21
22 use api\v4\UnitTestCase;
23 use Civi\Api4\Contact;
24 use Civi\Api4\Email;
25
26 /**
27 * @group headless
28 */
29 class SavedSearchTest extends UnitTestCase {
30
31 /**
32 * @throws \API_Exception
33 * @throws \Civi\API\Exception\NotImplementedException
34 */
35 public function testContactSmartGroup(): void {
36 $in = Contact::create(FALSE)->addValue('first_name', 'yes')->addValue('do_not_phone', TRUE)->execute()->first();
37 $out = Contact::create(FALSE)->addValue('first_name', 'no')->addValue('do_not_phone', FALSE)->execute()->first();
38
39 $savedSearch = civicrm_api4('SavedSearch', 'create', [
40 'values' => [
41 'api_entity' => 'Contact',
42 'api_params' => [
43 'version' => 4,
44 'where' => [
45 ['do_not_phone', '=', TRUE],
46 ],
47 ],
48 ],
49 'chain' => [
50 'group' => ['Group', 'create', ['values' => ['title' => 'Contact Test', 'saved_search_id' => '$id']], 0],
51 ],
52 ])->first();
53
54 $ins = civicrm_api4('Contact', 'get', [
55 'where' => [['groups', 'IN', [$savedSearch['group']['id']]]],
56 ])->indexBy('id');
57 $this->assertCount(1, $ins);
58 $this->assertArrayHasKey($in['id'], (array) $ins);
59
60 $outs = civicrm_api4('Contact', 'get', [
61 'where' => [['groups', 'NOT IN', [$savedSearch['group']['id']]]],
62 ])->indexBy('id');
63 $this->assertArrayHasKey($out['id'], (array) $outs);
64 $this->assertArrayNotHasKey($in['id'], (array) $outs);
65 }
66
67 public function testEmailSmartGroup() {
68 $in = Contact::create(FALSE)->addValue('first_name', 'yep')->execute()->first();
69 $out = Contact::create(FALSE)->addValue('first_name', 'nope')->execute()->first();
70 $email = uniqid() . '@' . uniqid();
71 Email::create(FALSE)->addValue('email', $email)->addValue('contact_id', $in['id'])->execute();
72
73 $savedSearch = civicrm_api4('SavedSearch', 'create', [
74 'values' => [
75 'api_entity' => 'Email',
76 'api_params' => [
77 'version' => 4,
78 'select' => ['contact_id'],
79 'where' => [
80 ['email', '=', $email],
81 ],
82 ],
83 ],
84 'chain' => [
85 'group' => ['Group', 'create', ['values' => ['title' => 'Email Test', 'saved_search_id' => '$id']], 0],
86 ],
87 ])->first();
88
89 $ins = civicrm_api4('Contact', 'get', [
90 'where' => [['groups', 'IN', [$savedSearch['group']['id']]]],
91 ])->indexBy('id');
92 $this->assertCount(1, $ins);
93 $this->assertArrayHasKey($in['id'], (array) $ins);
94
95 $outs = civicrm_api4('Contact', 'get', [
96 'where' => [['groups', 'NOT IN', [$savedSearch['group']['id']]]],
97 ])->indexBy('id');
98 $this->assertArrayHasKey($out['id'], (array) $outs);
99 $this->assertArrayNotHasKey($in['id'], (array) $outs);
100 }
101
102 public function testSmartGroupWithHaving() {
103 $in = Contact::create(FALSE)->addValue('first_name', 'yes')->addValue('last_name', 'siree')->execute()->first();
104 $in2 = Contact::create(FALSE)->addValue('first_name', 'yessir')->addValue('last_name', 'ee')->execute()->first();
105 $out = Contact::create(FALSE)->addValue('first_name', 'yess')->execute()->first();
106
107 $savedSearch = civicrm_api4('SavedSearch', 'create', [
108 'values' => [
109 'api_entity' => 'Contact',
110 'api_params' => [
111 'version' => 4,
112 'select' => ['id', 'CONCAT(first_name, last_name) AS whole_name'],
113 'where' => [
114 ['id', '>=', $in['id']],
115 ],
116 'having' => [
117 ['whole_name', '=', 'yessiree'],
118 ],
119 ],
120 ],
121 'chain' => [
122 'group' => ['Group', 'create', ['values' => ['title' => 'Having Test', 'saved_search_id' => '$id']], 0],
123 ],
124 ])->first();
125
126 $ins = civicrm_api4('Contact', 'get', [
127 'where' => [['groups', 'IN', [$savedSearch['group']['id']]]],
128 ])->indexBy('id');
129 $this->assertCount(2, $ins);
130 $this->assertArrayHasKey($in['id'], (array) $ins);
131 $this->assertArrayHasKey($in2['id'], (array) $ins);
132
133 $outs = civicrm_api4('Contact', 'get', [
134 'where' => [['groups', 'NOT IN', [$savedSearch['group']['id']]]],
135 ])->indexBy('id');
136 $this->assertArrayHasKey($out['id'], (array) $outs);
137 $this->assertArrayNotHasKey($in['id'], (array) $outs);
138 $this->assertArrayNotHasKey($in2['id'], (array) $outs);
139 }
140
141 public function testMultipleSmartGroups() {
142 $inGroup = $outGroup = [];
143 $inName = uniqid('inGroup');
144 $outName = uniqid('outGroup');
145 for ($i = 0; $i < 10; ++$i) {
146 $inGroup[] = Contact::create(FALSE)
147 ->setValues(['first_name' => "$i", 'last_name' => $inName])
148 ->execute()->first()['id'];
149 $outGroup[] = Contact::create(FALSE)
150 ->setValues(['first_name' => "$i", 'last_name' => $outName])
151 ->execute()->first()['id'];
152 }
153
154 $parentGroupId = \Civi\Api4\Group::create(FALSE)
155 ->setValues(['title' => uniqid()])
156 ->execute()->first()['id'];
157
158 $savedSearchA = civicrm_api4('SavedSearch', 'create', [
159 'values' => [
160 'api_entity' => 'Contact',
161 'api_params' => [
162 'version' => 4,
163 'where' => [
164 ['last_name', '=', $inName],
165 ],
166 ],
167 ],
168 'chain' => [
169 'group' => ['Group', 'create', ['values' => ['parents' => [$parentGroupId], 'title' => 'In A Test', 'saved_search_id' => '$id']], 0],
170 ],
171 ])->first();
172
173 $savedSearchB = civicrm_api4('SavedSearch', 'create', [
174 'values' => [
175 'api_entity' => 'Contact',
176 'api_params' => [
177 'version' => 4,
178 'where' => [
179 ['last_name', 'IN', [$inName, $outName]],
180 ['first_name', '>', '4'],
181 ],
182 ],
183 ],
184 'chain' => [
185 'group' => ['Group', 'create', ['values' => ['parents' => [$parentGroupId], 'title' => 'In B Test', 'saved_search_id' => '$id']], 0],
186 ],
187 ])->first();
188
189 $bothGroups = civicrm_api4('Contact', 'get', [
190 'where' => [['groups:name', 'IN', [$savedSearchA['group']['name'], $savedSearchB['group']['name']]]],
191 ]);
192 $this->assertCount(15, $bothGroups);
193
194 // Parent group includes both groups a & b so should give the same results as above
195 $parentGroup = civicrm_api4('Contact', 'get', [
196 'where' => [['groups', 'IN', [$parentGroupId]]],
197 ]);
198 $this->assertCount(15, $parentGroup);
199
200 $aNotB = civicrm_api4('Contact', 'get', [
201 'where' => [
202 ['groups:name', 'IN', [$savedSearchA['group']['name']]],
203 ['groups:name', 'NOT IN', [$savedSearchB['group']['name']]],
204 ],
205 ]);
206 $this->assertCount(5, $aNotB);
207 }
208
209 }