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