2 require_once 'CiviTest/CiviCaseTestCase.php';
5 * Class CRM_Case_Form_CustomDataTest
8 class CRM_Case_Form_CustomDataTest
extends CiviCaseTestCase
{
10 protected $custom_group;
12 public function setUp(): void
{
14 $this->custom_group
= $this->customGroupCreate(['extends' => 'Case']);
15 $this->custom_group
= $this->custom_group
['values'][$this->custom_group
['id']];
19 * Test that changes to custom fields on cases generate the correct details
20 * body for ChangeCustomData.
22 * @dataProvider customDataProvider
25 * @param array $expected
27 public function testChangeCustomDataFormattedDetails(array $input, array $expected) {
28 // set up custom field, with any overrides from input params
29 $custom_field = $this->callAPISuccess('custom_field', 'create', array_merge([
30 'custom_group_id' => $this->custom_group
['id'],
32 'data_type' => 'String',
33 'html_type' => 'Text',
35 ], $input['custom_field_params']));
36 $custom_field = $custom_field['values'][$custom_field['id']];
38 // set up case and set the custom field initial value
39 $client_id = $this->individualCreate([], 0, TRUE);
40 $caseObj = $this->createCase($client_id, $this->_loggedInUser
);
41 if (isset($input['custom_field_oldvalue'])) {
42 $this->callAPISuccess('CustomValue', 'create', [
43 "custom_{$custom_field['id']}" => $input['custom_field_oldvalue'],
44 'entity_id' => $caseObj->id
,
49 $form = $this->getFormObject('CRM_Case_Form_CustomData');
50 $form->set('groupID', $this->custom_group
['id']);
51 $form->set('entityID', $caseObj->id
);
52 $form->set('subType', $this->caseTypeId
);
53 $form->set('cid', $client_id);
56 // We need to do money conversion here because to do the creation above it
57 // needs to be in machine format, but then for the form stuff it needs to
59 if (($input['custom_field_params']['data_type'] ??
'') === 'Money' && CRM_Core_I18n
::singleton()->getLocale() !== 'en_US') {
60 $expected['string'] = $this->convertCurrency($expected['string']);
61 if (isset($input['custom_field_oldvalue'])) {
62 $input['custom_field_oldvalue'] = $this->convertCurrency($input['custom_field_oldvalue']);
64 $input['custom_field_newvalue'] = $this->convertCurrency($input['custom_field_newvalue']);
67 // Simulate an edit with formValues.
68 // The suffix is always going to be '1' since we created it above and it's
69 // the first entry in the custom_value_XX table. If it doesn't exist yet
70 // then our new entry will still be the first and will have suffix 1.
71 $custom_field_name = "custom_{$custom_field['id']}_1";
72 $formValues = [$custom_field_name => $input['custom_field_newvalue']];
74 // compute and compare
75 $output = $form->formatCustomDataChangesForDetail($formValues);
76 $this->assertEquals($expected['string'], $output);
80 * Same as testChangeCustomDataFormattedDetails but in a different locale.
82 * @dataProvider customDataProvider
85 * @param array $expected
87 public function testChangeCustomDataFormattedDetailsLocale(array $input, array $expected) {
88 CRM_Core_I18n
::singleton()->setLocale('it_IT');
89 CRM_Core_Config
::singleton()->defaultCurrency
= 'EUR';
90 CRM_Core_Config
::singleton()->monetaryThousandSeparator
= ' ';
91 CRM_Core_Config
::singleton()->monetaryDecimalPoint
= ',';
93 $this->testChangeCustomDataFormattedDetails($input, $expected);
95 CRM_Core_Config
::singleton()->defaultCurrency
= 'USD';
96 CRM_Core_Config
::singleton()->monetaryThousandSeparator
= ',';
97 CRM_Core_Config
::singleton()->monetaryDecimalPoint
= '.';
98 CRM_Core_I18n
::singleton()->setLocale('en_US');
102 * data provider for testChangeCustomDataFormattedDetails
106 public function customDataProvider(): array {
110 'custom_field_params' => [
111 'html_type' => 'Select',
129 'custom_field_oldvalue' => '1',
130 'custom_field_newvalue' => '2',
133 'string' => 'What?: Red => Green',
139 'custom_field_params' => [
140 'html_type' => 'Select',
158 'custom_field_oldvalue' => '',
159 'custom_field_newvalue' => '2',
162 'string' => 'What?: => Green',
168 'custom_field_params' => [
169 'html_type' => 'Select',
187 'custom_field_oldvalue' => '1',
188 'custom_field_newvalue' => '',
191 'string' => 'What?: Red => ',
197 'custom_field_params' => [
198 'html_type' => 'Select',
216 // Note no old value, simulating as if we already have existing cases, but just added the field definition now.
217 'custom_field_newvalue' => '2',
220 'string' => 'What?: => Green',
226 'custom_field_params' => [
227 'data_type' => 'Money',
229 'custom_field_oldvalue' => '1.23',
230 'custom_field_newvalue' => '2.34',
233 'string' => 'What?: 1.23 => 2.34',
239 'custom_field_params' => [
240 'data_type' => 'Money',
242 'custom_field_oldvalue' => '',
243 'custom_field_newvalue' => '2.34',
246 'string' => 'What?: 0.00 => 2.34',
252 'custom_field_params' => [
253 'data_type' => 'Money',
255 'custom_field_oldvalue' => '1.23',
256 'custom_field_newvalue' => '',
259 'string' => 'What?: 1.23 => ',
265 'custom_field_params' => [
266 'data_type' => 'Money',
268 'custom_field_newvalue' => '2.34',
271 'string' => 'What?: => 2.34',
277 'custom_field_params' => [],
278 'custom_field_oldvalue' => 'some text',
279 'custom_field_newvalue' => 'some new text',
282 'string' => 'What?: some text => some new text',
288 'custom_field_params' => [],
289 'custom_field_oldvalue' => '',
290 'custom_field_newvalue' => 'some new text',
293 'string' => 'What?: => some new text',
299 'custom_field_params' => [],
300 'custom_field_oldvalue' => 'some text',
301 'custom_field_newvalue' => '',
304 'string' => 'What?: some text => ',
310 'custom_field_params' => [],
311 'custom_field_newvalue' => 'some new text',
314 'string' => 'What?: => some new text',
321 * Convert to locale currency format for purposes of these tests
322 * @param string $input
325 private function convertCurrency(string $input): string {
326 $conversion_table = [
327 ',' => CRM_Core_Config
::singleton()->monetaryThousandSeparator
,
328 '.' => CRM_Core_Config
::singleton()->monetaryDecimalPoint
,
330 return strtr($input, $conversion_table);
334 * Test that when custom case data is edited but not changed that it doesn't
335 * create a meaningless empty activity.
337 public function testCustomDataNoChangeNoActivity(): void
{
338 // Create a custom group and field
339 $customField = $this->callAPISuccess('custom_field', 'create', [
340 'custom_group_id' => $this->custom_group
['id'],
342 'data_type' => 'String',
343 'html_type' => 'Text',
346 $customField = $customField['values'][$customField['id']];
348 // Create a case and set the custom field to something
349 $individual = $this->individualCreate();
350 $caseObj = $this->createCase($individual, $this->_loggedInUser
);
351 $caseId = $caseObj->id
;
352 $this->callAPISuccess('CustomValue', 'create', [
353 "custom_{$customField['id']}" => 'immutable text',
354 'entity_id' => $caseId,
358 $form = new CRM_Case_Form_CustomData();
359 $form->controller
= new CRM_Core_Controller_Simple('CRM_Case_Form_CustomData', 'Case Data');
360 $form->set('groupID', $this->custom_group
['id']);
361 $form->set('entityID', $caseId);
363 $form->set('subType', 1);
364 $form->set('cid', $individual);
367 $form->controller
->_actions
['display']->perform($form, 'display');
370 // Don't change any field values and now call postProcess.
371 // Because the form does a redirect it triggers an exception during unit
372 // tests but that's ok.
373 $hadException = FALSE;
375 $form->controller
->_actions
['upload']->perform($form, 'upload');
377 catch (CRM_Core_Exception_PrematureExitException
$e) {
378 $hadException = TRUE;
379 $this->assertEquals('redirect', $e->errorData
['context']);
380 // compare parts of query string separately to avoid any clean url format mismatches
381 $this->assertStringContainsString('civicrm/contact/view/case', $e->errorData
['url']);
382 $this->assertStringContainsString("reset=1&id={$caseId}&cid={$individual}&action=view", $e->errorData
['url']);
384 // Make sure we did have an exception since otherwise we might get a
385 // false pass for the asserts above since they'd never run.
386 $this->assertTrue($hadException);
388 // there shouldn't be an activity of type Change Custom Data on the case
389 $result = $this->callAPISuccess('Activity', 'get', [
390 'activity_type_id' => 'Change Custom Data',
391 'case_id' => $caseId,
393 $this->assertEquals(0, $result['count']);