Merge pull request #17953 from civicrm/5.28
[civicrm-core.git] / tests / phpunit / CRM / Case / XMLProcessor / ProcessTest.php
1 <?php
2 require_once 'CiviTest/CiviCaseTestCase.php';
3
4 /**
5 * Class CRM_Case_PseudoConstantTest
6 * @group headless
7 */
8 class CRM_Case_XMLProcessor_ProcessTest extends CiviCaseTestCase {
9
10 public function setUp() {
11 parent::setUp();
12
13 $this->defaultAssigneeOptionsValues = [];
14
15 $this->setupContacts();
16 $this->setupDefaultAssigneeOptions();
17 $this->setupRelationships();
18 $this->setupMoreRelationshipTypes();
19 $this->setupActivityDefinitions();
20
21 $this->process = new CRM_Case_XMLProcessor_Process();
22 }
23
24 public function tearDown() {
25 $this->deleteMoreRelationshipTypes();
26
27 parent::tearDown();
28 }
29
30 /**
31 * Creates sample contacts.
32 */
33 protected function setUpContacts() {
34 $this->contacts = [
35 'ana' => $this->individualCreate(),
36 'beto' => $this->individualCreate(),
37 'carlos' => $this->individualCreate(),
38 ];
39 }
40
41 /**
42 * Adds the default assignee group and options to the test database.
43 * It also stores the IDs of the options in an index.
44 */
45 protected function setupDefaultAssigneeOptions() {
46 $options = [
47 'NONE', 'BY_RELATIONSHIP', 'SPECIFIC_CONTACT', 'USER_CREATING_THE_CASE',
48 ];
49
50 CRM_Core_BAO_OptionGroup::ensureOptionGroupExists([
51 'name' => 'activity_default_assignee',
52 ]);
53
54 foreach ($options as $option) {
55 $optionValue = CRM_Core_BAO_OptionValue::ensureOptionValueExists([
56 'option_group_id' => 'activity_default_assignee',
57 'name' => $option,
58 'label' => $option,
59 ]);
60
61 $this->defaultAssigneeOptionsValues[$option] = $optionValue['value'];
62 }
63 }
64
65 /**
66 * Adds a relationship between the activity's target contact and default assignee.
67 */
68 protected function setupRelationships() {
69 $this->relationships = [
70 'ana_is_pupil_of_beto' => [
71 'type_id' => NULL,
72 'name_a_b' => 'Pupil of',
73 'name_b_a' => 'Instructor',
74 'contact_id_a' => $this->contacts['ana'],
75 'contact_id_b' => $this->contacts['beto'],
76 ],
77 'ana_is_spouse_of_carlos' => [
78 'type_id' => NULL,
79 'name_a_b' => 'Spouse of',
80 'name_b_a' => 'Spouse of',
81 'contact_id_a' => $this->contacts['ana'],
82 'contact_id_b' => $this->contacts['carlos'],
83 ],
84 'unassigned_employee' => [
85 'type_id' => NULL,
86 'name_a_b' => 'Employee of',
87 'name_b_a' => 'Employer',
88 ],
89 ];
90
91 foreach ($this->relationships as $name => &$relationship) {
92 $relationship['type_id'] = $this->relationshipTypeCreate([
93 'contact_type_a' => 'Individual',
94 'contact_type_b' => 'Individual',
95 'name_a_b' => $relationship['name_a_b'],
96 'label_a_b' => $relationship['name_a_b'],
97 'name_b_a' => $relationship['name_b_a'],
98 'label_b_a' => $relationship['name_b_a'],
99 ]);
100
101 if (isset($relationship['contact_id_a'])) {
102 $this->callAPISuccess('Relationship', 'create', [
103 'contact_id_a' => $relationship['contact_id_a'],
104 'contact_id_b' => $relationship['contact_id_b'],
105 'relationship_type_id' => $relationship['type_id'],
106 ]);
107 }
108 }
109 }
110
111 /**
112 * Set up some additional relationship types for some specific tests.
113 */
114 protected function setupMoreRelationshipTypes() {
115 $this->moreRelationshipTypes = [
116 'unidirectional_name_label_different' => [
117 'type_id' => NULL,
118 'name_a_b' => 'jm7ab',
119 'label_a_b' => 'Jedi Master is',
120 'name_b_a' => 'jm7ba',
121 'label_b_a' => 'Jedi Master for',
122 'description' => 'Jedi Master',
123 ],
124 'unidirectional_name_label_same' => [
125 'type_id' => NULL,
126 'name_a_b' => 'Quilt Maker is',
127 'label_a_b' => 'Quilt Maker is',
128 'name_b_a' => 'Quilt Maker for',
129 'label_b_a' => 'Quilt Maker for',
130 'description' => 'Quilt Maker',
131 ],
132 'bidirectional_name_label_different' => [
133 'type_id' => NULL,
134 'name_a_b' => 'f12',
135 'label_a_b' => 'Friend of',
136 'name_b_a' => 'f12',
137 'label_b_a' => 'Friend of',
138 'description' => 'Friend',
139 ],
140 'bidirectional_name_label_same' => [
141 'type_id' => NULL,
142 'name_a_b' => 'Enemy of',
143 'label_a_b' => 'Enemy of',
144 'name_b_a' => 'Enemy of',
145 'label_b_a' => 'Enemy of',
146 'description' => 'Enemy',
147 ],
148 ];
149
150 foreach ($this->moreRelationshipTypes as &$relationship) {
151 $relationship['type_id'] = $this->relationshipTypeCreate([
152 'contact_type_a' => 'Individual',
153 'contact_type_b' => 'Individual',
154 'name_a_b' => $relationship['name_a_b'],
155 'label_a_b' => $relationship['label_a_b'],
156 'name_b_a' => $relationship['name_b_a'],
157 'label_b_a' => $relationship['label_b_a'],
158 'description' => $relationship['description'],
159 ]);
160 }
161 }
162
163 /**
164 * Clean up additional relationship types (tearDown).
165 */
166 protected function deleteMoreRelationshipTypes() {
167 foreach ($this->moreRelationshipTypes as $relationship) {
168 $this->callAPISuccess('relationship_type', 'delete', ['id' => $relationship['type_id']]);
169 }
170 }
171
172 /**
173 * Defines the the activity parameters and XML definitions. These can be used
174 * to create the activity.
175 */
176 protected function setupActivityDefinitions() {
177 $activityTypeXml = '<activity-type><name>Open Case</name></activity-type>';
178 $this->activityTypeXml = new SimpleXMLElement($activityTypeXml);
179 $this->activityParams = [
180 'activity_date_time' => date('Ymd'),
181 // @todo This seems wrong, it just happens to work out because both caseId and caseTypeId equal 1 in the stock setup here.
182 'caseID' => $this->caseTypeId,
183 'clientID' => $this->contacts['ana'],
184 'creatorID' => $this->_loggedInUser,
185 ];
186 }
187
188 /**
189 * Tests the creation of activities where the default assignee should be the
190 * target contact's instructor. Beto is the instructor for Ana.
191 */
192 public function testCreateActivityWithDefaultContactByRelationship() {
193 $relationship = $this->relationships['ana_is_pupil_of_beto'];
194 $this->activityTypeXml->default_assignee_type = $this->defaultAssigneeOptionsValues['BY_RELATIONSHIP'];
195 $this->activityTypeXml->default_assignee_relationship = "{$relationship['type_id']}_b_a";
196
197 $this->process->createActivity($this->activityTypeXml, $this->activityParams);
198 $this->assertActivityAssignedToContactExists($this->contacts['beto']);
199 }
200
201 /**
202 * Test the creation of activities where the default assignee should not
203 * end up being a contact from another case where it has the same client
204 * and relationship.
205 */
206 public function testCreateActivityWithDefaultContactByRelationshipTwoCases() {
207 /*
208 At this point the stock setup looks like this:
209 Case 1: no roles assigned
210 Non-case relationship with ana as pupil of beto
211 Non-case relationship with ana as spouse of carlos
212
213 So we want to:
214 Make another case for the same client ana.
215 Add a pupil role on that new case with some other person.
216 Make an activity on the first case.
217
218 Since there is a non-case relationship of that type for the
219 right person we do want it to take that one even though there is no role
220 on the first case, i.e. it SHOULD fall back to non-case relationships.
221 So this is test 1.
222
223 Then we want to get rid of the non-case relationship and try again. In
224 this situation it should not make any assignment, i.e. it should not
225 take the other person from the other case. The original bug was that it
226 would assign the activity to that other person from the other case. This
227 is test 2.
228 */
229
230 $relationship = $this->relationships['ana_is_pupil_of_beto'];
231
232 // Make another case and add a case role with the same relationship we
233 // want, but a different person.
234 $caseObj = $this->createCase($this->contacts['ana'], $this->_loggedInUser);
235 $this->callAPISuccess('Relationship', 'create', [
236 'contact_id_a' => $this->contacts['ana'],
237 'contact_id_b' => $this->contacts['carlos'],
238 'relationship_type_id' => $relationship['type_id'],
239 'case_id' => $caseObj->id,
240 ]);
241
242 $this->activityTypeXml->default_assignee_type = $this->defaultAssigneeOptionsValues['BY_RELATIONSHIP'];
243 $this->activityTypeXml->default_assignee_relationship = "{$relationship['type_id']}_b_a";
244
245 $this->process->createActivity($this->activityTypeXml, $this->activityParams);
246
247 // We can't use assertActivityAssignedToContactExists because it assumes
248 // there's only one activity in the database, but we have several from the
249 // second case. We want the one we just created on the first case.
250 $result = $this->callAPISuccess('Activity', 'get', [
251 'case_id' => $this->activityParams['caseID'],
252 'return' => ['assignee_contact_id'],
253 ])['values'];
254 $this->assertCount(1, $result);
255 foreach ($result as $activity) {
256 // Note the first parameter is turned into an array to match the second.
257 $this->assertEquals([$this->contacts['beto']], $activity['assignee_contact_id']);
258 }
259
260 // Now remove the non-case relationship.
261 $result = $this->callAPISuccess('Relationship', 'get', [
262 'case_id' => ['IS NULL' => 1],
263 'relationship_type_id' => $relationship['type_id'],
264 'contact_id_a' => $this->contacts['ana'],
265 'contact_id_b' => $this->contacts['beto'],
266 ])['values'];
267 $this->assertCount(1, $result);
268 foreach ($result as $activity) {
269 $result = $this->callAPISuccess('Relationship', 'delete', ['id' => $activity['id']]);
270 }
271
272 // Create another activity on the first case. Make it a different activity
273 // type so we can find it better.
274 $activityXml = '<activity-type><name>Follow up</name></activity-type>';
275 $activityXmlElement = new SimpleXMLElement($activityXml);
276 $activityXmlElement->default_assignee_type = $this->defaultAssigneeOptionsValues['BY_RELATIONSHIP'];
277 $activityXmlElement->default_assignee_relationship = "{$relationship['type_id']}_b_a";
278 $this->process->createActivity($activityXmlElement, $this->activityParams);
279
280 $result = $this->callAPISuccess('Activity', 'get', [
281 'case_id' => $this->activityParams['caseID'],
282 'activity_type_id' => 'Follow up',
283 'return' => ['assignee_contact_id'],
284 ])['values'];
285 $this->assertCount(1, $result);
286 foreach ($result as $activity) {
287 // It should be empty, not the contact from the second case.
288 $this->assertEmpty($activity['assignee_contact_id']);
289 }
290 }
291
292 /**
293 * Create and return case object of given Client ID.
294 * @todo This is copy/paste from Case/BAO/CaseTest - should put into base class?
295 * @param $clientId
296 * @param $loggedInUser
297 * @return CRM_Case_BAO_Case
298 */
299 private function createCase($clientId, $loggedInUser = NULL) {
300 if (empty($loggedInUser)) {
301 // backwards compatibility - but it's more typical that the creator is a different person than the client
302 $loggedInUser = $clientId;
303 }
304 $caseParams = [
305 'activity_subject' => 'Case Subject',
306 'client_id' => $clientId,
307 'case_type_id' => 1,
308 'status_id' => 1,
309 'case_type' => 'housing_support',
310 'subject' => 'Case Subject',
311 'start_date' => date("Y-m-d"),
312 'start_date_time' => date("YmdHis"),
313 'medium_id' => 2,
314 'activity_details' => '',
315 ];
316 $form = new CRM_Case_Form_Case();
317 $caseObj = $form->testSubmit($caseParams, "OpenCase", $loggedInUser, "standalone");
318 return $caseObj;
319 }
320
321 /**
322 * Tests when the default assignee relationship exists, but in the other direction only.
323 * Ana is a pupil, but has no pupils related to her.
324 */
325 public function testCreateActivityWithDefaultContactByRelationshipMissing() {
326 $relationship = $this->relationships['ana_is_pupil_of_beto'];
327 $this->activityTypeXml->default_assignee_type = $this->defaultAssigneeOptionsValues['BY_RELATIONSHIP'];
328 $this->activityTypeXml->default_assignee_relationship = "{$relationship['type_id']}_a_b";
329
330 $this->process->createActivity($this->activityTypeXml, $this->activityParams);
331 $this->assertActivityAssignedToContactExists(NULL);
332 }
333
334 /**
335 * Tests when the the default assignee relationship exists and is a bidirectional
336 * relationship. Ana and Carlos are spouses.
337 */
338 public function testCreateActivityWithDefaultContactByRelationshipBidirectional() {
339 $relationship = $this->relationships['ana_is_spouse_of_carlos'];
340 $this->activityParams['clientID'] = $this->contacts['carlos'];
341 $this->activityTypeXml->default_assignee_type = $this->defaultAssigneeOptionsValues['BY_RELATIONSHIP'];
342 $this->activityTypeXml->default_assignee_relationship = "{$relationship['type_id']}_a_b";
343
344 $this->process->createActivity($this->activityTypeXml, $this->activityParams);
345 $this->assertActivityAssignedToContactExists($this->contacts['ana']);
346 }
347
348 /**
349 * Tests when the default assignee relationship does not exist. Ana is not an
350 * employee for anyone.
351 */
352 public function testCreateActivityWithDefaultContactByRelationButTheresNoRelationship() {
353 $relationship = $this->relationships['unassigned_employee'];
354 $this->activityTypeXml->default_assignee_type = $this->defaultAssigneeOptionsValues['BY_RELATIONSHIP'];
355 $this->activityTypeXml->default_assignee_relationship = "{$relationship['type_id']}_b_a";
356
357 $this->process->createActivity($this->activityTypeXml, $this->activityParams);
358 $this->assertActivityAssignedToContactExists(NULL);
359 }
360
361 /**
362 * Tests the creation of activities with default assignee set to a specific contact.
363 */
364 public function testCreateActivityAssignedToSpecificContact() {
365 $this->activityTypeXml->default_assignee_type = $this->defaultAssigneeOptionsValues['SPECIFIC_CONTACT'];
366 $this->activityTypeXml->default_assignee_contact = $this->contacts['carlos'];
367
368 $this->process->createActivity($this->activityTypeXml, $this->activityParams);
369 $this->assertActivityAssignedToContactExists($this->contacts['carlos']);
370 }
371
372 /**
373 * Tests the creation of activities with default assignee set to a specific contact,
374 * but the contact does not exist.
375 */
376 public function testCreateActivityAssignedToNonExistantSpecificContact() {
377 $this->activityTypeXml->default_assignee_type = $this->defaultAssigneeOptionsValues['SPECIFIC_CONTACT'];
378 $this->activityTypeXml->default_assignee_contact = 987456321;
379
380 $this->process->createActivity($this->activityTypeXml, $this->activityParams);
381 $this->assertActivityAssignedToContactExists(NULL);
382 }
383
384 /**
385 * Tests the creation of activities with the default assignee being the one
386 * creating the case's activity.
387 */
388 public function testCreateActivityAssignedToUserCreatingTheCase() {
389 $this->activityTypeXml->default_assignee_type = $this->defaultAssigneeOptionsValues['USER_CREATING_THE_CASE'];
390
391 $this->process->createActivity($this->activityTypeXml, $this->activityParams);
392 $this->assertActivityAssignedToContactExists($this->_loggedInUser);
393 }
394
395 /**
396 * Tests the creation of activities when the default assignee is set to NONE.
397 */
398 public function testCreateActivityAssignedNoUser() {
399 $this->activityTypeXml->default_assignee_type = $this->defaultAssigneeOptionsValues['NONE'];
400
401 $this->process->createActivity($this->activityTypeXml, $this->activityParams);
402 $this->assertActivityAssignedToContactExists(NULL);
403 }
404
405 /**
406 * Tests the creation of activities when the default assignee is set to NONE.
407 */
408 public function testCreateActivityWithNoDefaultAssigneeOption() {
409 $this->process->createActivity($this->activityTypeXml, $this->activityParams);
410 $this->assertActivityAssignedToContactExists(NULL);
411 }
412
413 /**
414 * Asserts that an activity was created where the assignee was the one related
415 * to the target contact.
416 *
417 * @param int|null $assigneeContactId the ID of the expected assigned contact or NULL if expected to be empty.
418 */
419 protected function assertActivityAssignedToContactExists($assigneeContactId) {
420 $expectedContact = $assigneeContactId === NULL ? [] : [$assigneeContactId];
421 $result = $this->callAPISuccess('Activity', 'get', [
422 'target_contact_id' => $this->activityParams['clientID'],
423 'return' => ['assignee_contact_id'],
424 ]);
425 $activity = CRM_Utils_Array::first($result['values']);
426
427 $this->assertNotNull($activity, 'Target contact has no activities assigned to them');
428 $this->assertEquals($expectedContact, $activity['assignee_contact_id'], 'Activity is not assigned to expected contact');
429 }
430
431 /**
432 * Test that caseRoles() doesn't have name and label mixed up.
433 *
434 * @param $key string The array key in the moreRelationshipTypes array that
435 * is the relationship type we're currently testing. So not necessarily
436 * unique for each entry in the dataprovider since want to test a given
437 * relationship type against multiple xml strings. It's not a test
438 * identifier, it's an array key to use to look up something.
439 * @param $xmlString string
440 * @param $expected array
441 * @param $dontcare array We're re-using the data provider for two tests and
442 * we don't care about those expected values.
443 *
444 * @dataProvider xmlCaseRoleDataProvider
445 */
446 public function testCaseRoles($key, $xmlString, $expected, $dontcare) {
447 $xmlObj = new SimpleXMLElement($xmlString);
448
449 // element 0 is direction (a_b), 1 is the text we want
450 $expectedArray = empty($expected) ? [] : ["{$this->moreRelationshipTypes[$key]['type_id']}_{$expected[0]}" => $expected[1]];
451
452 $this->assertEquals($expectedArray, $this->process->caseRoles($xmlObj->CaseRoles, FALSE));
453 }
454
455 /**
456 * Test that locateNameOrLabel doesn't have name and label mixed up.
457 *
458 * @param $key string The array key in the moreRelationshipTypes array that
459 * is the relationship type we're currently testing. So not necessarily
460 * unique for each entry in the dataprovider since want to test a given
461 * relationship type against multiple xml strings. It's not a test
462 * identifier, it's an array key to use to look up something.
463 * @param $xmlString string
464 * @param $dontcare array We're re-using the data provider for two tests and
465 * we don't care about those expected values.
466 * @param $expected array
467 *
468 * @dataProvider xmlCaseRoleDataProvider
469 */
470 public function testLocateNameOrLabel($key, $xmlString, $dontcare, $expected) {
471 $xmlObj = new SimpleXMLElement($xmlString);
472
473 // element 0 is direction (a_b), 1 is the text we want.
474 // In case of failure, the function is expected to return FALSE for the
475 // direction and then for the text it just gives us back the string we
476 // gave it.
477 $expectedArray = empty($expected[0])
478 ? [FALSE, $expected[1]]
479 : ["{$this->moreRelationshipTypes[$key]['type_id']}_{$expected[0]}", $expected[1]];
480
481 $this->assertEquals($expectedArray, $this->process->locateNameOrLabel($xmlObj->CaseRoles->RelationshipType));
482 }
483
484 /**
485 * Data provider for testCaseRoles and testLocateNameOrLabel
486 * @return array
487 */
488 public function xmlCaseRoleDataProvider() {
489 return [
490 // Simulate one that has been converted to the format it should be going
491 // forward, where name is the actual name, i.e. same as machineName.
492 [
493 // this is the array key in the $this->moreRelationshipTypes array
494 'unidirectional_name_label_different',
495 // some xml
496 '<CaseType><CaseRoles><RelationshipType><name>jm7ba</name><creator>1</creator><manager>1</manager></RelationshipType></CaseRoles></CaseType>',
497 // this is the expected for testCaseRoles
498 ['a_b', 'Jedi Master is'],
499 // this is the expected for testLocateNameOrLabel
500 ['a_b', 'jm7ba'],
501 ],
502 // Simulate one that is still in label format, i.e. one that is still in
503 // xml files that haven't been updated, or in the db but upgrade script
504 // not run yet.
505 [
506 'unidirectional_name_label_different',
507 '<CaseType><CaseRoles><RelationshipType><name>Jedi Master for</name><creator>1</creator><manager>1</manager></RelationshipType></CaseRoles></CaseType>',
508 ['a_b', 'Jedi Master is'],
509 ['a_b', 'jm7ba'],
510 ],
511 // Ditto but where we know name and label are the same in the db.
512 [
513 'unidirectional_name_label_same',
514 '<CaseType><CaseRoles><RelationshipType><name>Quilt Maker for</name><creator>1</creator><manager>1</manager></RelationshipType></CaseRoles></CaseType>',
515 ['a_b', 'Quilt Maker is'],
516 ['a_b', 'Quilt Maker for'],
517 ],
518 // Simulate one that is messed up and should fail, e.g. like a typo
519 // in an xml file. Here we've made a typo on purpose.
520 [
521 'unidirectional_name_label_different',
522 '<CaseType><CaseRoles><RelationshipType><name>Jedi Masterrrr for</name><creator>1</creator><manager>1</manager></RelationshipType></CaseRoles></CaseType>',
523 NULL,
524 [FALSE, 'Jedi Masterrrr for'],
525 ],
526 // Now some similar tests to above but for bidirectional relationships.
527 // Bidirectional relationship, name and label different, using machine name.
528 [
529 'bidirectional_name_label_different',
530 '<CaseType><CaseRoles><RelationshipType><name>f12</name><creator>1</creator><manager>1</manager></RelationshipType></CaseRoles></CaseType>',
531 ['b_a', 'Friend of'],
532 ['b_a', 'f12'],
533 ],
534 // Bidirectional relationship, name and label different, using display label.
535 [
536 'bidirectional_name_label_different',
537 '<CaseType><CaseRoles><RelationshipType><name>Friend of</name><creator>1</creator><manager>1</manager></RelationshipType></CaseRoles></CaseType>',
538 ['b_a', 'Friend of'],
539 ['b_a', 'f12'],
540 ],
541 // Bidirectional relationship, name and label same.
542 [
543 'bidirectional_name_label_same',
544 '<CaseType><CaseRoles><RelationshipType><name>Enemy of</name><creator>1</creator><manager>1</manager></RelationshipType></CaseRoles></CaseType>',
545 ['b_a', 'Enemy of'],
546 ['b_a', 'Enemy of'],
547 ],
548 ];
549 }
550
551 /**
552 * Test XMLProcessor activityTypes()
553 */
554 public function testXmlProcessorActivityTypes() {
555 // First change an activity's label since we also test getting the labels.
556 // @todo Having a brain freeze or something - can't do this in one step?
557 $activity_type_id = $this->callApiSuccess('OptionValue', 'get', [
558 'option_group_id' => 'activity_type',
559 'name' => 'Medical evaluation',
560 ])['id'];
561 $this->callApiSuccess('OptionValue', 'create', [
562 'id' => $activity_type_id,
563 'label' => 'Medical evaluation changed',
564 ]);
565
566 $p = new CRM_Case_XMLProcessor_Process();
567 $xml = $p->retrieve('housing_support');
568
569 // Test getting the `name`s
570 $activityTypes = $p->activityTypes($xml->ActivityTypes, FALSE, FALSE, FALSE);
571 $this->assertEquals(
572 [
573 13 => 'Open Case',
574 55 => 'Medical evaluation',
575 56 => 'Mental health evaluation',
576 57 => 'Secure temporary housing',
577 60 => 'Income and benefits stabilization',
578 58 => 'Long-term housing plan',
579 14 => 'Follow up',
580 15 => 'Change Case Type',
581 16 => 'Change Case Status',
582 18 => 'Change Case Start Date',
583 25 => 'Link Cases',
584 ],
585 $activityTypes
586 );
587
588 // While we're here and have the `name`s check the editable types in
589 // Settings.xml which is something that gets called reasonably often
590 // thru CRM_Case_XMLProcessor_Process::activityTypes().
591 $activityTypeValues = array_flip($activityTypes);
592 $xml = $p->retrieve('Settings');
593 $settings = $p->activityTypes($xml->ActivityTypes, FALSE, FALSE, 'edit');
594 $this->assertEquals(
595 [
596 'edit' => [
597 0 => $activityTypeValues['Change Case Status'],
598 1 => $activityTypeValues['Change Case Start Date'],
599 ],
600 ],
601 $settings
602 );
603
604 // Now get `label`s
605 $xml = $p->retrieve('housing_support');
606 $activityTypes = $p->activityTypes($xml->ActivityTypes, FALSE, TRUE, FALSE);
607 $this->assertEquals(
608 [
609 13 => 'Open Case',
610 55 => 'Medical evaluation changed',
611 56 => 'Mental health evaluation',
612 57 => 'Secure temporary housing',
613 60 => 'Income and benefits stabilization',
614 58 => 'Long-term housing plan',
615 14 => 'Follow up',
616 15 => 'Change Case Type',
617 16 => 'Change Case Status',
618 18 => 'Change Case Start Date',
619 25 => 'Link Cases',
620 ],
621 $activityTypes
622 );
623 }
624
625 }