Merge pull request #3057 from agh1/counties-as-extensions
[civicrm-core.git] / tests / phpunit / api / v3 / CaseTest.php
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;
44 protected $_apiversion =3;
45 protected $followup_activity_type_value;
46 protected $caseTypeId;
47 protected $caseStatusGroup;
48 protected $optionValues;
49
50 /**
51 * Test setup for every test
52 *
53 * Connect to the database, truncate the tables that will be used
54 * and redirect stdin to a temporary file
55 */
56 public function setUp() {
57 $this->_entity = 'case';
58
59 parent::setUp();
60 // CRM-9404 - set-up is a bit cumbersome but had to put something in place to set up activity types & case types
61 //. Using XML was causing breakage as id numbers were changing over time
62 // & was really hard to troubleshoot as involved truncating option_value table to mitigate this & not leaving DB in a
63 // state where tests could run afterwards without re-loading.
64 $this->caseStatusGroup = $this->callAPISuccess('option_group', 'get', array(
65 'name' => 'case_status',
66 'format.only_id' => 1)
67 );
68 $optionValues = array(
69 'Medical evaluation' => 'Medical evaluation',
70 'Mental health evaluation' => "Mental health evaluation",
71 'Secure temporary housing' => 'Secure temporary housing',
72 'Long-term housing plan' => 'Long-term housing plan',
73 'ADC referral' => 'ADC referral',
74 'Income and benefits stabilization' => 'Income and benefits stabilization',
75 );
76 foreach ($optionValues as $name => $label) {
77 $activityTypes = $this->callAPISuccess('option_value', 'Create', array(
78 'option_group_id' => 2,
79 'name' => $name,
80 'label' => $label,
81 'component_id' => 7,
82 ));
83 // store for cleanup
84 $this->optionValues[] = $activityTypes['id'];
85 }
86 $this->caseTypeId = 1;
87 $this->tablesToTruncate = array(
88 'civicrm_activity',
89 'civicrm_contact',
90 'civicrm_custom_group',
91 'civicrm_custom_field',
92 'civicrm_case',
93 'civicrm_case_contact',
94 'civicrm_case_activity',
95 'civicrm_case_type',
96 'civicrm_activity_contact',
97 'civicrm_relationship',
98 'civicrm_relationship_type',
99 );
100
101 $this->quickCleanup($this->tablesToTruncate);
102
103 $this->loadAllFixtures();
104
105 $activityTypes = $this->callAPISuccess('option_value', 'get', array(
106 'option_group_id' => 2,
107 'name' => 'Follow Up',
108 'label' => 'Follow Up',
109 'sequential' => 1,
110 ));
111 $this->followup_activity_type_value = $activityTypes['values'][0]['value'];
112
113 // enable the default custom templates for the case type xml files
114 $this->customDirectories(array('template_path' => TRUE));
115
116 // case is not enabled by default
117 $enableResult = CRM_Core_BAO_ConfigSetting::enableComponent('CiviCase');
118 $this->assertTrue($enableResult, 'Cannot enable CiviCase in line ' . __LINE__);
119
120 $this->_params = array(
121 'case_type_id' => $this->caseTypeId,
122 'subject' => 'Test case',
123 'contact_id' => 17,
124 );
125
126 // create a logged in USER since the code references it for source_contact_id
127 $this->createLoggedInUser();
128 $session = CRM_Core_Session::singleton();
129 $this->_loggedInUser = $session->get('userID');
130 /// note that activityType options are cached by the FULL set of options you pass in
131 // ie. because Activity api includes campaign in it's call cache is not flushed unless
132 // included in this call. Also note flush function doesn't work on this property as it sets to null not empty array
133 CRM_Core_PseudoConstant::activityType(TRUE, TRUE, TRUE, 'name', TRUE);
134 }
135
136 /**
137 * Tears down the fixture, for example, closes a network connection.
138 * This method is called after a test is executed.
139 *
140 * @access protected
141 */
142 function tearDown() {
143 $this->quickCleanup($this->tablesToTruncate, TRUE);
144
145 $this->customDirectories(array('template_path' => FALSE));
146 }
147
148 /**
149 * check with empty array
150 */
151 function testCaseCreateEmpty() {
152 $result = $this->callAPIFailure('case', 'create', array());
153 }
154
155 /**
156 * check if required fields are not passed
157 */
158 function testCaseCreateWithoutRequired() {
159 $params = array(
160 'subject' => 'this case should fail',
161 'case_type_id' => 1,
162 );
163
164 $result = $this->callAPIFailure('case', 'create', $params);
165 }
166
167 /**
168 * Test create function with valid parameters
169 */
170 function testCaseCreate() {
171 // Create Case
172 $params = $this->_params;
173 // Test using label instead of value
174 unset($params['case_type_id']);
175 $params['case_type'] = 'Housing Support';
176 $result = $this->callAPISuccess('case', 'create', $params);
177 $id = $result['id'];
178
179 // Check result
180 $result = $this->callAPISuccess('case', 'get', array('id' => $id));
181 $this->assertEquals($result['values'][$id]['id'], $id, 'in line ' . __LINE__);
182 $this->assertEquals($result['values'][$id]['case_type_id'], $this->caseTypeId, 'in line ' . __LINE__);
183 $this->assertEquals($result['values'][$id]['subject'], $params['subject'], 'in line ' . __LINE__);
184 }
185
186 /**
187 * Test update (create with id) function with valid parameters
188 */
189 function testCaseUpdate() {
190 // Create Case
191 $params = $this->_params;
192 // Test using name instead of value
193 unset($params['case_type_id']);
194 $params['case_type'] = 'Housing Support';
195 $result = $this->callAPISuccess('case', 'create', $params);
196 $id = $result['id'];
197 $result = $this->callAPISuccess('case', 'get', array('id' => $id));
198 $case = $result['values'][$id];
199
200 // Update Case
201 $params = array('id' => $id);
202 $params['subject'] = $case['subject'] = 'Something Else';
203 $result = $this->callAPISuccess('case', 'create', $params);
204
205 // Verify that updated case is exactly equal to the original with new subject
206 $result = $this->callAPISuccess('case', 'get', array('case_id' => $id));
207 $this->assertEquals($result['values'][$id], $case, 'in line ' . __LINE__);
208 }
209
210 /**
211 * Test delete function with valid parameters
212 */
213 function testCaseDelete() {
214 // Create Case
215 $result = $this->callAPISuccess('case', 'create', $this->_params);
216
217 // Move Case to Trash
218 $id = $result['id'];
219 $result = $this->callAPISuccess('case', 'delete', array('id' => $id, 'move_to_trash' => 1));
220
221 // Check result - also check that 'case_id' works as well as 'id'
222 $result = $this->callAPISuccess('case', 'get', array('case_id' => $id));
223 $this->assertEquals(1, $result['values'][$id]['is_deleted'], 'in line ' . __LINE__);
224
225 // Delete Case Permanently - also check that 'case_id' works as well as 'id'
226 $result = $this->callAPISuccess('case', 'delete', array('case_id' => $id));
227
228 // Check result - case should no longer exist
229 $result = $this->callAPISuccess('case', 'get', array('id' => $id));
230 $this->assertEquals(0, $result['count']);
231 }
232
233 /**
234 * Test get function based on activity
235 */
236 function testCaseGetByActivity() {
237 // Create Case
238 $result = $this->callAPISuccess('case', 'create', $this->_params);
239 $id = $result['id'];
240
241 // Check result - we should get a list of activity ids
242 $result = $this->callAPISuccess('case', 'get', array('id' => $id));
243 $case = $result['values'][$id];
244 $activity = $case['activities'][0];
245
246 // Fetch case based on an activity id
247 $result = $this->callAPISuccess('case', 'get', array('activity_id' => $activity, 'return' => 'activities,contacts'));
248 $this->assertEquals(FALSE, empty($result['values'][$id]), 'in line ' . __LINE__);
249 $this->assertEquals($result['values'][$id], $case, 'in line ' . __LINE__);
250 }
251
252 /**
253 * Test get function based on contact id
254 */
255 function testCaseGetByContact() {
256 // Create Case
257 $result = $this->callAPISuccess('case', 'create', $this->_params);
258 $id = $result['id'];
259
260 // Store result for later
261 $case = $this->callAPISuccess('case', 'getsingle', array('id' => $id));
262
263 // Fetch case based on client contact id
264 $result = $this->callAPISuccess('case', 'get', array('client_id' => $this->_params['contact_id'], 'return' => array('activities', 'contacts')));
265 $this->assertAPIArrayComparison($result['values'][$id], $case);
266 }
267
268 /**
269 * Test get function based on subject
270 */
271 function testCaseGetBySubject() {
272 // Create Case
273 $result = $this->callAPISuccess('case', 'create', $this->_params);
274 $id = $result['id'];
275
276 // Store result for later
277 $case = $this->callAPISuccess('case', 'getsingle', array('id' => $id));
278
279 // Fetch case based on client contact id
280 $result = $this->callAPISuccess('case', 'get', array('subject' => $this->_params['subject'], 'return' => array('activities', 'contacts')));
281 $this->assertAPIArrayComparison($result['values'][$id], $case);
282 }
283
284 /**
285 * Test get function based on wrong subject
286 */
287 function testCaseGetByWrongSubject() {
288 // Create Case
289 $result = $this->callAPISuccess('case', 'create', $this->_params);
290 $id = $result['id'];
291
292 // Append 'wrong' to subject so that it is no longer the same
293 $result = $this->callAPISuccess('case', 'get', array('subject' => $this->_params['subject'] . 'wrong', 'return' => array('activities', 'contacts')));
294 $this->assertEquals(0, $result['count'], 'in line ' . __LINE__);
295 }
296
297 /**
298 * Test get function with no criteria
299 */
300 function testCaseGetNoCriteria() {
301 // Create Case
302 $result = $this->callAPISuccess('case', 'create', $this->_params);
303 $id = $result['id'];
304
305 // Store result for later
306 $case = $this->callAPISuccess('case', 'getsingle', array('id' => $id));
307
308 $result = $this->callAPISuccess('case', 'get', array('return' => array('activities', 'contacts')));
309 $this->assertAPIArrayComparison($result['values'][$id], $case);
310 }
311
312 /**
313 * Test activity api create for case activities
314 */
315 function testCaseActivityCreate() {
316 // Create a case first
317 $params = $this->_params;
318 $result = $this->callAPISuccess('case', 'create', $params);
319 $params = array(
320 'case_id' => 1,
321 // follow up
322 'activity_type_id' => $this->followup_activity_type_value,
323 'subject' => 'Test followup',
324 'source_contact_id' => $this->_loggedInUser,
325 'target_contact_id' => $this->_params['contact_id'],
326 );
327 $result = $this->callAPISuccess('activity', 'create', $params);
328 $this->assertEquals($result['values'][$result['id']]['activity_type_id'], $params['activity_type_id'], 'in line ' . __LINE__);
329
330 // might need this for other tests that piggyback on this one
331 $this->_caseActivityId = $result['values'][$result['id']]['id'];
332
333 // Check other DB tables populated properly - is there a better way to do this? assertDBState() requires that we know the id already.
334 $dao = new CRM_Case_DAO_CaseActivity();
335 $dao->case_id = 1;
336 $dao->activity_id = $this->_caseActivityId;
337 $this->assertEquals($dao->find(), 1, 'case_activity table not populated correctly in line ' . __LINE__);
338 $dao->free();
339
340 $dao = new CRM_Activity_DAO_ActivityContact();
341 $dao->activity_id = $this->_caseActivityId;
342 $dao->contact_id = $this->_params['contact_id'];
343 $dao->record_type_id = 3;
344 $this->assertEquals($dao->find(), 1, 'activity_contact table not populated correctly in line ' . __LINE__);
345 $dao->free();
346
347 // TODO: There's more things we could check
348 }
349
350 /**
351 * Test activity api update for case activities
352 */
353 function testCaseActivityUpdate() {
354 // Need to create the case and activity before we can update it
355 $this->testCaseActivityCreate();
356
357 $params = array(
358 'activity_id' => $this->_caseActivityId,
359 'case_id' => 1,
360 'activity_type_id' => 14,
361 'source_contact_id' => $this->_loggedInUser,
362 'subject' => 'New subject',
363 );
364 $result = $this->callAPISuccess('activity', 'create', $params);
365
366 $this->assertEquals($result['values'][$result['id']]['subject'], $params['subject'], 'in line ' . __LINE__);
367
368 // id should be one greater, since this is a new revision
369 $this->assertEquals($result['values'][$result['id']]['id'],
370 $this->_caseActivityId + 1,
371 'in line ' . __LINE__
372 );
373 $this->assertEquals($result['values'][$result['id']]['original_id'],
374 $this->_caseActivityId,
375 'in line ' . __LINE__
376 );
377
378 // Check revision is as expected
379 $revParams = array(
380 'activity_id' => $this->_caseActivityId,
381 );
382 $revActivity = $this->callAPISuccess('activity', 'get', $revParams);
383 $this->assertEquals($revActivity['values'][$this->_caseActivityId]['is_current_revision'],
384 0);
385 $this->assertEquals($revActivity['values'][$this->_caseActivityId]['is_deleted'],
386 0
387 );
388
389 //TODO: check some more things
390 }
391
392 function testCaseActivityUpdateCustom() {
393 // Create a case first
394 $result = $this->callAPISuccess('case', 'create', $this->_params);
395
396 // Create custom field group
397 // Note the second parameter is Activity on purpose, not Case.
398 $custom_ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__, 'ActivityTest.php');
399
400 // create activity
401 $params = array(
402 'case_id' => $result['id'],
403 // follow up
404 'activity_type_id' => 14,
405 'subject' => 'Test followup',
406 'source_contact_id' => $this->_loggedInUser,
407 'target_contact_id' => $this->_params['contact_id'],
408 'custom_' . $custom_ids['custom_field_id'] => "custom string",
409 );
410 $result = $this->callAPISuccess('activity', 'create', $params);
411
412 $aid = $result['values'][$result['id']]['id'];
413
414 // Update activity
415 $params = array(
416 'activity_id' => $aid,
417 'case_id' => 1,
418 'activity_type_id' => 14,
419 'source_contact_id' => $this->_loggedInUser,
420 'subject' => 'New subject',
421 );
422 $revAct = $this->callAPISuccess('activity', 'create', $params);
423
424 // Retrieve revision and check custom fields got copied
425 $revParams = array(
426 'activity_id' => $aid + 1,
427 'return.custom_' . $custom_ids['custom_field_id'] => 1,
428 );
429 $revAct = $this->callAPISuccess('activity', 'get', $revParams);
430
431 $this->assertEquals($revAct['values'][$aid + 1]['custom_' . $custom_ids['custom_field_id']], "custom string",
432 "Error message: " . CRM_Utils_Array::value('error_message', $revAct) . ' in line ' . __LINE__
433 );
434
435 $this->customFieldDelete($custom_ids['custom_field_id']);
436 $this->customGroupDelete($custom_ids['custom_group_id']);
437 }
438 }