fix header
[civicrm-core.git] / tests / phpunit / api / v3 / CaseTest.php
CommitLineData
6a488035
TO
1<?php
2/**
fe482240
EM
3 * @file
4 * File for the TestCase class
6a488035
TO
5 *
6 * (PHP 5)
7 *
6c6e6187
TO
8 * @author Walt Haas <walt@dharmatech.org> (801) 534-1262
9 * @copyright Copyright CiviCRM LLC (C) 2009
10 * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html
6a488035 11 * GNU Affero General Public License version 3
6c6e6187
TO
12 * @version $Id: ActivityTest.php 31254 2010-12-15 10:09:29Z eileen $
13 * @package CiviCRM
6a488035
TO
14 *
15 * This file is part of CiviCRM
16 *
17 * CiviCRM is free software; you can redistribute it and/or
18 * modify it under the terms of the GNU Affero General Public License
19 * as published by the Free Software Foundation; either version 3 of
20 * the License, or (at your option) any later version.
21 *
22 * CiviCRM is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 * GNU Affero General Public License for more details.
26 *
27 * You should have received a copy of the GNU Affero General Public
28 * License along with this program. If not, see
29 * <http://www.gnu.org/licenses/>.
30 */
31
32/**
9e959479 33 * Include class definitions
6a488035 34 */
6a488035
TO
35
36/**
37 * Test APIv3 civicrm_case_* functions
38 *
6c6e6187 39 * @package CiviCRM_APIv3
acb109b7 40 * @group headless
6a488035 41 */
1d8a8d12 42class api_v3_CaseTest extends CiviCaseTestCase {
6a488035
TO
43 protected $_params;
44 protected $_entity;
6c6e6187 45 protected $_apiversion = 3;
6a488035 46 protected $followup_activity_type_value;
9e959479
EM
47 /**
48 * Activity ID of created case.
49 *
50 * @var int
51 */
52 protected $_caseActivityId;
b7c9bc4c 53
534f8af1
TO
54 /**
55 * @var \Civi\Core\SettingsStack
56 */
57 protected $settingsStack;
58
6a488035 59 /**
fe482240 60 * Test setup for every test.
6a488035 61 *
d177a2a6 62 * Connect to the database, truncate the tables that will be used
9e959479 63 * and redirect stdin to a temporary file.
6a488035
TO
64 */
65 public function setUp() {
6a488035
TO
66 $this->_entity = 'case';
67
68 parent::setUp();
0b6f58fa 69
4e420887 70 $activityTypes = $this->callAPISuccess('option_value', 'get', array(
71 'option_group_id' => 2,
72 'name' => 'Follow Up',
73 'label' => 'Follow Up',
74 'sequential' => 1,
75 ));
6a488035 76 $this->followup_activity_type_value = $activityTypes['values'][0]['value'];
6a488035 77
6a488035
TO
78 $this->_params = array(
79 'case_type_id' => $this->caseTypeId,
80 'subject' => 'Test case',
81 'contact_id' => 17,
6a488035 82 );
534f8af1
TO
83
84 $this->settingsStack = new \Civi\Core\SettingsStack();
6a488035
TO
85 }
86
c16b4619 87 public function tearDown() {
534f8af1 88 $this->settingsStack->popAll();
c16b4619
TO
89 parent::tearDown();
90 }
91
6a488035 92 /**
fe482240 93 * Check with empty array.
6a488035 94 */
00be9182 95 public function testCaseCreateEmpty() {
fe482240 96 $this->callAPIFailure('case', 'create', array());
6a488035
TO
97 }
98
99 /**
fe482240 100 * Check if required fields are not passed.
6a488035 101 */
00be9182 102 public function testCaseCreateWithoutRequired() {
6a488035
TO
103 $params = array(
104 'subject' => 'this case should fail',
105 'case_type_id' => 1,
6a488035
TO
106 );
107
225d474b 108 $this->callAPIFailure('case', 'create', $params);
6a488035
TO
109 }
110
09d55aa3 111 /**
112 * Test Getlist with id and case_id
113 */
114 public function testCaseGetListById() {
115 $params = $this->_params;
116 $params['contact_id'] = $this->individualCreate();
117
118 //Create 3 sample Cases.
119 $case1 = $this->callAPISuccess('case', 'create', $params);
120 $params['subject'] = 'Test Case 2';
121 $case2 = $this->callAPISuccess('case', 'create', $params);
122 $params['subject'] = 'Test Case 3';
123 $case3 = $this->callAPISuccess('case', 'create', $params);
124
125 $getParams = array(
126 'id' => array($case1['id']),
127 'extra' => array('contact_id'),
128 'params' => array(
129 'version' => 3,
130 'case_id' => array('!=' => $case2['id']),
131 'case_id.is_deleted' => 0,
132 'case_id.status_id' => array('!=' => "Closed"),
133 'case_id.end_date' => array('IS NULL' => 1),
134 ),
135 );
136 $result = $this->callAPISuccess('case', 'getlist', $getParams);
137
138 //Only 1 case should be returned.
139 $this->assertEquals(count($result['values']), 1);
140 $this->assertEquals($result['values'][0]['id'], $case1['id']);
141 }
142
6a488035 143 /**
fe482240 144 * Test create function with valid parameters.
6a488035 145 */
00be9182 146 public function testCaseCreate() {
6a488035 147 $params = $this->_params;
9e959479 148 // Test using label instead of value.
6a488035 149 unset($params['case_type_id']);
82de141d 150 $params['case_type'] = $this->caseType;
32191489 151 $result = $this->callAPIAndDocument('case', 'create', $params, __FUNCTION__, __FILE__);
6a488035
TO
152 $id = $result['id'];
153
154 // Check result
4e420887 155 $result = $this->callAPISuccess('case', 'get', array('id' => $id));
9e959479
EM
156 $this->assertEquals($result['values'][$id]['id'], $id);
157 $this->assertEquals($result['values'][$id]['case_type_id'], $this->caseTypeId);
158 $this->assertEquals($result['values'][$id]['subject'], $params['subject']);
6a488035
TO
159 }
160
3717c347
JP
161 /**
162 * Test create function with resolved status.
163 */
164 public function testCaseCreateWithResolvedStatus() {
165 $params = $this->_params;
166 // Test using label instead of value.
167 unset($params['case_type_id']);
168 $params['case_type'] = $this->caseType;
169 $params['status_id'] = 'Closed';
170 $result = $this->callAPISuccess('case', 'create', $params);
171 $id = $result['id'];
172
173 // Check result
174 $result = $this->callAPISuccess('case', 'get', array('id' => $id));
175 $this->assertEquals($result['values'][$id]['id'], $id);
176 $this->assertEquals($result['values'][$id]['case_type_id'], $this->caseTypeId);
177 $this->assertEquals($result['values'][$id]['subject'], $params['subject']);
178 $this->assertEquals($result['values'][$id]['end_date'], date('Y-m-d'));
179
180 //Check all relationship end dates are set to case end date.
181 $relationships = $this->callAPISuccess('Relationship', 'get', array(
182 'sequential' => 1,
183 'case_id' => $id,
184 ));
185 foreach ($relationships['values'] as $key => $values) {
186 $this->assertEquals($values['end_date'], date('Y-m-d'));
187 }
188 }
189
c35f5692
MW
190 /**
191 * Test case create with valid parameters and custom data.
192 */
193 public function testCaseCreateCustom() {
194 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__, __FILE__);
195 $params = $this->_params;
196 $params['custom_' . $ids['custom_field_id']] = "custom string";
197 $result = $this->callAPIAndDocument($this->_entity, 'create', $params, __FUNCTION__, __FILE__);
198 $result = $this->callAPISuccess($this->_entity, 'get', array(
199 'return.custom_' . $ids['custom_field_id'] => 1,
200 'id' => $result['id'],
201 ));
202 $this->assertEquals("custom string", $result['values'][$result['id']]['custom_' . $ids['custom_field_id']], ' in line ' . __LINE__);
203
204 $this->customFieldDelete($ids['custom_field_id']);
205 $this->customGroupDelete($ids['custom_group_id']);
206 }
207
6a488035 208 /**
9e959479 209 * Test update (create with id) function with valid parameters.
6a488035 210 */
00be9182 211 public function testCaseUpdate() {
6a77ff3d
CW
212 $params = $this->_params;
213 // Test using name instead of value
8ffdec17 214 unset($params['case_type_id']);
82de141d 215 $params['case_type'] = $this->caseType;
4e420887 216 $result = $this->callAPISuccess('case', 'create', $params);
6a488035 217 $id = $result['id'];
e61d8c45 218 $case = $this->callAPISuccess('case', 'getsingle', array('id' => $id));
6a488035 219
9e959479 220 // Update Case.
4e420887 221 $params = array('id' => $id);
9937542b 222 $params['subject'] = $case['subject'] = 'Something Else';
9e959479 223 $this->callAPISuccess('case', 'create', $params);
be84446f
MW
224
225 // Verify that updated case is equal to the original with new subject.
226 $result = $this->callAPISuccessGetSingle('Case', array('case_id' => $id));
227 // Modification dates are likely to differ by 0-2 sec. Check manually.
244626a4
CW
228 $this->assertGreaterThanOrEqual($case['modified_date'], $result['modified_date']);
229 unset($result['modified_date'], $case['modified_date']);
be84446f
MW
230 // Everything else should be identical.
231 $this->assertAPIArrayComparison($result, $case);
232 }
233
234 /**
235 * Test update (create with id) function with valid parameters.
236 */
237 public function testCaseUpdateWithExistingCaseContact() {
238 $params = $this->_params;
239 // Test using name instead of value
240 unset($params['case_type_id']);
241 $params['case_type'] = $this->caseType;
242 $result = $this->callAPISuccess('case', 'create', $params);
243 $id = $result['id'];
244 $case = $this->callAPISuccess('case', 'getsingle', array('id' => $id));
245
246 // Update Case, we specify existing case ID and existing contact ID to verify that CaseContact.create is not called
247 $params = $this->_params;
248 $params['id'] = $id;
249 $this->callAPISuccess('case', 'create', $params);
6a488035 250
32c1003d 251 // Verify that updated case is equal to the original with new subject.
9937542b 252 $result = $this->callAPISuccessGetSingle('Case', array('case_id' => $id));
32c1003d 253 // Modification dates are likely to differ by 0-2 sec. Check manually.
244626a4
CW
254 $this->assertGreaterThanOrEqual($case['modified_date'], $result['modified_date']);
255 unset($result['modified_date'], $case['modified_date']);
32c1003d 256 // Everything else should be identical.
e61d8c45 257 $this->assertAPIArrayComparison($result, $case);
6a488035
TO
258 }
259
c35f5692
MW
260 /**
261 * Test case update with custom data
262 */
263 public function testCaseUpdateCustom() {
264 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__, __FILE__);
265 $params = $this->_params;
266
267 // Create a case with custom data
268 $params['custom_' . $ids['custom_field_id']] = 'custom string';
269 $result = $this->callAPISuccess($this->_entity, 'create', $params);
270
271 $caseId = $result['id'];
272 $result = $this->callAPISuccess($this->_entity, 'get', array(
273 'return.custom_' . $ids['custom_field_id'] => 1,
274 'version' => 3,
275 'id' => $result['id'],
276 ));
277 $this->assertEquals("custom string", $result['values'][$result['id']]['custom_' . $ids['custom_field_id']]);
278 $fields = $this->callAPISuccess($this->_entity, 'getfields', array('version' => $this->_apiversion));
279 $this->assertTrue(is_array($fields['values']['custom_' . $ids['custom_field_id']]));
280
281 // Update the activity with custom data.
282 $params = array(
283 'id' => $caseId,
284 'custom_' . $ids['custom_field_id'] => 'Updated my test data',
285 'version' => $this->_apiversion,
286 );
287 $result = $this->callAPISuccess($this->_entity, 'create', $params);
288
289 $result = $this->callAPISuccess($this->_entity, 'get', array(
290 'return.custom_' . $ids['custom_field_id'] => 1,
291 'version' => 3,
292 'id' => $result['id'],
293 ));
294 $this->assertEquals("Updated my test data", $result['values'][$result['id']]['custom_' . $ids['custom_field_id']]);
295 }
296
6a488035 297 /**
fe482240 298 * Test delete function with valid parameters.
6a488035 299 */
00be9182 300 public function testCaseDelete() {
6a488035 301 // Create Case
4e420887 302 $result = $this->callAPISuccess('case', 'create', $this->_params);
6a488035
TO
303
304 // Move Case to Trash
305 $id = $result['id'];
8572e6de 306 $this->callAPISuccess('case', 'delete', array('id' => $id, 'move_to_trash' => 1));
6a488035
TO
307
308 // Check result - also check that 'case_id' works as well as 'id'
4e420887 309 $result = $this->callAPISuccess('case', 'get', array('case_id' => $id));
9e959479 310 $this->assertEquals(1, $result['values'][$id]['is_deleted']);
6a488035 311
8572e6de
CW
312 // Restore Case from Trash
313 $this->callAPISuccess('case', 'restore', array('id' => $id));
314
315 // Check result
316 $result = $this->callAPISuccess('case', 'get', array('case_id' => $id));
317 $this->assertEquals(0, $result['values'][$id]['is_deleted']);
318
319 // Delete Case Permanently
320 $this->callAPISuccess('case', 'delete', array('case_id' => $id));
6a488035
TO
321
322 // Check result - case should no longer exist
4e420887 323 $result = $this->callAPISuccess('case', 'get', array('id' => $id));
324 $this->assertEquals(0, $result['count']);
6a488035
TO
325 }
326
327 /**
fe482240 328 * Test get function based on activity.
6a488035 329 */
00be9182 330 public function testCaseGetByActivity() {
6a488035 331 // Create Case
4e420887 332 $result = $this->callAPISuccess('case', 'create', $this->_params);
6a488035
TO
333 $id = $result['id'];
334
335 // Check result - we should get a list of activity ids
e61d8c45 336 $result = $this->callAPISuccess('case', 'get', array('id' => $id, 'return' => 'activities'));
6a488035
TO
337 $case = $result['values'][$id];
338 $activity = $case['activities'][0];
339
340 // Fetch case based on an activity id
92915c55
TO
341 $result = $this->callAPISuccess('case', 'get', array(
342 'activity_id' => $activity,
e61d8c45 343 'return' => 'activities',
92915c55 344 ));
9e959479
EM
345 $this->assertEquals(FALSE, empty($result['values'][$id]));
346 $this->assertEquals($result['values'][$id], $case);
6a488035
TO
347 }
348
349 /**
fe482240 350 * Test get function based on contact id.
6a488035 351 */
00be9182 352 public function testCaseGetByContact() {
6a488035 353 // Create Case
4e420887 354 $result = $this->callAPISuccess('case', 'create', $this->_params);
6a488035
TO
355 $id = $result['id'];
356
357 // Store result for later
9937542b 358 $case = $this->callAPISuccessGetSingle('case', array('id' => $id, 'return' => array('activities', 'contacts')));
6a488035
TO
359
360 // Fetch case based on client contact id
92915c55
TO
361 $result = $this->callAPISuccess('case', 'get', array(
362 'client_id' => $this->_params['contact_id'],
79d7553f 363 'return' => array('activities', 'contacts'),
92915c55 364 ));
4e420887 365 $this->assertAPIArrayComparison($result['values'][$id], $case);
6a488035
TO
366 }
367
f21557af 368 /**
fe482240 369 * Test get function based on subject.
f21557af 370 */
00be9182 371 public function testCaseGetBySubject() {
f21557af 372 // Create Case
373 $result = $this->callAPISuccess('case', 'create', $this->_params);
374 $id = $result['id'];
375
376 // Store result for later
9937542b 377 $case = $this->callAPISuccessGetSingle('Case', array('id' => $id, 'return' => 'subject'));
f21557af 378
379 // Fetch case based on client contact id
92915c55
TO
380 $result = $this->callAPISuccess('case', 'get', array(
381 'subject' => $this->_params['subject'],
e61d8c45 382 'return' => array('subject'),
92915c55 383 ));
f21557af 384 $this->assertAPIArrayComparison($result['values'][$id], $case);
385 }
386
387 /**
fe482240 388 * Test get function based on wrong subject.
f21557af 389 */
00be9182 390 public function testCaseGetByWrongSubject() {
f21557af 391 $result = $this->callAPISuccess('case', 'create', $this->_params);
f21557af 392
9e959479 393 // Append 'wrong' to subject so that it is no longer the same.
92915c55
TO
394 $result = $this->callAPISuccess('case', 'get', array(
395 'subject' => $this->_params['subject'] . 'wrong',
79d7553f 396 'return' => array('activities', 'contacts'),
92915c55 397 ));
9e959479 398 $this->assertEquals(0, $result['count']);
f21557af 399 }
400
401 /**
fe482240 402 * Test get function with no criteria.
f21557af 403 */
00be9182 404 public function testCaseGetNoCriteria() {
f21557af 405 $result = $this->callAPISuccess('case', 'create', $this->_params);
406 $id = $result['id'];
407
408 // Store result for later
9937542b 409 $case = $this->callAPISuccessGetSingle('Case', array('id' => $id, 'return' => 'contact_id'));
f21557af 410
e61d8c45 411 $result = $this->callAPISuccess('case', 'get', array('limit' => 0, 'return' => array('contact_id')));
f21557af 412 $this->assertAPIArrayComparison($result['values'][$id], $case);
413 }
414
6a488035 415 /**
fe482240 416 * Test activity api create for case activities.
6a488035 417 */
00be9182 418 public function testCaseActivityCreate() {
6a488035 419 $params = $this->_params;
bc4b6f0f 420 $case = $this->callAPISuccess('case', 'create', $params);
6a488035 421 $params = array(
bc4b6f0f 422 'case_id' => $case['id'],
6a488035
TO
423 // follow up
424 'activity_type_id' => $this->followup_activity_type_value,
bc4b6f0f 425 'subject' => 'Test followup 123',
6a488035
TO
426 'source_contact_id' => $this->_loggedInUser,
427 'target_contact_id' => $this->_params['contact_id'],
6a488035 428 );
4e420887 429 $result = $this->callAPISuccess('activity', 'create', $params);
9e959479 430 $this->assertEquals($result['values'][$result['id']]['activity_type_id'], $params['activity_type_id']);
6a488035
TO
431
432 // might need this for other tests that piggyback on this one
433 $this->_caseActivityId = $result['values'][$result['id']]['id'];
434
435 // Check other DB tables populated properly - is there a better way to do this? assertDBState() requires that we know the id already.
4e420887 436 $dao = new CRM_Case_DAO_CaseActivity();
bc4b6f0f 437 $dao->case_id = $case['id'];
6a488035
TO
438 $dao->activity_id = $this->_caseActivityId;
439 $this->assertEquals($dao->find(), 1, 'case_activity table not populated correctly in line ' . __LINE__);
440 $dao->free();
441
b319d00a 442 $dao = new CRM_Activity_DAO_ActivityContact();
6a488035 443 $dao->activity_id = $this->_caseActivityId;
b319d00a
DL
444 $dao->contact_id = $this->_params['contact_id'];
445 $dao->record_type_id = 3;
446 $this->assertEquals($dao->find(), 1, 'activity_contact table not populated correctly in line ' . __LINE__);
6a488035
TO
447 $dao->free();
448
bc4b6f0f
CW
449 // Check that fetching an activity by case id works, as well as returning case_id
450 $result = $this->callAPISuccessGetSingle('Activity', array(
451 'case_id' => $case['id'],
452 'activity_type_id' => $this->followup_activity_type_value,
453 'subject' => 'Test followup 123',
454 'return' => array('case_id'),
455 ));
18e0f096 456 $this->assertContains($case['id'], $result['case_id']);
6a488035
TO
457 }
458
459 /**
fe482240 460 * Test activity api update for case activities.
6a488035 461 */
534f8af1
TO
462 public function testCaseActivityUpdate_Tracked() {
463 $this->settingsStack->push('civicaseActivityRevisions', TRUE);
464
6a488035
TO
465 // Need to create the case and activity before we can update it
466 $this->testCaseActivityCreate();
467
468 $params = array(
469 'activity_id' => $this->_caseActivityId,
470 'case_id' => 1,
471 'activity_type_id' => 14,
472 'source_contact_id' => $this->_loggedInUser,
473 'subject' => 'New subject',
6a488035 474 );
4e420887 475 $result = $this->callAPISuccess('activity', 'create', $params);
6a488035 476
9e959479 477 $this->assertEquals($result['values'][$result['id']]['subject'], $params['subject']);
6a488035
TO
478
479 // id should be one greater, since this is a new revision
480 $this->assertEquals($result['values'][$result['id']]['id'],
481 $this->_caseActivityId + 1,
482 'in line ' . __LINE__
483 );
484 $this->assertEquals($result['values'][$result['id']]['original_id'],
485 $this->_caseActivityId,
486 'in line ' . __LINE__
487 );
488
489 // Check revision is as expected
490 $revParams = array(
491 'activity_id' => $this->_caseActivityId,
6a488035 492 );
4e420887 493 $revActivity = $this->callAPISuccess('activity', 'get', $revParams);
6a488035 494 $this->assertEquals($revActivity['values'][$this->_caseActivityId]['is_current_revision'],
4e420887 495 0);
6a488035 496 $this->assertEquals($revActivity['values'][$this->_caseActivityId]['is_deleted'],
4e420887 497 0
6a488035
TO
498 );
499
500 //TODO: check some more things
501 }
502
c16b4619
TO
503 /**
504 * If you disable `civicaseActivityRevisions`, then editing an activity
505 * will *not* create or change IDs.
506 */
507 public function testCaseActivityUpdate_Untracked() {
534f8af1 508 $this->settingsStack->push('civicaseActivityRevisions', FALSE);
c16b4619
TO
509
510 // Need to create the case and activity before we can update it
511 $this->testCaseActivityCreate();
512
513 $oldIDs = CRM_Utils_SQL_Select::from('civicrm_activity')
514 ->select('id, original_id, is_current_revision')
515 ->orderBy('id')
516 ->execute()->fetchAll();
517
518 $params = array(
519 'activity_id' => $this->_caseActivityId,
520 'case_id' => 1,
521 'activity_type_id' => 14,
522 'source_contact_id' => $this->_loggedInUser,
523 'subject' => 'New subject',
524 );
525 $result = $this->callAPISuccess('activity', 'create', $params);
526 $this->assertEquals($result['values'][$result['id']]['subject'], $params['subject']);
527
528 // id should not change because we've opted out.
529 $this->assertEquals($this->_caseActivityId, $result['values'][$result['id']]['id']);
530 $this->assertEmpty($result['values'][$result['id']]['original_id']);
531
532 $newIDs = CRM_Utils_SQL_Select::from('civicrm_activity')
533 ->select('id, original_id, is_current_revision')
534 ->orderBy('id')
535 ->execute()->fetchAll();
536 $this->assertEquals($oldIDs, $newIDs);
537 }
538
00be9182 539 public function testCaseActivityUpdateCustom() {
534f8af1
TO
540 $this->settingsStack->push('civicaseActivityRevisions', TRUE);
541
6a488035 542 // Create a case first
4e420887 543 $result = $this->callAPISuccess('case', 'create', $this->_params);
6a488035
TO
544
545 // Create custom field group
546 // Note the second parameter is Activity on purpose, not Case.
547 $custom_ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__, 'ActivityTest.php');
548
549 // create activity
550 $params = array(
4e420887 551 'case_id' => $result['id'],
6a488035
TO
552 // follow up
553 'activity_type_id' => 14,
554 'subject' => 'Test followup',
555 'source_contact_id' => $this->_loggedInUser,
556 'target_contact_id' => $this->_params['contact_id'],
557 'custom_' . $custom_ids['custom_field_id'] => "custom string",
6a488035 558 );
4e420887 559 $result = $this->callAPISuccess('activity', 'create', $params);
6a488035
TO
560
561 $aid = $result['values'][$result['id']]['id'];
562
563 // Update activity
564 $params = array(
565 'activity_id' => $aid,
566 'case_id' => 1,
567 'activity_type_id' => 14,
568 'source_contact_id' => $this->_loggedInUser,
569 'subject' => 'New subject',
6a488035 570 );
9e959479 571 $this->callAPISuccess('activity', 'create', $params);
6a488035 572
9e959479 573 // Retrieve revision and check custom fields got copied.
6a488035
TO
574 $revParams = array(
575 'activity_id' => $aid + 1,
6a488035
TO
576 'return.custom_' . $custom_ids['custom_field_id'] => 1,
577 );
4e420887 578 $revAct = $this->callAPISuccess('activity', 'get', $revParams);
6a488035 579
6a488035 580 $this->assertEquals($revAct['values'][$aid + 1]['custom_' . $custom_ids['custom_field_id']], "custom string",
9e959479 581 "Error message: " . CRM_Utils_Array::value('error_message', $revAct));
6a488035
TO
582
583 $this->customFieldDelete($custom_ids['custom_field_id']);
584 $this->customGroupDelete($custom_ids['custom_group_id']);
585 }
96025800 586
37606d10
SB
587 public function testCaseGetByStatus() {
588 // Create 2 cases with different status ids.
589 $case1 = $this->callAPISuccess('Case', 'create', array(
590 'contact_id' => 17,
591 'subject' => "Test case 1",
592 'case_type_id' => $this->caseTypeId,
593 'status_id' => "Open",
594 'sequential' => 1,
595 ));
596 $this->callAPISuccess('Case', 'create', array(
597 'contact_id' => 17,
598 'subject' => "Test case 2",
599 'case_type_id' => $this->caseTypeId,
600 'status_id' => "Urgent",
601 'sequential' => 1,
602 ));
603 $result = $this->callAPISuccessGetSingle('Case', array(
604 'sequential' => 1,
605 'contact_id' => 17,
606 'status_id' => "Open",
607 ));
608 $this->assertEquals($case1['id'], $result['id']);
609 }
610
0ab56350
CW
611 public function testCaseGetWithRoles() {
612 $case1 = $this->callAPISuccess('Case', 'create', array(
613 'contact_id' => 17,
614 'subject' => "Test case with roles",
615 'case_type_id' => $this->caseTypeId,
616 'status_id' => "Open",
617 ));
618 $result = $this->callAPISuccessGetSingle('Case', array(
619 'id' => $case1['id'],
620 'status_id' => "Open",
621 'return' => array('contacts'),
622 ));
623 foreach ($result['contacts'] as $contact) {
624 if ($contact['role'] == 'Client') {
625 $this->assertEquals(17, $contact['contact_id']);
626 }
627 elseif ($contact['role'] == 'Homeless Services Coordinator') {
628 $this->assertEquals(1, $contact['creator']);
629 $this->assertEquals(1, $contact['manager']);
630 }
631 }
632 }
633
634 public function testCaseGetWithDefinition() {
635 $case1 = $this->callAPISuccess('Case', 'create', array(
636 'contact_id' => 17,
637 'subject' => "Test case with definition",
638 'case_type_id' => $this->caseTypeId,
639 'status_id' => "Open",
640 ));
641 $result1 = $this->callAPISuccessGetSingle('Case', array(
642 'id' => $case1['id'],
643 'status_id' => "Open",
644 'return' => array('case_type_id.definition'),
645 ));
646 $result2 = $this->callAPISuccessGetSingle('Case', array(
647 'id' => $case1['id'],
648 'status_id' => "Open",
649 'return' => array('case_type_id', 'case_type_id.definition'),
650 ));
651 $this->assertEquals($result1['case_type_id.definition'], $result2['case_type_id.definition']);
652 $def = $result1['case_type_id.definition'];
653 $this->assertEquals(array('name' => 'Open Case', 'max_instances' => 1), $def['activityTypes'][0]);
654 $this->assertNotEmpty($def['activitySets'][0]['activityTypes']);
655 $this->assertNotEmpty($def['caseRoles'][0]['manager']);
656 $this->assertNotEmpty($def['caseRoles'][0]['creator']);
657 }
658
9ef16723
CW
659 public function testCaseGetTags() {
660 $case1 = $this->callAPISuccess('Case', 'create', array(
661 'contact_id' => 17,
662 'subject' => "Test case with tags",
663 'case_type_id' => $this->caseTypeId,
664 'status_id' => "Open",
665 ));
666 $tag1 = $this->tagCreate(array(
667 'name' => 'CaseTag1',
668 'used_for' => 'civicrm_case',
669 ));
670 $tag2 = $this->tagCreate(array(
671 'name' => 'CaseTag2',
672 'used_for' => 'civicrm_case',
673 ));
674 $this->callAPISuccess('EntityTag', 'create', array(
675 'entity_table' => 'civicrm_case',
676 'entity_id' => $case1['id'],
677 'tag_id' => $tag1['id'],
678 ));
679 $this->callAPIFailure('Case', 'getsingle', array(
680 'tag_id' => $tag2['id'],
681 ));
682 $result = $this->callAPISuccessGetSingle('Case', array(
683 'tag_id' => $tag1['id'],
684 'return' => 'tag_id.name',
685 ));
686 $this->assertEquals('CaseTag1', $result['tag_id'][$tag1['id']]['tag_id.name']);
687 }
688
10befc1f
CW
689 /**
690 * Test that a chained api call can use the operator syntax.
691 *
692 * E.g. array('IN' => $value.contact_id)
693 *
694 * @throws \Exception
695 */
696 public function testCaseGetChainedOp() {
697 $contact1 = $this->individualCreate(array(), 1);
698 $contact2 = $this->individualCreate(array(), 2);
699 $case1 = $this->callAPISuccess('Case', 'create', array(
700 'contact_id' => $contact1,
701 'subject' => "Test case 1",
702 'case_type_id' => $this->caseTypeId,
703 ));
704 $case2 = $this->callAPISuccess('Case', 'create', array(
705 'contact_id' => $contact2,
706 'subject' => "Test case 2",
707 'case_type_id' => $this->caseTypeId,
708 ));
709 $case3 = $this->callAPISuccess('Case', 'create', array(
710 'contact_id' => array($contact1, $contact2),
711 'subject' => "Test case 3",
712 'case_type_id' => $this->caseTypeId,
713 ));
714
715 // Fetch case 1 and all cases with the same client. Chained get should return case 3.
716 $result = $this->callAPISuccessGetSingle('Case', array(
717 'id' => $case1['id'],
718 'return' => 'contact_id',
719 'api.Case.get' => array(
720 'contact_id' => array('IN' => "\$value.contact_id"),
721 'id' => array('!=' => "\$value.id"),
722 ),
723 ));
724 $this->assertEquals($case3['id'], $result['api.Case.get']['id']);
725
726 // Fetch case 3 and all cases with the same clients. Chained get should return case 1&2.
727 $result = $this->callAPISuccessGetSingle('Case', array(
728 'id' => $case3['id'],
729 'return' => array('contact_id'),
730 'api.Case.get' => array(
731 'return' => 'id',
732 'contact_id' => array('IN' => "\$value.contact_id"),
733 'id' => array('!=' => "\$value.id"),
734 ),
735 ));
736 $this->assertEquals(array($case1['id'], $case2['id']), array_keys(CRM_Utils_Array::rekey($result['api.Case.get']['values'], 'id')));
737 }
738
242220e2
CW
739 /**
740 * Test the ability to order by client using the join syntax.
741 *
742 * For multi-client cases, should order by the first client.
743 */
744 public function testCaseGetOrderByClient() {
745 $contact1 = $this->individualCreate(array('first_name' => 'Aa', 'last_name' => 'Zz'));
4c6cc364 746 $contact2 = $this->individualCreate(array('first_name' => 'Bb', 'last_name' => 'Zz'));
242220e2
CW
747 $contact3 = $this->individualCreate(array('first_name' => 'Cc', 'last_name' => 'Xx'));
748
749 $case1 = $this->callAPISuccess('Case', 'create', array(
750 'contact_id' => $contact1,
751 'subject' => "Test case 1",
752 'case_type_id' => $this->caseTypeId,
753 ));
754 $case2 = $this->callAPISuccess('Case', 'create', array(
755 'contact_id' => $contact2,
756 'subject' => "Test case 2",
757 'case_type_id' => $this->caseTypeId,
758 ));
759 $case3 = $this->callAPISuccess('Case', 'create', array(
760 'contact_id' => array($contact3, $contact1),
761 'subject' => "Test case 3",
762 'case_type_id' => $this->caseTypeId,
763 ));
764
765 $result = $this->callAPISuccess('Case', 'get', array(
766 'contact_id' => array('IN' => array($contact1, $contact2, $contact3)),
767 'sequential' => 1,
768 'return' => 'id',
769 'options' => array('sort' => 'contact_id.first_name'),
770 ));
771 $this->assertEquals($case3['id'], $result['values'][2]['id']);
772 $this->assertEquals($case2['id'], $result['values'][1]['id']);
773 $this->assertEquals($case1['id'], $result['values'][0]['id']);
774
775 $result = $this->callAPISuccess('Case', 'get', array(
776 'contact_id' => array('IN' => array($contact1, $contact2, $contact3)),
777 'sequential' => 1,
778 'return' => 'id',
4c6cc364 779 'options' => array('sort' => 'contact_id.last_name ASC, contact_id.first_name DESC'),
242220e2
CW
780 ));
781 $this->assertEquals($case1['id'], $result['values'][2]['id']);
782 $this->assertEquals($case2['id'], $result['values'][1]['id']);
783 $this->assertEquals($case3['id'], $result['values'][0]['id']);
784
785 $result = $this->callAPISuccess('Case', 'get', array(
786 'contact_id' => array('IN' => array($contact1, $contact2, $contact3)),
787 'sequential' => 1,
788 'return' => 'id',
789 'options' => array('sort' => 'contact_id.first_name DESC'),
790 ));
791 $this->assertEquals($case1['id'], $result['values'][2]['id']);
792 $this->assertEquals($case2['id'], $result['values'][1]['id']);
793 $this->assertEquals($case3['id'], $result['values'][0]['id']);
794
795 $result = $this->callAPISuccess('Case', 'get', array(
796 'contact_id' => array('IN' => array($contact1, $contact2, $contact3)),
797 'sequential' => 1,
798 'return' => 'id',
4c6cc364 799 'options' => array('sort' => 'case_type_id, contact_id DESC, status_id'),
242220e2
CW
800 ));
801 $this->assertEquals($case1['id'], $result['values'][2]['id']);
802 $this->assertEquals($case2['id'], $result['values'][1]['id']);
803 $this->assertEquals($case3['id'], $result['values'][0]['id']);
804 $this->assertCount(3, $result['values']);
805 }
806
ae76ce5e
CW
807 /**
808 * Test the ability to add a timeline to an existing case.
809 *
810 * See the case.addtimeline api.
811 *
534f8af1 812 * @dataProvider caseActivityRevisionExamples
ae76ce5e
CW
813 * @throws \Exception
814 */
534f8af1
TO
815 public function testCaseAddtimeline($enableRevisions) {
816 $this->settingsStack->push('civicaseActivityRevisions', $enableRevisions);
817
ae76ce5e
CW
818 $caseSpec = array(
819 'title' => 'Application with Definition',
820 'name' => 'Application_with_Definition',
821 'is_active' => 1,
822 'weight' => 4,
823 'definition' => array(
824 'activityTypes' => array(
825 array('name' => 'Follow up'),
826 ),
827 'activitySets' => array(
828 array(
829 'name' => 'set1',
830 'label' => 'Label 1',
831 'timeline' => 1,
832 'activityTypes' => array(
833 array('name' => 'Open Case', 'status' => 'Completed'),
834 ),
835 ),
836 array(
837 'name' => 'set2',
838 'label' => 'Label 2',
839 'timeline' => 1,
840 'activityTypes' => array(
841 array('name' => 'Follow up'),
842 ),
843 ),
844 ),
845 'caseRoles' => array(
846 array('name' => 'Homeless Services Coordinator', 'creator' => 1, 'manager' => 1),
847 ),
848 ),
849 );
850 $cid = $this->individualCreate();
851 $caseType = $this->callAPISuccess('CaseType', 'create', $caseSpec);
852 $case = $this->callAPISuccess('Case', 'create', array(
853 'case_type_id' => $caseType['id'],
854 'contact_id' => $cid,
855 'subject' => 'Test case with timeline',
856 ));
857 // Created case should only have 1 activity per the spec
858 $result = $this->callAPISuccessGetSingle('Activity', array('case_id' => $case['id'], 'return' => 'activity_type_id.name'));
859 $this->assertEquals('Open Case', $result['activity_type_id.name']);
860 // Add timeline
861 $timeline = civicrm_api('Case', 'addtimeline', array(
862 'case_id' => $case['id'],
863 'timeline' => 'set2',
864 'version' => 3,
865 ));
866 $result = $this->callAPISuccess('Activity', 'get', array(
867 'case_id' => $case['id'],
868 'return' => 'activity_type_id.name',
869 'sequential' => 1,
870 'options' => array('sort' => 'id'),
871 ));
872 $this->assertEquals(2, $result['count']);
873 $this->assertEquals('Follow up', $result['values'][1]['activity_type_id.name']);
874 }
875
a6bc7218
CW
876 /**
877 * Test the case merge function.
878 *
879 * 2 cases should be mergeable into 1
880 *
881 * @throws \Exception
882 */
883 public function testCaseMerge() {
884 $contact1 = $this->individualCreate(array(), 1);
885 $case1 = $this->callAPISuccess('Case', 'create', array(
886 'contact_id' => $contact1,
887 'subject' => "Test case 1",
888 'case_type_id' => $this->caseTypeId,
889 ));
890 $case2 = $this->callAPISuccess('Case', 'create', array(
891 'contact_id' => $contact1,
892 'subject' => "Test case 2",
893 'case_type_id' => $this->caseTypeId,
894 ));
895 $result = $this->callAPISuccess('Case', 'getcount', array('contact_id' => $contact1));
896 $this->assertEquals(2, $result);
897
898 $this->callAPISuccess('Case', 'merge', array('case_id_1' => $case1['id'], 'case_id_2' => $case2['id']));
899
900 $result = $this->callAPISuccess('Case', 'getsingle', array('id' => $case2['id']));
901 $this->assertEquals(1, $result['is_deleted']);
902 }
903
534f8af1
TO
904 public function caseActivityRevisionExamples() {
905 $examples = array();
906 $examples[] = array(FALSE);
907 $examples[] = array(TRUE);
908 return $examples;
909 }
910
2c6b0b4b
TO
911 public function testTimestamps() {
912 $params = $this->_params;
913 $case_created = $this->callAPISuccess('case', 'create', $params);
914
915 $case_1 = $this->callAPISuccess('Case', 'getsingle', array(
916 'id' => $case_created['id'],
917 ));
918 $this->assertRegExp(';^\d\d\d\d-\d\d-\d\d \d\d:\d\d;', $case_1['created_date']);
919 $this->assertRegExp(';^\d\d\d\d-\d\d-\d\d \d\d:\d\d;', $case_1['modified_date']);
920 $this->assertApproxEquals(strtotime($case_1['created_date']), strtotime($case_1['modified_date']), 2);
921
922 $activity_1 = $this->callAPISuccess('activity', 'getsingle', array(
923 'case_id' => $case_created['id'],
924 'options' => array(
925 'limit' => 1,
926 ),
927 ));
928 $this->assertRegExp(';^\d\d\d\d-\d\d-\d\d \d\d:\d\d;', $activity_1['created_date']);
929 $this->assertRegExp(';^\d\d\d\d-\d\d-\d\d \d\d:\d\d;', $activity_1['modified_date']);
930 $this->assertApproxEquals(strtotime($activity_1['created_date']), strtotime($activity_1['modified_date']), 2);
931
932 usleep(1.5 * 1000000);
933 $this->callAPISuccess('activity', 'create', array(
934 'id' => $activity_1['id'],
935 'subject' => 'Make cheese',
936 ));
937
938 $activity_2 = $this->callAPISuccess('activity', 'getsingle', array(
939 'id' => $activity_1['id'],
940 ));
941 $this->assertRegExp(';^\d\d\d\d-\d\d-\d\d \d\d:\d\d;', $activity_2['created_date']);
942 $this->assertRegExp(';^\d\d\d\d-\d\d-\d\d \d\d:\d\d;', $activity_2['modified_date']);
943 $this->assertNotEquals($activity_2['created_date'], $activity_2['modified_date']);
944
945 $this->assertEquals($activity_1['created_date'], $activity_2['created_date']);
946 $this->assertNotEquals($activity_1['modified_date'], $activity_2['modified_date']);
947 $this->assertLessThan($activity_2['modified_date'], $activity_1['modified_date'],
948 sprintf("Original modification time (%s) should predate later modification time (%s)", $activity_1['modified_date'], $activity_2['modified_date']));
949
950 $case_2 = $this->callAPISuccess('Case', 'getsingle', array(
951 'id' => $case_created['id'],
952 ));
953 $this->assertRegExp(';^\d\d\d\d-\d\d-\d\d \d\d:\d\d;', $case_2['created_date']);
954 $this->assertRegExp(';^\d\d\d\d-\d\d-\d\d \d\d:\d\d;', $case_2['modified_date']);
955 $this->assertEquals($case_1['created_date'], $case_2['created_date']);
956 $this->assertNotEquals($case_2['created_date'], $case_2['modified_date']);
957 }
958
6a488035 959}