9ad9bffe201d3d8aa5bea7f71102f46c67784499
[civicrm-core.git] / tests / phpunit / CRM / Case / BAO / CaseTest.php
1 <?php
2
3 /**
4 * Class CRM_Case_BAO_CaseTest
5 * @group headless
6 */
7 class CRM_Case_BAO_CaseTest extends CiviUnitTestCase {
8
9 public function setUp() {
10 parent::setUp();
11
12 $this->tablesToTruncate = [
13 'civicrm_activity',
14 'civicrm_contact',
15 'civicrm_custom_group',
16 'civicrm_custom_field',
17 'civicrm_case',
18 'civicrm_case_contact',
19 'civicrm_case_activity',
20 'civicrm_case_type',
21 'civicrm_activity_contact',
22 'civicrm_managed',
23 'civicrm_relationship',
24 'civicrm_relationship_type',
25 ];
26
27 $this->quickCleanup($this->tablesToTruncate);
28
29 $this->loadAllFixtures();
30
31 CRM_Core_BAO_ConfigSetting::enableComponent('CiviCase');
32 }
33
34 /**
35 * Make sure that the latest case activity works accurately.
36 */
37 public function testCaseActivity() {
38 $userID = $this->createLoggedInUser();
39
40 $addTimeline = civicrm_api3('Case', 'addtimeline', [
41 'case_id' => 1,
42 'timeline' => "standard_timeline",
43 ]);
44
45 $query = CRM_Case_BAO_Case::getCaseActivityQuery('recent', $userID, ' civicrm_case.id IN( 1 )');
46 $res = CRM_Core_DAO::executeQuery($query);
47 $openCaseType = CRM_Core_PseudoConstant::getKey('CRM_Activity_BAO_Activity', 'activity_type_id', 'Open Case');
48 while ($res->fetch()) {
49 $message = 'Failed asserting that the case activity query has a activity_type_id property:';
50 $this->assertObjectHasAttribute('activity_type_id', $res, $message . PHP_EOL . print_r($res, TRUE));
51 $message = 'Failed asserting that the latest activity from Case ID 1 was "Open Case":';
52 $this->assertEquals($openCaseType, $res->activity_type_id, $message . PHP_EOL . print_r($res, TRUE));
53 }
54 }
55
56 protected function tearDown() {
57 parent::tearDown();
58 $this->quickCleanup($this->tablesToTruncate, TRUE);
59 }
60
61 public function testAddCaseToContact() {
62 $params = [
63 'case_id' => 1,
64 'contact_id' => 17,
65 ];
66 CRM_Case_BAO_CaseContact::create($params);
67
68 $recent = CRM_Utils_Recent::get();
69 $this->assertEquals('Test Contact - Housing Support', $recent[0]['title']);
70 }
71
72 /**
73 * Create and return case object of given Client ID.
74 * @param $clientId
75 * @param $loggedInUser
76 * @return CRM_Case_BAO_Case
77 */
78 private function createCase($clientId, $loggedInUser = NULL) {
79 if (empty($loggedInUser)) {
80 // backwards compatibility - but it's more typical that the creator is a different person than the client
81 $loggedInUser = $clientId;
82 }
83 $caseParams = [
84 'activity_subject' => 'Case Subject',
85 'client_id' => $clientId,
86 'case_type_id' => 1,
87 'status_id' => 1,
88 'case_type' => 'housing_support',
89 'subject' => 'Case Subject',
90 'start_date' => date("Y-m-d"),
91 'start_date_time' => date("YmdHis"),
92 'medium_id' => 2,
93 'activity_details' => '',
94 ];
95 $form = new CRM_Case_Form_Case();
96 $caseObj = $form->testSubmit($caseParams, "OpenCase", $loggedInUser, "standalone");
97 return $caseObj;
98 }
99
100 /**
101 * Create case role relationship between given contacts for provided case ID.
102 *
103 * @param $contactIdA
104 * @param $contactIdB
105 * @param $caseId
106 * @param bool $isActive
107 */
108 private function createCaseRoleRelationship($contactIdA, $contactIdB, $caseId, $isActive = TRUE) {
109 $relationshipType = $this->relationshipTypeCreate([
110 'contact_type_b' => 'Individual',
111 ]);
112
113 $this->callAPISuccess('Relationship', 'create', [
114 'contact_id_a' => $contactIdA,
115 'contact_id_b' => $contactIdB,
116 'relationship_type_id' => $relationshipType,
117 'case_id' => $caseId,
118 'is_active' => $isActive,
119 ]);
120 }
121
122 /**
123 * Asserts number of cases for given logged in user.
124 *
125 * @param $loggedInUser
126 * @param $caseId
127 * @param $caseCount
128 */
129 private function assertCasesOfUser($loggedInUser, $caseId, $caseCount) {
130 $summary = CRM_Case_BAO_Case::getCasesSummary(FALSE);
131 $upcomingCases = CRM_Case_BAO_Case::getCases(FALSE, [], 'dashboard', TRUE);
132 $caseRoles = CRM_Case_BAO_Case::getCaseRoles($loggedInUser, $caseId);
133
134 $this->assertEquals($caseCount, $upcomingCases, 'Upcoming case count must be ' . $caseCount);
135 $this->assertEquals($caseCount, $summary['rows']['Housing Support']['Ongoing']['count'], 'Housing Support Ongoing case summary must be ' . $caseCount);
136 $this->assertEquals($caseCount, count($caseRoles), 'Total case roles for logged in users must be ' . $caseCount);
137 }
138
139 /**
140 * core/issue-1623: My Case dashlet doesn't sort by name but contact_id instead
141 *
142 * @throws \CRM_Core_Exception
143 */
144 public function testSortByCaseContact() {
145 // delete any cases if present
146 $this->callAPISuccess('Case', 'get', ['api.Case.delete' => ['id' => '$value.id']]);
147
148 // create three contacts with different name, later used in respective cases
149 $contacts = [
150 $this->individualCreate(['first_name' => 'Antonia', 'last_name' => 'D`souza']),
151 $this->individualCreate(['first_name' => 'Darric', 'last_name' => 'Roy']),
152 $this->individualCreate(['first_name' => 'Adam', 'last_name' => 'Pitt']),
153 ];
154 $loggedInUser = $this->createLoggedInUser();
155 $relationshipType = $this->relationshipTypeCreate([
156 'contact_type_b' => 'Individual',
157 ]);
158
159 // create cases for each contact
160 $cases = [];
161 foreach ($contacts as $contactID) {
162 $cases[] = $caseID = $this->createCase($contactID)->id;
163 $this->callAPISuccess('Relationship', 'create', [
164 'contact_id_a' => $contactID,
165 'contact_id_b' => $loggedInUser,
166 'relationship_type_id' => $relationshipType,
167 'case_id' => $caseID,
168 'is_active' => TRUE,
169 ]);
170 }
171
172 // USECASE A: fetch all cases using the AJAX fn without any sorting criteria, and match the result
173 global $_GET;
174 $_GET = [
175 'start' => 0,
176 'length' => 10,
177 'type' => 'any',
178 'all' => 1,
179 'is_unittest' => 1,
180 ];
181
182 $cases = [];
183 try {
184 CRM_Case_Page_AJAX::getCases();
185 }
186 catch (CRM_Core_Exception_PrematureExitException $e) {
187 $cases = $e->errorData['data'];
188 }
189
190 // list of expected sorted names in order the respective cases were created
191 $unsortedExpectedContactNames = [
192 'D`souza, Antonia',
193 'Roy, Darric',
194 'Pitt, Adam',
195 ];
196 $unsortedActualContactNames = CRM_Utils_Array::collect('sort_name', $cases);
197 foreach ($unsortedExpectedContactNames as $key => $name) {
198 $this->assertContains($name, $unsortedActualContactNames[$key]);
199 }
200
201 // USECASE B: fetch all cases using the AJAX fn based any 'Contact' sorting criteria, and match the result against expected sequence of names
202 $_GET = [
203 'start' => 0,
204 'length' => 10,
205 'type' => 'any',
206 'all' => 1,
207 'is_unittest' => 1,
208 'columns' => [
209 1 => [
210 'data' => 'sort_name',
211 'name' => NULL,
212 'searchable' => TRUE,
213 'orderable' => TRUE,
214 'search' => [
215 'value' => NULL,
216 'regex' => FALSE,
217 ],
218 ],
219 ],
220 'order' => [
221 [
222 'column' => 1,
223 'dir' => 'asc',
224 ],
225 ],
226 ];
227
228 $cases = [];
229 try {
230 CRM_Case_Page_AJAX::getCases();
231 }
232 catch (CRM_Core_Exception_PrematureExitException $e) {
233 $cases = $e->errorData['data'];
234 }
235
236 // list of expected sorted names in ASC order
237 $sortedExpectedContactNames = [
238 'D`souza, Antonia',
239 'Pitt, Adam',
240 'Roy, Darric',
241 ];
242 $sortedActualContactNames = CRM_Utils_Array::collect('sort_name', $cases);
243 foreach ($sortedExpectedContactNames as $key => $name) {
244 $this->assertContains($name, $sortedActualContactNames[$key]);
245 }
246 }
247
248 /**
249 * Test that Case count is exactly one for logged in user for user's active role.
250 *
251 * @throws \CRM_Core_Exception
252 */
253 public function testActiveCaseRole() {
254 $individual = $this->individualCreate();
255 $caseObj = $this->createCase($individual);
256 $caseId = $caseObj->id;
257 $loggedInUser = $this->createLoggedInUser();
258 $this->createCaseRoleRelationship($individual, $loggedInUser, $caseId);
259 $this->assertCasesOfUser($loggedInUser, $caseId, 1);
260 }
261
262 /**
263 * Test that case count is zero for logged in user for user's inactive role.
264 */
265 public function testInactiveCaseRole() {
266 $individual = $this->individualCreate();
267 $caseObj = $this->createCase($individual);
268 $caseId = $caseObj->id;
269 $loggedInUser = $this->createLoggedInUser();
270 $this->createCaseRoleRelationship($individual, $loggedInUser, $caseId, FALSE);
271 $this->assertCasesOfUser($loggedInUser, $caseId, 0);
272 }
273
274 public function testGetCaseType() {
275 $caseTypeLabel = CRM_Case_BAO_Case::getCaseType(1);
276 $this->assertEquals('Housing Support', $caseTypeLabel);
277 }
278
279 public function testRetrieveCaseIdsByContactId() {
280 $caseIds = CRM_Case_BAO_Case::retrieveCaseIdsByContactId(3, FALSE, 'housing_support');
281 $this->assertEquals([1], $caseIds);
282 }
283
284 /**
285 * Test that all custom files are migrated to new case when case is assigned to new client.
286 */
287 public function testCaseReassignForCustomFiles() {
288 $individual = $this->individualCreate();
289 $customGroup = $this->customGroupCreate(array(
290 'extends' => 'Case',
291 ));
292 $customGroup = $customGroup['values'][$customGroup['id']];
293
294 $customFileFieldA = $this->customFieldCreate(array(
295 'custom_group_id' => $customGroup['id'],
296 'html_type' => 'File',
297 'is_active' => 1,
298 'default_value' => 'null',
299 'label' => 'Custom File A',
300 'data_type' => 'File',
301 ));
302
303 $customFileFieldB = $this->customFieldCreate(array(
304 'custom_group_id' => $customGroup['id'],
305 'html_type' => 'File',
306 'is_active' => 1,
307 'default_value' => 'null',
308 'label' => 'Custom File B',
309 'data_type' => 'File',
310 ));
311
312 // Create two files to attach to the new case
313 $filepath = Civi::paths()->getPath('[civicrm.files]/custom');
314
315 CRM_Utils_File::createFakeFile($filepath, 'Bananas do not bend themselves without a little help.', 'i_bend_bananas.txt');
316 $fileA = $this->callAPISuccess('File', 'create', ['uri' => "$filepath/i_bend_bananas.txt"]);
317
318 CRM_Utils_File::createFakeFile($filepath, 'Wombats will bite your ankles if you run from them.', 'wombats_bite_your_ankles.txt');
319 $fileB = $this->callAPISuccess('File', 'create', ['uri' => "$filepath/wombats_bite_your_ankles.txt"]);
320
321 $caseObj = $this->createCase($individual);
322
323 $this->callAPISuccess('Case', 'create', array(
324 'id' => $caseObj->id,
325 'custom_' . $customFileFieldA['id'] => $fileA['id'],
326 'custom_' . $customFileFieldB['id'] => $fileB['id'],
327 ));
328
329 $reassignIndividual = $this->individualCreate();
330 $this->createLoggedInUser();
331 $newCase = CRM_Case_BAO_Case::mergeCases($reassignIndividual, $caseObj->id, $individual, NULL, TRUE);
332
333 $entityFiles = new CRM_Core_DAO_EntityFile();
334 $entityFiles->entity_id = $newCase[0];
335 $entityFiles->entity_table = $customGroup['table_name'];
336 $entityFiles->find();
337
338 $totalEntityFiles = 0;
339 while ($entityFiles->fetch()) {
340 $totalEntityFiles++;
341 }
342
343 $this->assertEquals(2, $totalEntityFiles, 'Two files should be attached with new case.');
344 }
345
346 /**
347 * FIXME: need to create an activity to run this test
348 * function testGetCases() {
349 * $cases = CRM_Case_BAO_Case::getCases(TRUE, 3);
350 * $this->assertEquals('Housing Support', $cases[1]['case_type']);
351 * $this->assertEquals(1, $cases[1]['case_type_id']);
352 * }
353 */
354 public function testGetCasesSummary() {
355 $cases = CRM_Case_BAO_Case::getCasesSummary();
356 $this->assertEquals(1, $cases['rows']['Housing Support']['Ongoing']['count']);
357 }
358
359 /**
360 * Test that getRelatedCases() returns the other case when you create a
361 * Link Cases activity on one of the cases.
362 */
363 public function testGetRelatedCases() {
364 $loggedInUser = $this->createLoggedInUser();
365 // create some cases
366 $client_id_1 = $this->individualCreate([], 0);
367 $caseObj_1 = $this->createCase($client_id_1, $loggedInUser);
368 $case_id_1 = $caseObj_1->id;
369 $client_id_2 = $this->individualCreate([], 1);
370 $caseObj_2 = $this->createCase($client_id_2, $loggedInUser);
371 $case_id_2 = $caseObj_2->id;
372
373 // Create link case activity. We could go thru the whole form processes
374 // but we really just want to test the BAO function so just need the
375 // activity to exist.
376 $result = $this->callAPISuccess('activity', 'create', [
377 'activity_type_id' => 'Link Cases',
378 'subject' => 'Test Link Cases',
379 'status_id' => 'Completed',
380 'source_contact_id' => $loggedInUser,
381 'target_contact_id' => $client_id_1,
382 'case_id' => $case_id_1,
383 ]);
384
385 // Put it in the format needed for endPostProcess
386 $activity = new StdClass();
387 $activity->id = $result['id'];
388 $params = [
389 'link_to_case_id' => $case_id_2,
390 ];
391 CRM_Case_Form_Activity_LinkCases::endPostProcess(NULL, $params, $activity);
392
393 // Get related cases for case 1
394 $cases = CRM_Case_BAO_Case::getRelatedCases($case_id_1);
395 // It should have case 2
396 $this->assertEquals($case_id_2, $cases[$case_id_2]['case_id']);
397
398 // Ditto but reverse the cases
399 $cases = CRM_Case_BAO_Case::getRelatedCases($case_id_2);
400 $this->assertEquals($case_id_1, $cases[$case_id_1]['case_id']);
401 }
402
403 /**
404 * Test various things after a case is closed.
405 *
406 * This annotation is not ideal, but without it there is some kind of
407 * messup that happens to quickform that persists between tests, e.g.
408 * it can't add maxfilesize validation rules.
409 * @runInSeparateProcess
410 * @preserveGlobalState disabled
411 */
412 public function testCaseClosure() {
413 $loggedInUser = $this->createLoggedInUser();
414 $client_id = $this->individualCreate();
415 $caseObj = $this->createCase($client_id, $loggedInUser);
416 $case_id = $caseObj->id;
417
418 // Get the case status option value for "Resolved" (name="Closed").
419 $closed_status = $this->callAPISuccess('OptionValue', 'getValue', [
420 'return' => 'value',
421 'option_group_id' => 'case_status',
422 'name' => 'Closed',
423 ]);
424 $this->assertNotEmpty($closed_status);
425
426 // Get the activity status option value for "Completed"
427 $completed_status = $this->callAPISuccess('OptionValue', 'getValue', [
428 'return' => 'value',
429 'option_group_id' => 'activity_status',
430 'name' => 'Completed',
431 ]);
432 $this->assertNotEmpty($completed_status);
433
434 // Get the value for the activity type id we need to create
435 $atype = CRM_Core_PseudoConstant::getKey('CRM_Activity_BAO_Activity', 'activity_type_id', 'Change Case Status');
436
437 // Now it gets weird. There doesn't seem to be a good way to test this, so we simulate a form and the various bits that go with it.
438
439 // HTTP vars needed because that's how the form determines stuff
440 $oldMETHOD = empty($_SERVER['REQUEST_METHOD']) ? NULL : $_SERVER['REQUEST_METHOD'];
441 $oldGET = empty($_GET) ? [] : $_GET;
442 $oldREQUEST = empty($_REQUEST) ? [] : $_REQUEST;
443 $_SERVER['REQUEST_METHOD'] = 'GET';
444 $_GET['caseid'] = $case_id;
445 $_REQUEST['caseid'] = $case_id;
446 $_GET['cid'] = $client_id;
447 $_REQUEST['cid'] = $client_id;
448 $_GET['action'] = 'add';
449 $_REQUEST['action'] = 'add';
450 $_GET['reset'] = 1;
451 $_REQUEST['reset'] = 1;
452 $_GET['atype'] = $atype;
453 $_REQUEST['atype'] = $atype;
454
455 $form = new CRM_Case_Form_Activity();
456 $form->controller = new CRM_Core_Controller_Simple('CRM_Case_Form_Activity', 'Case Activity');
457 $form->_activityTypeId = $atype;
458 $form->_activityTypeName = 'Change Case Status';
459 $form->_activityTypeFile = 'ChangeCaseStatus';
460
461 $form->preProcess();
462 $form->buildQuickForm();
463 $form->setDefaultValues();
464
465 // Now submit the form. Store the date used so we can check it later.
466
467 $t = time();
468 $now_date = date('Y-m-d H:i:s', $t);
469 $now_date_date_only = date('Y-m-d', $t);
470 $actParams = [
471 'is_unittest' => TRUE,
472 'case_status_id' => $closed_status,
473 'activity_date_time' => $now_date,
474 'target_contact_id' => $client_id,
475 'source_contact_id' => $loggedInUser,
476 // yeah this is extra weird, but without it you get the wrong subject
477 'subject' => 'null',
478 ];
479
480 $form->postProcess($actParams);
481
482 // Ok now let's check some things
483
484 $result = $this->callAPISuccess('Case', 'get', [
485 'sequential' => 1,
486 'id' => $case_id,
487 ]);
488 $caseData = array_shift($result['values']);
489
490 $this->assertEquals($caseData['end_date'], $now_date_date_only);
491 $this->assertEquals($caseData['status_id'], $closed_status);
492
493 // now get the latest activity and check some things for it
494
495 $actId = max($caseData['activities']);
496 $this->assertNotEmpty($actId);
497
498 $result = $this->callAPISuccess('Activity', 'get', [
499 'sequential' => 1,
500 'id' => $actId,
501 ]);
502 $activity = array_shift($result['values']);
503
504 $this->assertEquals($activity['subject'], 'Case status changed from Ongoing to Resolved');
505 $this->assertEquals($activity['activity_date_time'], $now_date);
506 $this->assertEquals($activity['status_id'], $completed_status);
507
508 // Now replace old globals
509 if (is_null($oldMETHOD)) {
510 unset($_SERVER['REQUEST_METHOD']);
511 }
512 else {
513 $_SERVER['REQUEST_METHOD'] = $oldMETHOD;
514 }
515 $_GET = $oldGET;
516 $_REQUEST = $oldREQUEST;
517 }
518
519 /**
520 * Test getGlobalContacts
521 */
522 public function testGetGlobalContacts() {
523 //Add contact to case resource.
524 $caseResourceContactID = $this->individualCreate();
525 $this->callAPISuccess('GroupContact', 'create', [
526 'group_id' => "Case_Resources",
527 'contact_id' => $caseResourceContactID,
528 ]);
529
530 //No contact should be returned.
531 CRM_Core_Config::singleton()->userPermissionClass->permissions = [];
532 $groupInfo = [];
533 $groupContacts = CRM_Case_BAO_Case::getGlobalContacts($groupInfo);
534 $this->assertEquals(0, count($groupContacts));
535
536 //Verify if contact is returned correctly.
537 CRM_Core_Config::singleton()->userPermissionClass->permissions = [
538 'access CiviCRM',
539 'view all contacts',
540 ];
541 $groupInfo = [];
542 $groupContacts = CRM_Case_BAO_Case::getGlobalContacts($groupInfo);
543 $this->assertEquals(1, count($groupContacts));
544 $this->assertEquals($caseResourceContactID, key($groupContacts));
545 }
546
547 /**
548 * Test max_instances
549 */
550 public function testMaxInstances() {
551 $loggedInUser = $this->createLoggedInUser();
552 $client_id = $this->individualCreate();
553 $caseObj = $this->createCase($client_id, $loggedInUser);
554 $case_id = $caseObj->id;
555
556 // Sanity check to make sure we'll be testing what we think we're testing.
557 $this->assertEquals($caseObj->case_type_id, 1);
558
559 // Get the case type
560 $result = $this->callAPISuccess('CaseType', 'get', [
561 'sequential' => 1,
562 'id' => 1,
563 ]);
564 $caseType = array_shift($result['values']);
565 $activityTypeName = $caseType['definition']['activityTypes'][1]['name'];
566 // Sanity check to make sure we'll be testing what we think we're testing.
567 $this->assertEquals($activityTypeName, "Medical evaluation");
568
569 // Look up the activity type label - we need it later
570 $result = $this->callAPISuccess('OptionValue', 'get', [
571 'sequential' => 1,
572 'option_group_id' => 'activity_type',
573 'name' => $activityTypeName,
574 ]);
575 $optionValue = array_shift($result['values']);
576 $activityTypeLabel = $optionValue['label'];
577 $this->assertNotEmpty($activityTypeLabel);
578
579 // Locate the existing activity independently so we can check it
580 $result = $this->callAPISuccess('Activity', 'get', [
581 'sequential' => 1,
582 // this sometimes confuses me - pass in the name for the id
583 'activity_type_id' => $activityTypeName,
584 ]);
585 // There should be only one in the database at this point so this should be the id.
586 $activity_id = $result['id'];
587 $this->assertNotEmpty($activity_id);
588 $this->assertGreaterThan(0, $activity_id);
589 $activityArr = array_shift($result['values']);
590
591 // At the moment everything should be happy, although there's nothing to test because if max_instances has no value then nothing gets called, which is correct since it means unlimited. But we don't have a way to test that right now. For fun we could test max_instances=0 but that isn't the same as "not set". 0 would actually mean 0 are allowed, which is pointless, since then why would you even add the activity type to the config.
592
593 // Update max instances for the activity type
594 // We're not really checking that the tested code has retrieved the new case type definition, just that given some numbers as input it returns the right thing as output, so these lines are mostly symbolic at the moment.
595 $caseType['definition']['activityTypes'][1]['max_instances'] = 1;
596 $this->callAPISuccess('CaseType', 'create', $caseType);
597
598 // Now we should get a link back
599 $editUrl = CRM_Case_Form_Activity::checkMaxInstances(
600 $case_id,
601 $activityArr['activity_type_id'],
602 // max instances
603 1,
604 $loggedInUser,
605 $client_id,
606 // existing activity count
607 1
608 );
609 $this->assertNotNull($editUrl);
610
611 $expectedUrl = CRM_Utils_System::url(
612 'civicrm/case/activity',
613 "reset=1&cid={$client_id}&caseid={$case_id}&action=update&id={$activity_id}"
614 );
615 $this->assertEquals($editUrl, $expectedUrl);
616
617 // And also a bounce message is expected
618 $bounceMessage = CRM_Case_Form_Activity::getMaxInstancesBounceMessage(
619 $editUrl,
620 $activityTypeLabel,
621 // max instances,
622 1,
623 // existing activity count
624 1
625 );
626 $this->assertNotEmpty($bounceMessage);
627
628 // Now check with max_instances = 2
629 $caseType['definition']['activityTypes'][1]['max_instances'] = 2;
630 $this->callAPISuccess('CaseType', 'create', $caseType);
631
632 // So it should now be back to being happy
633 $editUrl = CRM_Case_Form_Activity::checkMaxInstances(
634 $case_id,
635 $activityArr['activity_type_id'],
636 // max instances
637 2,
638 $loggedInUser,
639 $client_id,
640 // existing activity count
641 1
642 );
643 $this->assertNull($editUrl);
644 $bounceMessage = CRM_Case_Form_Activity::getMaxInstancesBounceMessage(
645 $editUrl,
646 $activityTypeLabel,
647 // max instances,
648 2,
649 // existing activity count
650 1
651 );
652 $this->assertEmpty($bounceMessage);
653
654 // Add new activity check again
655 $newActivity = [
656 'case_id' => $case_id,
657 'activity_type_id' => $activityArr['activity_type_id'],
658 'status_id' => $activityArr['status_id'],
659 'subject' => "A different subject",
660 'activity_date_time' => date('Y-m-d H:i:s'),
661 'source_contact_id' => $loggedInUser,
662 'target_id' => $client_id,
663 ];
664 $this->callAPISuccess('Activity', 'create', $newActivity);
665
666 $editUrl = CRM_Case_Form_Activity::checkMaxInstances(
667 $case_id,
668 $activityArr['activity_type_id'],
669 // max instances
670 2,
671 $loggedInUser,
672 $client_id,
673 // existing activity count
674 2
675 );
676 // There should be no url here.
677 $this->assertNull($editUrl);
678
679 // But there should be a warning message still.
680 $bounceMessage = CRM_Case_Form_Activity::getMaxInstancesBounceMessage(
681 $editUrl,
682 $activityTypeLabel,
683 // max instances,
684 2,
685 // existing activity count
686 2
687 );
688 $this->assertNotEmpty($bounceMessage);
689 }
690
691 /**
692 * Test changing the label for the case manager role and then creating
693 * a case.
694 * At the time this test was written this test would fail, demonstrating
695 * one problem with name vs label.
696 */
697 public function testCreateCaseWithChangedManagerLabel() {
698 // We could just assume the relationship that gets created has
699 // relationship_type_id = 1, but let's create a case, see what the
700 // id is, then do our actual test.
701 $loggedInUser = $this->createLoggedInUser();
702 $client_id = $this->individualCreate();
703 $caseObj = $this->createCase($client_id, $loggedInUser);
704 $case_id = $caseObj->id;
705
706 // Going to assume the stock case type has what it currently has at the
707 // time of writing, which is the autocreated case manager relationship for
708 // the logged in user.
709 $getParams = [
710 'contact_id_b' => $loggedInUser,
711 'case_id' => $case_id,
712 ];
713 $result = $this->callAPISuccess('Relationship', 'get', $getParams);
714 // as noted above assume this is the only one
715 $relationship_type_id = $result['values'][$result['id']]['relationship_type_id'];
716
717 // Save the old labels first so we can put back at end of test.
718 $oldParams = [
719 'id' => $relationship_type_id,
720 ];
721 $oldValues = $this->callAPISuccess('RelationshipType', 'get', $oldParams);
722 // Now change the label of the relationship type.
723 $changeParams = [
724 'id' => $relationship_type_id,
725 'label_a_b' => 'Best ' . $oldValues['values'][$relationship_type_id]['label_a_b'],
726 'label_b_a' => 'Best ' . $oldValues['values'][$relationship_type_id]['label_b_a'],
727 ];
728 $this->callAPISuccess('RelationshipType', 'create', $changeParams);
729
730 // Now try creating another case.
731 $caseObj2 = $this->createCase($client_id, $loggedInUser);
732 $case_id2 = $caseObj2->id;
733
734 $checkParams = [
735 'contact_id_b' => $loggedInUser,
736 'case_id' => $case_id2,
737 ];
738 $result = $this->callAPISuccess('Relationship', 'get', $checkParams);
739 // Main thing is the above createCase call doesn't fail, but let's check
740 // the relationship type id is what we expect too while we're here.
741 // See note above about assuming this is the only relationship autocreated.
742 $this->assertEquals($relationship_type_id, $result['values'][$result['id']]['relationship_type_id']);
743
744 // Now put relationship type back to the way it was.
745 $changeParams = [
746 'id' => $relationship_type_id,
747 'label_a_b' => $oldValues['values'][$relationship_type_id]['label_a_b'],
748 'label_b_a' => $oldValues['values'][$relationship_type_id]['label_b_a'],
749 ];
750 $this->callAPISuccess('RelationshipType', 'create', $changeParams);
751 }
752
753 }