Merge pull request #17953 from civicrm/5.28
[civicrm-core.git] / tests / phpunit / CRM / Case / XMLProcessor / ReportTest.php
CommitLineData
d42b8a81
D
1<?php
2require_once 'CiviTest/CiviCaseTestCase.php';
3
4/**
5 * Class CRM_Case_XMLProcessor_ReportTest
6 * @group headless
7 */
8class CRM_Case_XMLProcessor_ReportTest extends CiviCaseTestCase {
9
10 public function setUp() {
11 parent::setUp();
12
13 $this->simplifyCaseTypeDefinition();
14
15 $this->report = new CRM_Case_XMLProcessor_Report();
16 }
17
18 public function tearDown() {
19 parent::tearDown();
20 }
21
22 /**
23 * Test that getCaseReport has the right output.
24 *
25 * @param $activitySetName string Also acts as data provider test identifier.
26 * @param $expected array
27 *
28 * @dataProvider caseReportDataProvider
29 */
30 public function testGetCaseReport($activitySetName, $expected) {
31 $client_id = $this->individualCreate([
32 'first_name' => 'Casey',
33 'middle_name' => '',
34 'last_name' => 'Reportee',
35 'prefix_id' => NULL,
36 'suffix_id' => NULL,
37 ]);
38 $caseObj = $this->createCase($client_id, $this->_loggedInUser);
39 $case_id = $caseObj->id;
40
41 // Add an additional meeting activity not in the timeline to the case.
42 $meetingTypeId = $this->callAPISuccess('OptionValue', 'getsingle', [
43 'return' => ["value"],
44 'option_group_id' => 'activity_type',
45 'name' => 'Meeting',
46 ]);
47 $this->callAPISuccess('activity', 'create', [
48 'case_id' => $case_id,
49 'activity_type_id' => $meetingTypeId['value'],
50 'activity_date_time' => '20191114123456',
51 'subject' => 'Test Meeting',
52 'source_contact_id' => $this->_loggedInUser,
53 'target_contact_id' => $client_id,
54 ]);
55
56 $caseReportParams = [
57 'is_redact' => FALSE,
58 'include_activities' => 1,
59 ];
60
61 // run the thing we're testing and get the output vars
62 $template = CRM_Case_XMLProcessor_Report::populateCaseReportTemplate($client_id, $case_id, $activitySetName, $caseReportParams, $this->report);
63 $assigned_vars = $template->get_template_vars();
64
65 // Update $expected now since dataprovider doesn't have access to the variables from setup() because it runs before setup.
66 $this->updateExpectedBecauseDataProviderEvaluatesBeforeEverything($expected, $client_id, $case_id);
67
68 foreach ($expected as $key => $value) {
69 // does the assigned template var match the expected value?
70 $this->assertEquals($value, $assigned_vars[$key], "$activitySetName: $key does not match" . print_r($assigned_vars[$key], TRUE));
71 }
72 }
73
a9410a63 74 /**
75 * This is similar to testGetCaseReport but test with a timeline that
76 * does have Meeting in it.
77 */
78 public function testGetCaseReportWithMeetingInTimeline() {
79 $client_id = $this->individualCreate([
80 'first_name' => 'Casey',
81 'middle_name' => '',
82 'last_name' => 'Reportee',
83 'prefix_id' => NULL,
84 'suffix_id' => NULL,
85 ]);
86 $caseObj = $this->createCase($client_id, $this->_loggedInUser);
87 $case_id = $caseObj->id;
88
89 // Now update the timeline so it has Meeting in it.
90 $this->addMeetingToTimeline();
91
92 // Add a meeting activity to the case.
93 $meetingTypeId = $this->callAPISuccess('OptionValue', 'getsingle', [
94 'return' => ["value"],
95 'option_group_id' => 'activity_type',
96 'name' => 'Meeting',
97 ]);
98 $this->callAPISuccess('activity', 'create', [
99 'case_id' => $case_id,
100 'activity_type_id' => $meetingTypeId['value'],
101 'activity_date_time' => '20191114123456',
102 'subject' => 'Test Meeting',
103 'source_contact_id' => $this->_loggedInUser,
104 'target_contact_id' => $client_id,
105 ]);
106
107 $caseReportParams = [
108 'is_redact' => FALSE,
109 'include_activities' => 1,
110 ];
111
112 // run the thing we're testing and get the output vars
113 $template = CRM_Case_XMLProcessor_Report::populateCaseReportTemplate($client_id, $case_id, 'standard_timeline', $caseReportParams, $this->report);
114 $assigned_vars = $template->get_template_vars();
115
116 // We don't want to run all the data in the dataprovider but we know
117 // in this case it should be the same as the second one in the
118 // dataprovider so we can reuse it.
119 $expected = $this->caseReportDataProvider()[1][1];
120 $this->updateExpectedBecauseDataProviderEvaluatesBeforeEverything($expected, $client_id, $case_id);
121
122 foreach ($expected as $key => $value) {
123 // does the assigned template var match the expected value?
124 $this->assertEquals($value, $assigned_vars[$key], "$key does not match" . print_r($assigned_vars[$key], TRUE));
125 }
126 }
127
d42b8a81
D
128 /**
129 * Data provider for testGetCaseReport
130 * @return array
131 */
132 public function caseReportDataProvider() {
133 return [
134 [
135 // activity set name
136 'standard_timeline',
a9410a63 137 // Some expected assigned vars of CRM_Core_Smarty template.
138 // In particular we shouldn't have meeting in the output since it's
139 // not in the timeline.
d42b8a81
D
140 [
141 'case' => [
142 'clientName' => 'Casey Reportee',
143 'subject' => 'Case Subject',
144 'start_date' => '2019-11-14',
145 'end_date' => NULL,
146 'caseType' => 'Housing Support',
147 'caseTypeName' => 'housing_support',
148 'status' => 'Ongoing',
149 ],
150 'activities' => [
151 0 => [
152 'fields' => [
153 0 => [
1474f129 154 'name' => 'Client',
d42b8a81
D
155 'label' => 'Client',
156 'value' => 'Casey Reportee',
157 'type' => 'String',
158 ],
159 1 => [
1474f129 160 'name' => 'Activity Type',
d42b8a81
D
161 'label' => 'Activity Type',
162 'value' => 'Open Case',
163 'type' => 'String',
164 ],
165 2 => [
1474f129 166 'name' => 'Subject',
d42b8a81
D
167 'label' => 'Subject',
168 'value' => 'Case Subject',
169 'type' => 'Memo',
170 ],
171 3 => [
1474f129 172 'name' => 'Created By',
d42b8a81
D
173 'label' => 'Created By',
174 // data providers run before everything, so update this later
175 'value' => 'placeholder',
176 'type' => 'String',
177 ],
178 4 => [
1474f129 179 'name' => 'Reported By',
d42b8a81
D
180 'label' => 'Reported By',
181 // see above - need to update this later
182 'value' => 'placeholder',
183 'type' => 'String',
184 ],
185 5 => [
1474f129 186 'name' => 'Medium',
d42b8a81
D
187 'label' => 'Medium',
188 'value' => 'Phone',
189 'type' => 'String',
190 ],
191 6 => [
1474f129 192 'name' => 'Location',
d42b8a81
D
193 'label' => 'Location',
194 'value' => NULL,
195 'type' => 'String',
196 ],
197 7 => [
1474f129 198 'name' => 'Date and Time',
d42b8a81
D
199 'label' => 'Date and Time',
200 'value' => '2019-11-14 00:00:00',
201 'type' => 'Date',
202 ],
203 8 => [
1474f129 204 'name' => 'Details',
d42b8a81
D
205 'label' => 'Details',
206 'value' => NULL,
207 'type' => 'Memo',
208 ],
209 9 => [
1474f129 210 'name' => 'Status',
d42b8a81
D
211 'label' => 'Status',
212 'value' => 'Completed',
213 'type' => 'String',
214 ],
215 10 => [
1474f129 216 'name' => 'Priority',
d42b8a81
D
217 'label' => 'Priority',
218 'value' => 'Normal',
219 'type' => 'String',
220 ],
221 ],
222 'editURL' => 'placeholder',
223 'customGroups' => NULL,
224 ],
225 1 => [
226 'fields' => [
227 0 => [
1474f129 228 'name' => 'Client',
d42b8a81
D
229 'label' => 'Client',
230 'value' => 'Casey Reportee',
231 'type' => 'String',
232 ],
233 1 => [
1474f129 234 'name' => 'Activity Type',
d42b8a81
D
235 'label' => 'Activity Type',
236 'value' => 'Medical evaluation',
237 'type' => 'String',
238 ],
239 2 => [
1474f129 240 'name' => 'Subject',
d42b8a81
D
241 'label' => 'Subject',
242 'value' => '',
243 'type' => 'Memo',
244 ],
245 3 => [
1474f129 246 'name' => 'Created By',
d42b8a81
D
247 'label' => 'Created By',
248 // see above - need to update this later
249 'value' => 'placeholder',
250 'type' => 'String',
251 ],
252 4 => [
1474f129 253 'name' => 'Reported By',
d42b8a81
D
254 'label' => 'Reported By',
255 // see above - need to update this later
256 'value' => 'placeholder',
257 'type' => 'String',
258 ],
259 5 => [
1474f129 260 'name' => 'Location',
d42b8a81
D
261 'label' => 'Location',
262 'value' => NULL,
263 'type' => 'String',
264 ],
265 6 => [
1474f129 266 'name' => 'Date and Time',
d42b8a81
D
267 'label' => 'Date and Time',
268 'value' => '2019-11-15 00:00:00',
269 'type' => 'Date',
270 ],
271 7 => [
1474f129 272 'name' => 'Details',
d42b8a81
D
273 'label' => 'Details',
274 'value' => NULL,
275 'type' => 'Memo',
276 ],
277 8 => [
1474f129 278 'name' => 'Status',
d42b8a81
D
279 'label' => 'Status',
280 'value' => 'Scheduled',
281 'type' => 'String',
282 ],
283 9 => [
1474f129 284 'name' => 'Priority',
d42b8a81
D
285 'label' => 'Priority',
286 'value' => 'Normal',
287 'type' => 'String',
288 ],
289 ],
290 'editURL' => 'placeholder',
291 'customGroups' => NULL,
292 ],
293 ],
294 ],
295 ],
296 [
297 // activity set name is blank here, meaning don't filter the activities
298 '',
a9410a63 299 // Some expected assigned vars of CRM_Core_Smarty template.
300 // In particular now we will have Meeting in the output.
d42b8a81
D
301 [
302 'case' => [
303 'clientName' => 'Casey Reportee',
304 'subject' => 'Case Subject',
305 'start_date' => '2019-11-14',
306 'end_date' => NULL,
307 'caseType' => 'Housing Support',
308 'caseTypeName' => 'housing_support',
309 'status' => 'Ongoing',
310 ],
311 'activities' => [
312 0 => [
313 'fields' => [
314 0 => [
1474f129 315 'name' => 'Client',
d42b8a81
D
316 'label' => 'Client',
317 'value' => 'Casey Reportee',
318 'type' => 'String',
319 ],
320 1 => [
1474f129 321 'name' => 'Activity Type',
d42b8a81
D
322 'label' => 'Activity Type',
323 'value' => 'Open Case',
324 'type' => 'String',
325 ],
326 2 => [
1474f129 327 'name' => 'Subject',
d42b8a81
D
328 'label' => 'Subject',
329 'value' => 'Case Subject',
330 'type' => 'Memo',
331 ],
332 3 => [
1474f129 333 'name' => 'Created By',
d42b8a81
D
334 'label' => 'Created By',
335 // data providers run before everything, so update this later
336 'value' => 'placeholder',
337 'type' => 'String',
338 ],
339 4 => [
1474f129 340 'name' => 'Reported By',
d42b8a81
D
341 'label' => 'Reported By',
342 // see above - need to update this later
343 'value' => 'placeholder',
344 'type' => 'String',
345 ],
346 5 => [
1474f129 347 'name' => 'Medium',
d42b8a81
D
348 'label' => 'Medium',
349 'value' => 'Phone',
350 'type' => 'String',
351 ],
352 6 => [
1474f129 353 'name' => 'Location',
d42b8a81
D
354 'label' => 'Location',
355 'value' => NULL,
356 'type' => 'String',
357 ],
358 7 => [
1474f129 359 'name' => 'Date and Time',
d42b8a81
D
360 'label' => 'Date and Time',
361 'value' => '2019-11-14 00:00:00',
362 'type' => 'Date',
363 ],
364 8 => [
1474f129 365 'name' => 'Details',
d42b8a81
D
366 'label' => 'Details',
367 'value' => NULL,
368 'type' => 'Memo',
369 ],
370 9 => [
1474f129 371 'name' => 'Status',
d42b8a81
D
372 'label' => 'Status',
373 'value' => 'Completed',
374 'type' => 'String',
375 ],
376 10 => [
1474f129 377 'name' => 'Priority',
d42b8a81
D
378 'label' => 'Priority',
379 'value' => 'Normal',
380 'type' => 'String',
381 ],
382 ],
383 'editURL' => 'placeholder',
384 'customGroups' => NULL,
385 ],
386 1 => [
387 'fields' => [
388 0 => [
1474f129 389 'name' => 'Client',
d42b8a81
D
390 'label' => 'Client',
391 'value' => 'Casey Reportee',
392 'type' => 'String',
393 ],
394 1 => [
1474f129 395 'name' => 'Activity Type',
d42b8a81
D
396 'label' => 'Activity Type',
397 'value' => 'Medical evaluation',
398 'type' => 'String',
399 ],
400 2 => [
1474f129 401 'name' => 'Subject',
d42b8a81
D
402 'label' => 'Subject',
403 'value' => '',
404 'type' => 'Memo',
405 ],
406 3 => [
1474f129 407 'name' => 'Created By',
d42b8a81
D
408 'label' => 'Created By',
409 // see above - need to update this later
410 'value' => 'placeholder',
411 'type' => 'String',
412 ],
413 4 => [
1474f129 414 'name' => 'Reported By',
d42b8a81
D
415 'label' => 'Reported By',
416 // see above - need to update this later
417 'value' => 'placeholder',
418 'type' => 'String',
419 ],
420 5 => [
1474f129 421 'name' => 'Location',
d42b8a81
D
422 'label' => 'Location',
423 'value' => NULL,
424 'type' => 'String',
425 ],
426 6 => [
1474f129 427 'name' => 'Date and Time',
d42b8a81
D
428 'label' => 'Date and Time',
429 'value' => '2019-11-15 00:00:00',
430 'type' => 'Date',
431 ],
432 7 => [
1474f129 433 'name' => 'Details',
d42b8a81
D
434 'label' => 'Details',
435 'value' => NULL,
436 'type' => 'Memo',
437 ],
438 8 => [
1474f129 439 'name' => 'Status',
d42b8a81
D
440 'label' => 'Status',
441 'value' => 'Scheduled',
442 'type' => 'String',
443 ],
444 9 => [
1474f129 445 'name' => 'Priority',
d42b8a81
D
446 'label' => 'Priority',
447 'value' => 'Normal',
448 'type' => 'String',
449 ],
450 ],
451 'editURL' => 'placeholder',
452 'customGroups' => NULL,
453 ],
454 2 => [
455 'fields' => [
456 0 => [
1474f129 457 'name' => 'Client',
d42b8a81
D
458 'label' => 'Client',
459 'value' => 'Casey Reportee',
460 'type' => 'String',
461 ],
462 1 => [
1474f129 463 'name' => 'Activity Type',
d42b8a81
D
464 'label' => 'Activity Type',
465 'value' => 'Meeting',
466 'type' => 'String',
467 ],
468 2 => [
1474f129 469 'name' => 'Subject',
d42b8a81
D
470 'label' => 'Subject',
471 'value' => 'Test Meeting',
472 'type' => 'Memo',
473 ],
474 3 => [
1474f129 475 'name' => 'Created By',
d42b8a81
D
476 'label' => 'Created By',
477 // see above - need to update this later
478 'value' => 'placeholder',
479 'type' => 'String',
480 ],
481 4 => [
1474f129 482 'name' => 'Reported By',
d42b8a81
D
483 'label' => 'Reported By',
484 // see above - need to update this later
485 'value' => 'placeholder',
486 'type' => 'String',
487 ],
488 5 => [
1474f129 489 'name' => 'Location',
d42b8a81
D
490 'label' => 'Location',
491 'value' => NULL,
492 'type' => 'String',
493 ],
494 6 => [
1474f129 495 'name' => 'Date and Time',
d42b8a81
D
496 'label' => 'Date and Time',
497 'value' => '2019-11-14 12:34:56',
498 'type' => 'Date',
499 ],
500 7 => [
1474f129 501 'name' => 'Details',
d42b8a81
D
502 'label' => 'Details',
503 'value' => NULL,
504 'type' => 'Memo',
505 ],
506 8 => [
1474f129 507 'name' => 'Status',
d42b8a81
D
508 'label' => 'Status',
509 'value' => 'Completed',
510 'type' => 'String',
511 ],
512 9 => [
1474f129 513 'name' => 'Priority',
d42b8a81
D
514 'label' => 'Priority',
515 'value' => 'Normal',
516 'type' => 'String',
517 ],
518 ],
519 'editURL' => 'placeholder',
520 'customGroups' => NULL,
521 ],
522 ],
523 ],
524 ],
525 ];
526 }
527
528 /**
529 * Since data providers get evaluated before setup and other variable
530 * assignments, we call this during the test to update placeholders we set
531 * in the data provider.
532 * Maybe it doesn't really make sense to use a data provider here, but kinda.
533 *
534 * @param &$expected array Contains the placeholders to update.
535 * @param $client_id int
536 * @param $case_id int
537 */
538 private function updateExpectedBecauseDataProviderEvaluatesBeforeEverything(&$expected, $client_id, $case_id) {
539 $display_name = $this->callAPISuccess('Contact', 'getsingle', [
540 'return' => ["display_name"],
541 'id' => $this->_loggedInUser,
542 ]);
543
544 foreach ($expected['activities'] as $idx => $activity) {
545 $expected['activities'][$idx]['fields'][3]['value'] = $display_name['display_name'];
546 $expected['activities'][$idx]['fields'][4]['value'] = $display_name['display_name'];
547
548 $activityTypeId = $this->callAPISuccess('OptionValue', 'getsingle', [
549 'return' => ["value"],
550 'option_group_id' => 'activity_type',
551 'name' => $expected['activities'][$idx]['fields'][1]['value'],
552 ]);
553 $expected['activities'][$idx]['editURL'] = CRM_Utils_System::url('civicrm/case/activity', "reset=1&cid={$client_id}&caseid={$case_id}&action=update&atype={$activityTypeId['value']}&id=" . ($idx + 1));
554 }
555 }
556
557 /**
558 * Create and return a new case object.
559 * @param $clientId
560 * @param $loggedInUser
561 * @return CRM_Case_BAO_Case
562 */
563 private function createCase($clientId, $loggedInUser) {
564 $caseParams = [
565 'activity_subject' => 'Case Subject',
566 'client_id' => $clientId,
567 'case_type_id' => $this->caseTypeId,
568 'status_id' => 1,
569 'case_type' => $this->caseType,
570 'subject' => 'Case Subject',
571 'start_date' => '2019-11-14',
572 'start_date_time' => '20191114000000',
573 'medium_id' => 2,
574 'activity_details' => '',
575 ];
576 $form = new CRM_Case_Form_Case();
577 $caseObj = $form->testSubmit($caseParams, "OpenCase", $loggedInUser, "standalone");
578 return $caseObj;
579 }
580
581 /**
582 * We don't need so many activities as in the stock case type. Just makes
583 * dataprovider unnecessarily long. Just take the first two.
584 * @return void
585 */
586 private function simplifyCaseTypeDefinition() {
587 $caseType = $this->callAPISuccess('CaseType', 'getsingle', ['id' => $this->caseTypeId]);
588 $newActivitySet = array_slice($caseType['definition']['activitySets'][0]['activityTypes'], 0, 2);
589 $caseType['definition']['activitySets'][0]['activityTypes'] = $newActivitySet;
590 $this->callAPISuccess('CaseType', 'create', $caseType);
591 }
592
a9410a63 593 /**
594 * Add Meeting to the standard timeline.
595 */
596 private function addMeetingToTimeline() {
597 $caseType = $this->callAPISuccess('CaseType', 'getsingle', ['id' => $this->caseTypeId]);
598 $activityTypes = $caseType['definition']['activitySets'][0]['activityTypes'];
599 // Make a copy of the second activity type and change the type.
600 $activityType = $activityTypes[1];
601 $activityType['name'] = 'Meeting';
602 $activityType['label'] = 'Meeting';
603
604 $activityTypes[] = $activityType;
605 $caseType['definition']['activitySets'][0]['activityTypes'] = $activityTypes;
606 $this->callAPISuccess('CaseType', 'create', $caseType);
607 }
608
d42b8a81 609}