Merge pull request #20499 from JMAConsulting/add_permission_fi_api4
[civicrm-core.git] / tests / phpunit / CRM / Contact / BAO / ActivitySearchTest.php
1 <?php
2 /**
3 * @file
4 * File for the ActivitySearchTest class
5 *
6 * (PHP 5)
7 *
8 * @copyright Copyright CiviCRM LLC (C) 2009
9 * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html
10 * GNU Affero General Public License version 3
11 * @package CiviCRM
12 *
13 * This file is part of CiviCRM
14 *
15 * CiviCRM is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU Affero General Public License
17 * as published by the Free Software Foundation; either version 3 of
18 * the License, or (at your option) any later version.
19 *
20 * CiviCRM is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU Affero General Public License for more details.
24 *
25 * You should have received a copy of the GNU Affero General Public
26 * License along with this program. If not, see
27 * <http://www.gnu.org/licenses/>.
28 */
29
30 /**
31 * Include class definitions
32 */
33
34 /**
35 * Test APIv3 civicrm_activity_* functions
36 *
37 * @package CiviCRM_APIv3
38 * @subpackage API_Activity
39 * @group headless
40 */
41 class CRM_Contact_BAO_ActivitySearchTest extends CiviUnitTestCase {
42
43 protected $_contactID;
44
45 protected $_params;
46
47 protected $test_activity_type_value;
48
49 /**
50 * Test setup for every test.
51 *
52 * Connect to the database, truncate the tables that will be used
53 * and redirect stdin to a temporary file
54 */
55 public function setUp(): void {
56 // Connect to the database
57 parent::setUp();
58
59 $this->_contactID = $this->individualCreate();
60 //create activity types
61 $activityTypes = $this->callAPISuccess('option_value', 'create', [
62 'option_group_id' => 2,
63 'name' => 'Test activity type',
64 'label' => 'Test activity type',
65 'sequential' => 1,
66 ]);
67 $this->test_activity_type_id = $activityTypes['id'];
68 $this->_params = [
69 'source_contact_id' => $this->_contactID,
70 'activity_type_id' => $activityTypes['values'][0]['value'],
71 'subject' => 'test activity type id',
72 'activity_date_time' => '2011-06-02 14:36:13',
73 'status_id' => 2,
74 'priority_id' => 1,
75 'duration' => 120,
76 'location' => 'Pennsylvania',
77 'details' => 'a test activity',
78 ];
79 // create a logged in USER since the code references it for source_contact_id
80 $this->createLoggedInUser();
81 }
82
83 /**
84 * Tears down the fixture, for example, closes a network connection.
85 *
86 * This method is called after a test is executed.
87 */
88 public function tearDown(): void {
89 $tablesToTruncate = [
90 'civicrm_contact',
91 'civicrm_activity',
92 'civicrm_activity_contact',
93 'civicrm_uf_match',
94 'civicrm_entity_tag',
95 ];
96 $this->quickCleanup($tablesToTruncate, TRUE);
97 $type = $this->callAPISuccess('optionValue', 'get', ['id' => $this->test_activity_type_id]);
98 if (!empty($type['count'])) {
99 $this->callAPISuccess('option_value', 'delete', ['id' => $this->test_activity_type_id]);
100 }
101 }
102
103 /**
104 * Test that activity.get api works when filtering on subject.
105 */
106 public function testSearchBySubjectOnly() {
107 $subject = 'test activity ' . __FUNCTION__;
108 $params = $this->_params;
109 $params['subject'] = $subject;
110 $this->callAPISuccess('Activity', 'Create', $params);
111
112 $case = [
113 'form_value' => [
114 'activity_text' => $subject,
115 'activity_option' => 3,
116 ],
117 'expected_count' => 1,
118 'expected_contact' => [$this->_contactID],
119 ];
120 $query = new CRM_Contact_BAO_Query(CRM_Contact_BAO_Query::convertFormValues($case['form_value']));
121 list($select, $from, $where, $having) = $query->query();
122 $groupContacts = CRM_Core_DAO::executeQuery("SELECT DISTINCT contact_a.id $from $where")->fetchAll();
123 foreach ($groupContacts as $key => $value) {
124 $groupContacts[$key] = $value['id'];
125 }
126 $this->assertEquals($case['expected_count'], count($groupContacts));
127 $this->checkArrayEquals($case['expected_contact'], $groupContacts);
128 }
129
130 /**
131 * Test that activity.get api works when filtering on subject.
132 */
133 public function testSearchBySubjectBoth() {
134 $subject = 'test activity ' . __FUNCTION__;
135 $params = $this->_params;
136 $params['subject'] = $subject;
137 $activity = $this->callAPISuccess('Activity', 'Create', $params);
138
139 $case = [
140 'form_value' => [
141 'activity_text' => $subject,
142 'activity_option' => 6,
143 ],
144 'expected_count' => 1,
145 'expected_contact' => [$this->_contactID],
146 ];
147 $query = new CRM_Contact_BAO_Query(CRM_Contact_BAO_Query::convertFormValues($case['form_value']));
148 list($select, $from, $where, $having) = $query->query();
149 $groupContacts = CRM_Core_DAO::executeQuery("SELECT DISTINCT contact_a.id $from $where")->fetchAll();
150 foreach ($groupContacts as $key => $value) {
151 $groupContacts[$key] = $value['id'];
152 }
153 $this->assertEquals($case['expected_count'], count($groupContacts));
154 $this->checkArrayEquals($case['expected_contact'], $groupContacts);
155 }
156
157 /**
158 * Test that activity.get api works when filtering on subject.
159 */
160 public function testSearchByDetailsOnly() {
161 $details = 'test activity ' . __FUNCTION__;
162 $params = $this->_params;
163 $params['details'] = $details;
164 $activity = $this->callAPISuccess('Activity', 'Create', $params);
165
166 $case = [
167 'form_value' => [
168 'activity_text' => $details,
169 'activity_option' => 2,
170 ],
171 'expected_count' => 1,
172 'expected_contact' => [$this->_contactID],
173 ];
174 $query = new CRM_Contact_BAO_Query(CRM_Contact_BAO_Query::convertFormValues($case['form_value']));
175 list($select, $from, $where, $having) = $query->query();
176 $groupContacts = CRM_Core_DAO::executeQuery("SELECT DISTINCT contact_a.id $from $where")->fetchAll();
177 foreach ($groupContacts as $key => $value) {
178 $groupContacts[$key] = $value['id'];
179 }
180 $this->assertEquals($case['expected_count'], count($groupContacts));
181 $this->checkArrayEquals($case['expected_contact'], $groupContacts);
182 }
183
184 /**
185 * Test that activity.get api works when filtering on details.
186 */
187 public function testSearchByDetailsBoth() {
188 $details = 'test activity ' . __FUNCTION__;
189 $params = $this->_params;
190 $params['details'] = $details;
191 $activity = $this->callAPISuccess('Activity', 'Create', $params);
192
193 $case = [
194 'form_value' => [
195 'activity_text' => $details,
196 'activity_option' => 6,
197 ],
198 'expected_count' => 1,
199 'expected_contact' => [$this->_contactID],
200 ];
201 $query = new CRM_Contact_BAO_Query(CRM_Contact_BAO_Query::convertFormValues($case['form_value']));
202 list($select, $from, $where, $having) = $query->query();
203 $groupContacts = CRM_Core_DAO::executeQuery("SELECT DISTINCT contact_a.id $from $where")->fetchAll();
204 foreach ($groupContacts as $key => $value) {
205 $groupContacts[$key] = $value['id'];
206 }
207 $this->assertEquals($case['expected_count'], count($groupContacts));
208 $this->checkArrayEquals($case['expected_contact'], $groupContacts);
209 }
210
211 /**
212 * Test that activity.get api works when filtering on bare tags (i.e. tags
213 * not part of a tagset).
214 */
215 public function testSearchByBareTags() {
216 $tag = $this->callAPISuccess('Tag', 'create', [
217 'name' => 'a1',
218 'used_for' => 'Activities',
219 ]);
220 $subject = 'test activity ' . __FUNCTION__;
221 $params = $this->_params;
222 $params['subject'] = $subject;
223 $activity = $this->callAPISuccess('Activity', 'Create', $params);
224 $this->callAPISuccess('EntityTag', 'create', [
225 'entity_id' => $activity['id'],
226 'entity_table' => 'civicrm_activity',
227 'tag_id' => 'a1',
228 ]);
229 $case = [
230 'form_value' => [
231 // It looks like it can be an array or comma-separated string.
232 // The qill will be slightly different ("IN" vs. "OR").
233 // The search form seems to use commas.
234 'activity_tags' => (string) $tag['id'],
235 ],
236 'expected_count' => 1,
237 'expected_contact' => [$this->_contactID],
238 ];
239 $query = new CRM_Contact_BAO_Query(CRM_Contact_BAO_Query::convertFormValues($case['form_value']));
240 list($select, $from, $where, $having) = $query->query();
241
242 $expectedQill = [
243 0 => [
244 0 => 'Activity Tag = a1',
245 ],
246 ];
247 $this->assertEquals($expectedQill, $query->_qill);
248
249 $groupContacts = CRM_Core_DAO::executeQuery("SELECT DISTINCT contact_a.id $from $where")->fetchAll();
250 foreach ($groupContacts as $key => $value) {
251 $groupContacts[$key] = $value['id'];
252 }
253 $this->assertEquals($case['expected_count'], count($groupContacts));
254 $this->checkArrayEquals($case['expected_contact'], $groupContacts);
255
256 // Clean up. Don't want to use teardown to wipe the table since then
257 // the stock tags get wiped.
258 $this->callAPISuccess('Tag', 'delete', ['id' => $tag['id']]);
259 }
260
261 /**
262 * Test that activity.get api works when filtering on a tag in a tagset.
263 */
264 public function testSearchByTagset() {
265 $tagset = $this->callAPISuccess('Tag', 'create', [
266 'name' => 'activity tagset',
267 'is_tagset' => 1,
268 'used_for' => 'Activities',
269 ]);
270 $tag = $this->callAPISuccess('Tag', 'create', [
271 'name' => 'aa1',
272 'used_for' => 'Activities',
273 'parent_id' => 'activity tagset',
274 ]);
275 $subject = 'test activity ' . __FUNCTION__;
276 $params = $this->_params;
277 $params['subject'] = $subject;
278 $activity = $this->callAPISuccess('Activity', 'Create', $params);
279 $this->callAPISuccess('EntityTag', 'create', [
280 'entity_id' => $activity['id'],
281 'entity_table' => 'civicrm_activity',
282 'tag_id' => 'aa1',
283 ]);
284 $case = [
285 'form_value' => [
286 // If multiple tags the array element value is a comma-separated string
287 // and then the qill looks like "IN a OR b".
288 "activity_taglist" => [$tagset['id'] => (string) $tag['id']],
289 ],
290 'expected_count' => 1,
291 'expected_contact' => [$this->_contactID],
292 ];
293 $query = new CRM_Contact_BAO_Query(CRM_Contact_BAO_Query::convertFormValues($case['form_value']));
294 list($select, $from, $where, $having) = $query->query();
295
296 $expectedQill = [
297 0 => [
298 0 => 'Activity Tag IN aa1',
299 ],
300 ];
301 $this->assertEquals($expectedQill, $query->_qill);
302
303 $groupContacts = CRM_Core_DAO::executeQuery("SELECT DISTINCT contact_a.id $from $where")->fetchAll();
304 foreach ($groupContacts as $key => $value) {
305 $groupContacts[$key] = $value['id'];
306 }
307 $this->assertEquals($case['expected_count'], count($groupContacts));
308 $this->checkArrayEquals($case['expected_contact'], $groupContacts);
309
310 // Clean up. Don't want to use teardown to wipe the table since then
311 // the stock tags get wiped.
312 $this->callAPISuccess('Tag', 'delete', ['id' => $tag['id']]);
313 }
314
315 }