Commit | Line | Data |
---|---|---|
6a488035 TO |
1 | <?php |
2 | /** | |
3 | * File for the TestCase class | |
4 | * | |
5 | * (PHP 5) | |
6 | * | |
7 | * @author Walt Haas <walt@dharmatech.org> (801) 534-1262 | |
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 | * @version $Id: ActivityTest.php 31254 2010-12-15 10:09:29Z eileen $ | |
12 | * @package CiviCRM | |
13 | * | |
14 | * This file is part of CiviCRM | |
15 | * | |
16 | * CiviCRM is free software; you can redistribute it and/or | |
17 | * modify it under the terms of the GNU Affero General Public License | |
18 | * as published by the Free Software Foundation; either version 3 of | |
19 | * the License, or (at your option) any later version. | |
20 | * | |
21 | * CiviCRM is distributed in the hope that it will be useful, | |
22 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
23 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
24 | * GNU Affero General Public License for more details. | |
25 | * | |
26 | * You should have received a copy of the GNU Affero General Public | |
27 | * License along with this program. If not, see | |
28 | * <http://www.gnu.org/licenses/>. | |
29 | */ | |
30 | ||
31 | /** | |
32 | * Include class definitions | |
33 | */ | |
34 | require_once 'CiviTest/CiviUnitTestCase.php'; | |
35 | ||
36 | /** | |
37 | * Test APIv3 civicrm_case_* functions | |
38 | * | |
39 | * @package CiviCRM_APIv3 | |
40 | */ | |
41 | class api_v3_CaseTest extends CiviUnitTestCase { | |
42 | protected $_params; | |
43 | protected $_entity; | |
4e420887 | 44 | protected $_apiversion =3; |
6a488035 TO |
45 | protected $followup_activity_type_value; |
46 | protected $caseTypeId; | |
47 | protected $caseStatusGroup; | |
48 | protected $caseTypeGroup; | |
49 | protected $optionValues; | |
50 | public $_eNoticeCompliant = TRUE; | |
51 | /** | |
52 | * Test setup for every test | |
53 | * | |
54 | * Connect to the database, truncate the tables that will be used | |
55 | * and redirect stdin to a temporary file | |
56 | */ | |
57 | public function setUp() { | |
6a488035 TO |
58 | $this->_entity = 'case'; |
59 | ||
60 | parent::setUp(); | |
61 | // CRM-9404 - set-up is a bit cumbersome but had to put something in place to set up activity types & case types | |
62 | //. Using XML was causing breakage as id numbers were changing over time | |
63 | // & was really hard to troubleshoot as involved truncating option_value table to mitigate this & not leaving DB in a | |
64 | // state where tests could run afterwards without re-loading. | |
4e420887 | 65 | $this->caseStatusGroup = $this->callAPISuccess('option_group', 'get', array( |
66 | 'name' => 'case_status', | |
67 | 'format.only_id' => 1) | |
68 | ); | |
69 | $this->caseTypeGroup = $this->callAPISuccess('option_group', 'get', array( | |
70 | 'name' => 'case_type', | |
71 | 'format.only_id' => 1) | |
72 | ); | |
73 | $caseTypes = $this->callAPISuccess('option_value', 'Create', array( | |
6a488035 TO |
74 | 'option_group_id' => $this->caseTypeGroup, |
75 | 'name' => 'housing_support', | |
76 | 'label' => "Housing Support", | |
77 | 'sequential' => 1, | |
78 | 'description' => 'Help homeless individuals obtain temporary and long-term housing', | |
79 | )); | |
80 | ||
81 | $this->caseTypeId = $caseTypes['values'][0]['value']; | |
82 | $this->optionValues[] = $caseTypes['id']; | |
83 | $optionValues = array( | |
84 | 'Medical evaluation' => 'Medical evaluation', | |
85 | 'Mental health evaluation' => "Mental health evaluation", | |
86 | 'Secure temporary housing' => 'Secure temporary housing', | |
87 | 'Long-term housing plan' => 'Long-term housing plan', | |
88 | 'ADC referral' => 'ADC referral', | |
89 | 'Income and benefits stabilization' => 'Income and benefits stabilization', | |
90 | ); | |
91 | foreach ($optionValues as $name => $label) { | |
4e420887 | 92 | $activityTypes = $this->callAPISuccess('option_value', 'Create', array( |
6a488035 TO |
93 | 'option_group_id' => 2, |
94 | 'name' => $name, | |
95 | 'label' => $label, | |
96 | 'component_id' => 7, | |
97 | )); | |
98 | // store for cleanup | |
99 | $this->optionValues[] = $activityTypes['id']; | |
100 | } | |
101 | $tablesToTruncate = array( | |
102 | 'civicrm_activity', | |
103 | 'civicrm_contact', | |
104 | 'civicrm_custom_group', | |
105 | 'civicrm_custom_field', | |
106 | 'civicrm_case', | |
107 | 'civicrm_case_contact', | |
108 | 'civicrm_case_activity', | |
b319d00a | 109 | 'civicrm_activity_contact', |
6a488035 TO |
110 | 'civicrm_relationship', |
111 | 'civicrm_relationship_type', | |
112 | ); | |
113 | ||
114 | $this->quickCleanup($tablesToTruncate); | |
115 | ||
4e420887 | 116 | $activityTypes = $this->callAPISuccess('option_value', 'get', array( |
117 | 'option_group_id' => 2, | |
118 | 'name' => 'Follow Up', | |
119 | 'label' => 'Follow Up', | |
120 | 'sequential' => 1, | |
121 | )); | |
6a488035 TO |
122 | $this->followup_activity_type_value = $activityTypes['values'][0]['value']; |
123 | // Insert a row in civicrm_contact creating contact 17 | |
124 | $op = new PHPUnit_Extensions_Database_Operation_Insert(); | |
125 | $op->execute($this->_dbconn, | |
126 | new PHPUnit_Extensions_Database_DataSet_XMLDataSet( | |
127 | dirname(__FILE__) . '/dataset/contact_17.xml' | |
128 | ) | |
129 | ); | |
130 | ||
131 | //Create relationship types | |
132 | $relTypeParams = array( | |
133 | 'name_a_b' => 'Case Coordinator is', | |
134 | 'label_a_b' => 'Case Coordinator is', | |
135 | 'name_b_a' => 'Case Coordinator', | |
136 | 'label_b_a' => 'Case Coordinator', | |
137 | 'description' => 'Case Coordinator', | |
138 | 'contact_type_a' => 'Individual', | |
139 | 'contact_type_b' => 'Individual', | |
140 | 'is_reserved' => 0, | |
141 | 'is_active' => 1, | |
6a488035 TO |
142 | ); |
143 | $this->relationshipTypeCreate($relTypeParams); | |
144 | ||
145 | $relTypeParams = array( | |
146 | 'name_a_b' => 'Homeless Services Coordinator is', | |
147 | 'label_a_b' => 'Homeless Services Coordinator is', | |
148 | 'name_b_a' => 'Homeless Services Coordinator', | |
149 | 'label_b_a' => 'Homeless Services Coordinator', | |
150 | 'description' => 'Homeless Services Coordinator', | |
151 | 'contact_type_a' => 'Individual', | |
152 | 'contact_type_b' => 'Individual', | |
153 | 'is_reserved' => 0, | |
154 | 'is_active' => 1, | |
6a488035 TO |
155 | ); |
156 | $this->relationshipTypeCreate($relTypeParams); | |
157 | ||
158 | $relTypeParams = array( | |
159 | 'name_a_b' => 'Health Services Coordinator is', | |
160 | 'label_a_b' => 'Health Services Coordinator is', | |
161 | 'name_b_a' => 'Health Services Coordinator', | |
162 | 'label_b_a' => 'Health Services Coordinator', | |
163 | 'description' => 'Health Services Coordinator', | |
164 | 'contact_type_a' => 'Individual', | |
165 | 'contact_type_b' => 'Individual', | |
166 | 'is_reserved' => 0, | |
167 | 'is_active' => 1, | |
6a488035 TO |
168 | ); |
169 | $this->relationshipTypeCreate($relTypeParams); | |
170 | ||
171 | $relTypeParams = array( | |
172 | 'name_a_b' => 'Senior Services Coordinator is', | |
173 | 'label_a_b' => 'Senior Services Coordinator is', | |
174 | 'name_b_a' => 'Senior Services Coordinator', | |
175 | 'label_b_a' => 'Senior Services Coordinator', | |
176 | 'description' => 'Senior Services Coordinator', | |
177 | 'contact_type_a' => 'Individual', | |
178 | 'contact_type_b' => 'Individual', | |
179 | 'is_reserved' => 0, | |
180 | 'is_active' => 1, | |
6a488035 TO |
181 | ); |
182 | $this->relationshipTypeCreate($relTypeParams); | |
183 | ||
184 | $relTypeParams = array( | |
185 | 'name_a_b' => 'Benefits Specialist is', | |
186 | 'label_a_b' => 'Benefits Specialist is', | |
187 | 'name_b_a' => 'Benefits Specialist', | |
188 | 'label_b_a' => 'Benefits Specialist', | |
189 | 'description' => 'Benefits Specialist', | |
190 | 'contact_type_a' => 'Individual', | |
191 | 'contact_type_b' => 'Individual', | |
192 | 'is_reserved' => 0, | |
193 | 'is_active' => 1, | |
6a488035 TO |
194 | ); |
195 | $this->relationshipTypeCreate($relTypeParams); | |
196 | ||
197 | // enable the default custom templates for the case type xml files | |
198 | $this->customDirectories(array('template_path' => TRUE)); | |
199 | ||
200 | // case is not enabled by default | |
6a488035 TO |
201 | $enableResult = CRM_Core_BAO_ConfigSetting::enableComponent('CiviCase'); |
202 | $this->assertTrue($enableResult, 'Cannot enable CiviCase in line ' . __LINE__); | |
203 | ||
204 | $this->_params = array( | |
205 | 'case_type_id' => $this->caseTypeId, | |
206 | 'subject' => 'Test case', | |
207 | 'contact_id' => 17, | |
6a488035 TO |
208 | ); |
209 | ||
210 | // create a logged in USER since the code references it for source_contact_id | |
211 | $this->createLoggedInUser(); | |
212 | $session = CRM_Core_Session::singleton(); | |
213 | $this->_loggedInUser = $session->get('userID'); | |
214 | /// note that activityType options are cached by the FULL set of options you pass in | |
215 | // ie. because Activity api includes campaign in it's call cache is not flushed unless | |
216 | // included in this call. Also note flush function doesn't work on this property as it sets to null not empty array | |
217 | CRM_Core_PseudoConstant::activityType(TRUE, TRUE, TRUE, 'name', TRUE); | |
218 | } | |
219 | ||
220 | /** | |
221 | * Tears down the fixture, for example, closes a network connection. | |
222 | * This method is called after a test is executed. | |
223 | * | |
224 | * @access protected | |
225 | */ | |
226 | function tearDown() { | |
227 | foreach ($this->optionValues as $id) { | |
4e420887 | 228 | $this->callAPISuccess('option_value', 'delete', array('id' => $id)); |
6a488035 TO |
229 | } |
230 | $tablesToTruncate = array( | |
231 | 'civicrm_contact', | |
232 | 'civicrm_activity', | |
233 | 'civicrm_case', | |
234 | 'civicrm_case_contact', | |
235 | 'civicrm_case_activity', | |
b319d00a | 236 | 'civicrm_activity_contact', |
6a488035 TO |
237 | 'civicrm_relationship', |
238 | 'civicrm_relationship_type', | |
239 | ); | |
240 | $this->quickCleanup($tablesToTruncate, TRUE); | |
241 | ||
242 | $this->customDirectories(array('template_path' => FALSE)); | |
243 | } | |
244 | ||
245 | /** | |
246 | * check with empty array | |
247 | */ | |
248 | function testCaseCreateEmpty() { | |
4e420887 | 249 | $result = $this->callAPIFailure('case', 'create', array()); |
6a488035 TO |
250 | } |
251 | ||
252 | /** | |
253 | * check if required fields are not passed | |
254 | */ | |
255 | function testCaseCreateWithoutRequired() { | |
256 | $params = array( | |
257 | 'subject' => 'this case should fail', | |
258 | 'case_type_id' => 1, | |
6a488035 TO |
259 | ); |
260 | ||
4e420887 | 261 | $result = $this->callAPIFailure('case', 'create', $params); |
6a488035 TO |
262 | } |
263 | ||
264 | /** | |
265 | * Test create function with valid parameters | |
266 | */ | |
267 | function testCaseCreate() { | |
268 | // Create Case | |
269 | $params = $this->_params; | |
270 | // Test using label instead of value | |
271 | unset($params['case_type_id']); | |
272 | $params['case_type'] = 'Housing Support'; | |
4e420887 | 273 | $result = $this->callAPISuccess('case', 'create', $params); |
6a488035 TO |
274 | $id = $result['id']; |
275 | ||
276 | // Check result | |
4e420887 | 277 | $result = $this->callAPISuccess('case', 'get', array('id' => $id)); |
6a488035 TO |
278 | $this->assertEquals($result['values'][$id]['id'], 1, 'in line ' . __LINE__); |
279 | $this->assertEquals($result['values'][$id]['case_type_id'], $this->caseTypeId, 'in line ' . __LINE__); | |
280 | $this->assertEquals($result['values'][$id]['subject'], $params['subject'], 'in line ' . __LINE__); | |
281 | } | |
282 | ||
283 | /** | |
284 | * Test update (create with id) function with valid parameters | |
285 | */ | |
286 | function testCaseUpdate() { | |
287 | // Create Case | |
6a77ff3d CW |
288 | $params = $this->_params; |
289 | // Test using name instead of value | |
290 | $params['case_type_id'] = 'housing_support'; | |
4e420887 | 291 | $result = $this->callAPISuccess('case', 'create', $params); |
6a488035 | 292 | $id = $result['id']; |
4e420887 | 293 | $result = $this->callAPISuccess('case', 'get', array('id' => $id)); |
6a488035 TO |
294 | $case = $result['values'][$id]; |
295 | ||
296 | // Update Case | |
4e420887 | 297 | $params = array('id' => $id); |
6a488035 | 298 | $params['subject'] = $case['subject'] = 'Something Else'; |
4e420887 | 299 | $result = $this->callAPISuccess('case', 'create', $params); |
6a488035 TO |
300 | |
301 | // Verify that updated case is exactly equal to the original with new subject | |
4e420887 | 302 | $result = $this->callAPISuccess('case', 'get', array('case_id' => $id)); |
6a488035 TO |
303 | $this->assertEquals($result['values'][$id], $case, 'in line ' . __LINE__); |
304 | } | |
305 | ||
306 | /** | |
307 | * Test delete function with valid parameters | |
308 | */ | |
309 | function testCaseDelete() { | |
310 | // Create Case | |
4e420887 | 311 | $result = $this->callAPISuccess('case', 'create', $this->_params); |
6a488035 TO |
312 | |
313 | // Move Case to Trash | |
314 | $id = $result['id']; | |
4e420887 | 315 | $result = $this->callAPISuccess('case', 'delete', array('id' => $id, 'move_to_trash' => 1)); |
6a488035 TO |
316 | |
317 | // Check result - also check that 'case_id' works as well as 'id' | |
4e420887 | 318 | $result = $this->callAPISuccess('case', 'get', array('case_id' => $id)); |
6a488035 TO |
319 | $this->assertEquals(1, $result['values'][$id]['is_deleted'], 'in line ' . __LINE__); |
320 | ||
321 | // Delete Case Permanently - also check that 'case_id' works as well as 'id' | |
4e420887 | 322 | $result = $this->callAPISuccess('case', 'delete', array('case_id' => $id)); |
6a488035 TO |
323 | |
324 | // Check result - case should no longer exist | |
4e420887 | 325 | $result = $this->callAPISuccess('case', 'get', array('id' => $id)); |
326 | $this->assertEquals(0, $result['count']); | |
6a488035 TO |
327 | } |
328 | ||
329 | /** | |
330 | * Test get function based on activity | |
331 | */ | |
332 | function testCaseGetByActivity() { | |
333 | // Create Case | |
4e420887 | 334 | $result = $this->callAPISuccess('case', 'create', $this->_params); |
6a488035 TO |
335 | $id = $result['id']; |
336 | ||
337 | // Check result - we should get a list of activity ids | |
4e420887 | 338 | $result = $this->callAPISuccess('case', 'get', array('id' => $id)); |
6a488035 TO |
339 | $case = $result['values'][$id]; |
340 | $activity = $case['activities'][0]; | |
341 | ||
342 | // Fetch case based on an activity id | |
4e420887 | 343 | $result = $this->callAPISuccess('case', 'get', array('activity_id' => $activity, 'return' => 'activities,contacts')); |
6a488035 TO |
344 | $this->assertEquals(FALSE, empty($result['values'][$id]), 'in line ' . __LINE__); |
345 | $this->assertEquals($result['values'][$id], $case, 'in line ' . __LINE__); | |
346 | } | |
347 | ||
348 | /** | |
349 | * Test get function based on contact id | |
350 | */ | |
351 | function testCaseGetByContact() { | |
352 | // Create Case | |
4e420887 | 353 | $result = $this->callAPISuccess('case', 'create', $this->_params); |
6a488035 TO |
354 | $id = $result['id']; |
355 | ||
356 | // Store result for later | |
4e420887 | 357 | $case = $this->callAPISuccess('case', 'getsingle', array('id' => $id)); |
6a488035 TO |
358 | |
359 | // Fetch case based on client contact id | |
4e420887 | 360 | $result = $this->callAPISuccess('case', 'get', array('client_id' => $this->_params['contact_id'], 'return' => array('activities', 'contacts'))); |
361 | $this->assertAPIArrayComparison($result['values'][$id], $case); | |
6a488035 TO |
362 | } |
363 | ||
364 | /** | |
365 | * Test activity api create for case activities | |
366 | */ | |
367 | function testCaseActivityCreate() { | |
368 | // Create a case first | |
369 | $params = $this->_params; | |
4e420887 | 370 | $result = $this->callAPISuccess('case', 'create', $params); |
6a488035 TO |
371 | $params = array( |
372 | 'case_id' => 1, | |
373 | // follow up | |
374 | 'activity_type_id' => $this->followup_activity_type_value, | |
375 | 'subject' => 'Test followup', | |
376 | 'source_contact_id' => $this->_loggedInUser, | |
377 | 'target_contact_id' => $this->_params['contact_id'], | |
6a488035 | 378 | ); |
4e420887 | 379 | $result = $this->callAPISuccess('activity', 'create', $params); |
6a488035 TO |
380 | $this->assertEquals($result['values'][$result['id']]['activity_type_id'], $params['activity_type_id'], 'in line ' . __LINE__); |
381 | ||
382 | // might need this for other tests that piggyback on this one | |
383 | $this->_caseActivityId = $result['values'][$result['id']]['id']; | |
384 | ||
385 | // Check other DB tables populated properly - is there a better way to do this? assertDBState() requires that we know the id already. | |
4e420887 | 386 | $dao = new CRM_Case_DAO_CaseActivity(); |
387 | $dao->case_id = 1; | |
6a488035 TO |
388 | $dao->activity_id = $this->_caseActivityId; |
389 | $this->assertEquals($dao->find(), 1, 'case_activity table not populated correctly in line ' . __LINE__); | |
390 | $dao->free(); | |
391 | ||
b319d00a | 392 | $dao = new CRM_Activity_DAO_ActivityContact(); |
6a488035 | 393 | $dao->activity_id = $this->_caseActivityId; |
b319d00a DL |
394 | $dao->contact_id = $this->_params['contact_id']; |
395 | $dao->record_type_id = 3; | |
396 | $this->assertEquals($dao->find(), 1, 'activity_contact table not populated correctly in line ' . __LINE__); | |
6a488035 TO |
397 | $dao->free(); |
398 | ||
399 | // TODO: There's more things we could check | |
400 | } | |
401 | ||
402 | /** | |
403 | * Test activity api update for case activities | |
404 | */ | |
405 | function testCaseActivityUpdate() { | |
406 | // Need to create the case and activity before we can update it | |
407 | $this->testCaseActivityCreate(); | |
408 | ||
409 | $params = array( | |
410 | 'activity_id' => $this->_caseActivityId, | |
411 | 'case_id' => 1, | |
412 | 'activity_type_id' => 14, | |
413 | 'source_contact_id' => $this->_loggedInUser, | |
414 | 'subject' => 'New subject', | |
6a488035 | 415 | ); |
4e420887 | 416 | $result = $this->callAPISuccess('activity', 'create', $params); |
6a488035 | 417 | |
6a488035 TO |
418 | $this->assertEquals($result['values'][$result['id']]['subject'], $params['subject'], 'in line ' . __LINE__); |
419 | ||
420 | // id should be one greater, since this is a new revision | |
421 | $this->assertEquals($result['values'][$result['id']]['id'], | |
422 | $this->_caseActivityId + 1, | |
423 | 'in line ' . __LINE__ | |
424 | ); | |
425 | $this->assertEquals($result['values'][$result['id']]['original_id'], | |
426 | $this->_caseActivityId, | |
427 | 'in line ' . __LINE__ | |
428 | ); | |
429 | ||
430 | // Check revision is as expected | |
431 | $revParams = array( | |
432 | 'activity_id' => $this->_caseActivityId, | |
6a488035 | 433 | ); |
4e420887 | 434 | $revActivity = $this->callAPISuccess('activity', 'get', $revParams); |
6a488035 | 435 | $this->assertEquals($revActivity['values'][$this->_caseActivityId]['is_current_revision'], |
4e420887 | 436 | 0); |
6a488035 | 437 | $this->assertEquals($revActivity['values'][$this->_caseActivityId]['is_deleted'], |
4e420887 | 438 | 0 |
6a488035 TO |
439 | ); |
440 | ||
441 | //TODO: check some more things | |
442 | } | |
443 | ||
444 | function testCaseActivityUpdateCustom() { | |
445 | // Create a case first | |
4e420887 | 446 | $result = $this->callAPISuccess('case', 'create', $this->_params); |
6a488035 TO |
447 | |
448 | // Create custom field group | |
449 | // Note the second parameter is Activity on purpose, not Case. | |
450 | $custom_ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__, 'ActivityTest.php'); | |
451 | ||
452 | // create activity | |
453 | $params = array( | |
4e420887 | 454 | 'case_id' => $result['id'], |
6a488035 TO |
455 | // follow up |
456 | 'activity_type_id' => 14, | |
457 | 'subject' => 'Test followup', | |
458 | 'source_contact_id' => $this->_loggedInUser, | |
459 | 'target_contact_id' => $this->_params['contact_id'], | |
460 | 'custom_' . $custom_ids['custom_field_id'] => "custom string", | |
6a488035 | 461 | ); |
4e420887 | 462 | $result = $this->callAPISuccess('activity', 'create', $params); |
6a488035 TO |
463 | |
464 | $aid = $result['values'][$result['id']]['id']; | |
465 | ||
466 | // Update activity | |
467 | $params = array( | |
468 | 'activity_id' => $aid, | |
469 | 'case_id' => 1, | |
470 | 'activity_type_id' => 14, | |
471 | 'source_contact_id' => $this->_loggedInUser, | |
472 | 'subject' => 'New subject', | |
6a488035 | 473 | ); |
4e420887 | 474 | $revAct = $this->callAPISuccess('activity', 'create', $params); |
6a488035 TO |
475 | |
476 | // Retrieve revision and check custom fields got copied | |
477 | $revParams = array( | |
478 | 'activity_id' => $aid + 1, | |
6a488035 TO |
479 | 'return.custom_' . $custom_ids['custom_field_id'] => 1, |
480 | ); | |
4e420887 | 481 | $revAct = $this->callAPISuccess('activity', 'get', $revParams); |
6a488035 | 482 | |
6a488035 TO |
483 | $this->assertEquals($revAct['values'][$aid + 1]['custom_' . $custom_ids['custom_field_id']], "custom string", |
484 | "Error message: " . CRM_Utils_Array::value('error_message', $revAct) . ' in line ' . __LINE__ | |
485 | ); | |
486 | ||
487 | $this->customFieldDelete($custom_ids['custom_field_id']); | |
488 | $this->customGroupDelete($custom_ids['custom_group_id']); | |
489 | } | |
490 | } |