Merge pull request #16469 from civicrm/5.22
[civicrm-core.git] / tests / phpunit / api / v3 / CaseTypeTest.php
1 <?php
2 /*
3 +--------------------------------------------------------------------+
4 | Copyright CiviCRM LLC. All rights reserved. |
5 | |
6 | This work is published under the GNU AGPLv3 license with some |
7 | permitted exceptions and without any warranty. For full license |
8 | and copyright information, see https://civicrm.org/licensing |
9 +--------------------------------------------------------------------+
10 */
11
12 /**
13 * Class api_v3_CaseTypeTest
14 * @group headless
15 */
16 class api_v3_CaseTypeTest extends CiviCaseTestCase {
17
18 public function setUp() {
19 $this->quickCleanup(['civicrm_case_type']);
20 parent::setUp();
21
22 $this->fixtures['Application_with_Definition'] = [
23 'title' => 'Application with Definition',
24 'name' => 'Application_with_Definition',
25 'is_active' => 1,
26 'weight' => 4,
27 'definition' => [
28 'activityTypes' => [
29 ['name' => 'First act'],
30 ],
31 'activitySets' => [
32 [
33 'name' => 'set1',
34 'label' => 'Label 1',
35 'timeline' => 1,
36 'activityTypes' => [
37 ['name' => 'Open Case', 'status' => 'Completed'],
38 ],
39 ],
40 ],
41 'timelineActivityTypes' => [
42 ['name' => 'Open Case', 'status' => 'Completed'],
43 ],
44 'caseRoles' => [
45 ['name' => 'First role', 'creator' => 1, 'manager' => 1],
46 ],
47 ],
48 ];
49 }
50
51 /**
52 * Tears down the fixture, for example, closes a network connection.
53 *
54 * This method is called after a test is executed.
55 */
56 public function tearDown() {
57 parent::tearDown();
58 $this->quickCleanup(['civicrm_case_type', 'civicrm_uf_match']);
59 }
60
61 /**
62 * Check with empty array.
63 */
64 public function testCaseTypeCreateEmpty() {
65 $this->callAPIFailure('CaseType', 'create', []);
66 }
67
68 /**
69 * Check if required fields are not passed.
70 */
71 public function testCaseTypeCreateWithoutRequired() {
72 $params = [
73 'name' => 'this case should fail',
74 ];
75 $this->callAPIFailure('CaseType', 'create', $params);
76
77 $params = [
78 'name' => 'this case should fail',
79 'weight' => 4,
80 ];
81 $this->callAPIFailure('CaseType', 'create', $params);
82 }
83
84 /**
85 * Test create methods with valid data.
86 *
87 * Success expected.
88 */
89 public function testCaseTypeCreate() {
90 // Create Case Type.
91 $params = [
92 'title' => 'Application',
93 'name' => 'Application',
94 'is_active' => 1,
95 'weight' => 4,
96 ];
97
98 $result = $this->callAPISuccess('CaseType', 'create', $params);
99 $id = $result['id'];
100
101 // Check result.
102 $result = $this->callAPISuccess('CaseType', 'get', ['id' => $id]);
103 $this->assertEquals($result['values'][$id]['id'], $id);
104 $this->assertEquals($result['values'][$id]['title'], $params['title']);
105 }
106
107 /**
108 * Create a case with an invalid name.
109 */
110 public function testCaseTypeCreate_invalidName() {
111 // Create Case Type
112 $params = [
113 'title' => 'Application',
114 // spaces are not allowed
115 'name' => 'Appl ication',
116 'is_active' => 1,
117 'weight' => 4,
118 ];
119
120 $this->callAPIFailure('CaseType', 'create', $params);
121 }
122
123 /**
124 * Test update (create with id) function with valid parameters.
125 */
126 public function testCaseTypeUpdate() {
127 // Create Case Type
128 $params = [
129 'title' => 'Application',
130 'name' => 'Application',
131 'is_active' => 1,
132 'weight' => 4,
133 ];
134 $result = $this->callAPISuccess('CaseType', 'create', $params);
135 $id = $result['id'];
136 $result = $this->callAPISuccess('CaseType', 'get', ['id' => $id]);
137 $caseType = $result['values'][$id];
138
139 // Update Case Type.
140 $params = ['id' => $id];
141 $params['title'] = $caseType['title'] = 'Something Else';
142 $this->callAPISuccess('CaseType', 'create', $params);
143
144 // Verify that updated case Type is exactly equal to the original with new title.
145 $result = $this->callAPISuccess('CaseType', 'get', ['id' => $id]);
146 $this->assertEquals($result['values'][$id], $caseType);
147 }
148
149 /**
150 * Test delete function with valid parameters.
151 */
152 public function testCaseTypeDelete_New() {
153 // Create Case Type.
154 $params = [
155 'title' => 'Application',
156 'name' => 'Application',
157 'is_active' => 1,
158 'weight' => 4,
159 ];
160 $result = $this->callAPISuccess('CaseType', 'create', $params);
161
162 $id = $result['id'];
163 $this->callAPISuccess('CaseType', 'delete', ['id' => $id]);
164
165 // Check result - case type should no longer exist
166 $result = $this->callAPISuccess('CaseType', 'get', ['id' => $id]);
167 $this->assertEquals(0, $result['count']);
168 }
169
170 /**
171 * Test create methods with xml file.
172 *
173 * Success expected.
174 */
175 public function testCaseTypeCreateWithDefinition() {
176 // Create Case Type
177 $params = $this->fixtures['Application_with_Definition'];
178 $result = $this->callAPISuccess('CaseType', 'create', $params);
179 $id = $result['id'];
180
181 // Check result
182 $result = $this->callAPISuccess('CaseType', 'get', ['id' => $id]);
183 $this->assertEquals($result['values'][$id]['id'], $id);
184 $this->assertEquals($result['values'][$id]['title'], $params['title']);
185 $this->assertEquals($result['values'][$id]['definition'], $params['definition']);
186
187 $caseXml = CRM_Case_XMLRepository::singleton()->retrieve('Application_with_Definition');
188 $this->assertTrue($caseXml instanceof SimpleXMLElement);
189 }
190
191 /**
192 * Create a CaseType+case then delete the CaseType.
193 */
194 public function testCaseTypeDelete_InUse() {
195 // Create Case Type
196 $params = $this->fixtures['Application_with_Definition'];
197 $createCaseType = $this->callAPISuccess('CaseType', 'create', $params);
198
199 $createCase = $this->callAPISuccess('Case', 'create', [
200 'case_type_id' => $createCaseType['id'],
201 'contact_id' => $this->_loggedInUser,
202 'subject' => 'Example',
203 ]);
204
205 // Deletion fails while case-type is in-use
206 $deleteCaseType = $this->callAPIFailure('CaseType', 'delete', ['id' => $createCaseType['id']]);
207 $this->assertEquals("You can not delete this case type -- it is assigned to 1 existing case record(s). If you do not want this case type to be used going forward, consider disabling it instead.", $deleteCaseType['error_message']);
208 $getCaseType = $this->callAPISuccess('CaseType', 'get', ['id' => $createCaseType['id']]);
209 $this->assertEquals(1, $getCaseType['count']);
210
211 // Deletion succeeds when it's not in-use.
212 $this->callAPISuccess('Case', 'delete', ['id' => $createCase['id']]);
213
214 // Check result - case type should no longer exist.
215 $this->callAPISuccess('CaseType', 'delete', ['id' => $createCaseType['id']]);
216 $getCaseType = $this->callAPISuccess('CaseType', 'get', ['id' => $createCaseType['id']]);
217 $this->assertEquals(0, $getCaseType['count']);
218 }
219
220 /**
221 * Test the api returns case statuses filtered by case type.
222 *
223 * Api getoptions should respect the case statuses declared in the case type definition.
224 *
225 * @throws \Exception
226 */
227 public function testCaseStatusByCaseType() {
228 $statusName = md5(mt_rand());
229 $template = $this->callAPISuccess('CaseType', 'getsingle', ['id' => $this->caseTypeId]);
230 unset($template['id']);
231 $template['name'] = $template['title'] = 'test_case_type';
232 $template['definition']['statuses'] = ['Closed', $statusName];
233 $this->callAPISuccess('CaseType', 'create', $template);
234 $this->callAPISuccess('OptionValue', 'create', [
235 'option_group_id' => 'case_status',
236 'name' => $statusName,
237 'label' => $statusName,
238 'weight' => 99,
239 ]);
240 $result = $this->callAPISuccess('Case', 'getoptions', ['field' => 'status_id', 'case_type_id' => 'test_case_type', 'context' => 'validate']);
241 $this->assertEquals($template['definition']['statuses'], array_values($result['values']));
242 }
243
244 public function testDefinitionGroups() {
245 $gid1 = $this->groupCreate(['name' => 'testDefinitionGroups1', 'title' => 'testDefinitionGroups1']);
246 $gid2 = $this->groupCreate(['name' => 'testDefinitionGroups2', 'title' => 'testDefinitionGroups2']);
247 $def = $this->fixtures['Application_with_Definition'];
248 $def['definition']['caseRoles'][] = [
249 'name' => 'Second role',
250 'groups' => ['testDefinitionGroups1', 'testDefinitionGroups2'],
251 ];
252 $def['definition']['caseRoles'][] = [
253 'name' => 'Third role',
254 'groups' => 'testDefinitionGroups2',
255 ];
256 $def['definition']['activityAsgmtGrps'] = $gid1;
257 $createCaseType = $this->callAPISuccess('CaseType', 'create', $def);
258 $caseType = $this->callAPISuccess('CaseType', 'getsingle', ['id' => $createCaseType['id']]);
259
260 // Assert the group id got converted to array with name not id
261 $this->assertEquals(['testDefinitionGroups1'], $caseType['definition']['activityAsgmtGrps']);
262
263 // Assert multiple groups are stored
264 $this->assertEquals(['testDefinitionGroups1', 'testDefinitionGroups2'], $caseType['definition']['caseRoles'][1]['groups']);
265
266 // Assert single group got converted to array
267 $this->assertEquals(['testDefinitionGroups2'], $caseType['definition']['caseRoles'][2]['groups']);
268
269 }
270
271 }