dev/core#389 [preliminary cleanup] Standardise metadat for custom field use
[civicrm-core.git] / tests / phpunit / CRM / Core / BAO / CustomFieldTest.php
CommitLineData
6a488035 1<?php
0eea664b 2
aba1cd8b
EM
3/**
4 * Class CRM_Core_BAO_CustomFieldTest
8392a043 5 *
acb109b7 6 * @group headless
aba1cd8b 7 */
6a488035 8class CRM_Core_BAO_CustomFieldTest extends CiviUnitTestCase {
6a488035 9
8392a043 10 use CRMTraits_Custom_CustomDataTrait;
11
c6b559da 12 protected $customFieldID;
13
00be9182 14 public function setUp() {
6a488035
TO
15 parent::setUp();
16 }
17
08e37a2a 18 public function testCreateCustomField() {
c6b559da 19 $customGroup = $this->createCustomField();
08e37a2a 20 $customFieldID = $this->assertDBNotNull('CRM_Core_DAO_CustomField', $customGroup['id'], 'id', 'custom_group_id',
6a488035
TO
21 'Database check for created CustomField.'
22 );
8392a043 23 $fields = [
6a488035
TO
24 'id' => $customFieldID,
25 'label' => 'editTestFld',
26 'is_active' => 1,
27 'data_type' => 'String',
28 'html_type' => 'Text',
08e37a2a 29 'custom_group_id' => $customGroup['id'],
8392a043 30 ];
6a488035 31
08e37a2a 32 CRM_Core_BAO_CustomField::create($fields);
6a488035
TO
33 $this->assertDBNotNull('CRM_Core_DAO_CustomField', 1, 'id', 'is_active', 'Database check for edited CustomField.');
34 $this->assertDBNotNull('CRM_Core_DAO_CustomField', $fields['label'], 'id', 'label', 'Database check for edited CustomField.');
35
8b3b9a2e
ARW
36 $dbFieldName = $this->assertDBNotNull('CRM_Core_DAO_CustomField', $customFieldID, 'name', 'id', 'Database check for edited CustomField.');
37 $dbColumnName = $this->assertDBNotNull('CRM_Core_DAO_CustomField', $customFieldID, 'column_name', 'id', 'Database check for edited CustomField.');
38 $this->assertEquals(strtolower("{$dbFieldName}_{$customFieldID}"), $dbColumnName,
92915c55 39 "Column name ends in ID");
8b3b9a2e 40
08e37a2a 41 $this->customGroupDelete($customGroup['id']);
8b3b9a2e 42 }
b2042573 43
08e37a2a 44 public function testCreateCustomFieldColumnName() {
8392a043 45 $customGroup = $this->customGroupCreate(['extends' => 'Individual']);
46 $fields = [
8b3b9a2e
ARW
47 'label' => 'testFld 2',
48 'column_name' => 'special_colname',
49 'data_type' => 'String',
50 'html_type' => 'Text',
08e37a2a 51 'custom_group_id' => $customGroup['id'],
8392a043 52 ];
08e37a2a 53 CRM_Core_BAO_CustomField::create($fields);
54 $customFieldID = $this->assertDBNotNull('CRM_Core_DAO_CustomField', $customGroup['id'], 'id', 'custom_group_id',
8b3b9a2e
ARW
55 'Database check for created CustomField.'
56 );
57 $dbColumnName = $this->assertDBNotNull('CRM_Core_DAO_CustomField', $customFieldID, 'column_name', 'id', 'Database check for edited CustomField.');
58 $this->assertEquals($fields['column_name'], $dbColumnName,
92915c55 59 "Column name set as specified");
8b3b9a2e 60
08e37a2a 61 $this->customGroupDelete($customGroup['id']);
6a488035
TO
62 }
63
08e37a2a 64 public function testCreateCustomFieldName() {
8392a043 65 $customGroup = $this->customGroupCreate(['extends' => 'Individual']);
66 $fields = [
43ff3196
TO
67 'label' => 'testFld 2',
68 'name' => 'special_fldlname',
69 'data_type' => 'String',
70 'html_type' => 'Text',
08e37a2a 71 'custom_group_id' => $customGroup['id'],
8392a043 72 ];
08e37a2a 73 CRM_Core_BAO_CustomField::create($fields);
74 $customFieldID = $this->assertDBNotNull('CRM_Core_DAO_CustomField', $customGroup['id'], 'id', 'custom_group_id',
43ff3196
TO
75 'Database check for created CustomField.'
76 );
77 $dbFieldName = $this->assertDBNotNull('CRM_Core_DAO_CustomField', $customFieldID, 'name', 'id', 'Database check for edited CustomField.');
78 $this->assertEquals($fields['name'], $dbFieldName,
79 "Column name set as specified");
80
08e37a2a 81 $this->customGroupDelete($customGroup['id']);
43ff3196
TO
82 }
83
00be9182 84 public function testGetFields() {
8392a043 85 $customGroup = $this->customGroupCreate(['extends' => 'Individual']);
86 $fields = [
6a488035
TO
87 'label' => 'testFld1',
88 'data_type' => 'String',
89 'html_type' => 'Text',
90 'is_active' => 1,
08e37a2a 91 'custom_group_id' => $customGroup['id'],
8392a043 92 ];
08e37a2a 93 CRM_Core_BAO_CustomField::create($fields);
94 $this->assertDBNotNull('CRM_Core_DAO_CustomField', $customGroup['id'], 'id', 'custom_group_id',
6a488035
TO
95 'Database check for created CustomField.'
96 );
8392a043 97 $fields = [
6a488035
TO
98 'label' => 'testFld2',
99 'data_type' => 'String',
100 'html_type' => 'Text',
101 'is_active' => 1,
08e37a2a 102 'custom_group_id' => $customGroup['id'],
8392a043 103 ];
08e37a2a 104 CRM_Core_BAO_CustomField::create($fields);
105 $this->assertDBNotNull('CRM_Core_DAO_CustomField', $customGroup['id'], 'id', 'custom_group_id',
6a488035
TO
106 'Database check for created CustomField.'
107 );
6a488035 108
08e37a2a 109 $this->customGroupDelete($customGroup['id']);
6a488035
TO
110 }
111
00be9182 112 public function testGetDisplayedValues() {
8392a043 113 $customGroup = $this->customGroupCreate(['extends' => 'Individual']);
114 $fieldsToCreate = [
115 [
d5c86914
CW
116 'data_type' => 'Country',
117 'html_type' => 'Select Country',
8392a043 118 'tests' => [
602b60e0 119 'United States' => 1228,
d5c86914 120 '' => NULL,
8392a043 121 ],
122 ],
123 [
d5c86914
CW
124 'data_type' => 'StateProvince',
125 'html_type' => 'Multi-Select State/Province',
8392a043 126 'tests' => [
d5c86914
CW
127 '' => 0,
128 'Alabama' => 1000,
8392a043 129 'Alabama, Alaska' => [1000, 1001],
130 ],
131 ],
132 [
d5c86914
CW
133 'data_type' => 'String',
134 'html_type' => 'Radio',
8392a043 135 'option_values' => [
d5c86914 136 'key' => 'KeyLabel',
8392a043 137 ],
138 'tests' => [
d5c86914 139 'KeyLabel' => 'key',
8392a043 140 ],
141 ],
142 [
d5c86914
CW
143 'data_type' => 'String',
144 'html_type' => 'CheckBox',
8392a043 145 'option_values' => [
d5c86914
CW
146 'key1' => 'Label1',
147 'key2' => 'Label2',
148 'key3' => 'Label3',
149 'key4' => 'Label4',
8392a043 150 ],
151 'tests' => [
152 'Label1' => ['key1'],
d5c86914 153 'Label2' => 'key2',
8392a043 154 'Label2, Label3' => ['key2', 'key3'],
155 'Label3, Label4' => CRM_Utils_Array::implodePadded(['key3', 'key4']),
156 'Label1, Label4' => ['key1' => 1, 'key4' => 1],
157 ],
158 ],
159 [
d5c86914
CW
160 'data_type' => 'Date',
161 'html_type' => 'Select Date',
162 'date_format' => 'd M yy',
163 'time_format' => 1,
8392a043 164 'tests' => [
d5c86914
CW
165 '1 Jun 1999 1:30PM' => '1999-06-01 13:30',
166 '' => '',
8392a043 167 ],
168 ],
169 ];
d5c86914 170 foreach ($fieldsToCreate as $num => $field) {
8392a043 171 $params = $field + [
172 'label' => 'test field ' . $num,
173 'custom_group_id' => $customGroup['id'],
174 ];
d5c86914
CW
175 unset($params['tests']);
176 $createdField = $this->callAPISuccess('customField', 'create', $params);
177 foreach ($field['tests'] as $expected => $input) {
178 $this->assertEquals($expected, CRM_Core_BAO_CustomField::displayValue($input, $createdField['id']));
179 }
180 }
6a488035 181
08e37a2a 182 $this->customGroupDelete($customGroup['id']);
6a488035
TO
183 }
184
17369736
AS
185 public function testGetDisplayedValuesContactRef() {
186 $customGroup = $this->customGroupCreate(['extends' => 'Individual']);
187 $params = [
188 'data_type' => 'ContactReference',
189 'html_type' => 'Autocomplete-Select',
190 'label' => 'test ref',
191 'custom_group_id' => $customGroup['id'],
192 ];
193 $createdField = $this->callAPISuccess('customField', 'create', $params);
194 $contact1 = $this->individualCreate();
195 $contact2 = $this->individualCreate(['custom_' . $createdField['id'] => $contact1['id']]);
196
197 $this->assertEquals($contact1['display_name'], CRM_Core_BAO_CustomField::displayValue($contact2['id'], $createdField['id']));
198 $this->assertEquals("Bob", CRM_Core_BAO_CustomField::displayValue("Bob", $createdField['id']));
199
200 $this->contactDelete($contact2['id']);
201 $this->contactDelete($contact1['id']);
202 $this->customGroupDelete($customGroup['id']);
203 }
204
08e37a2a 205 public function testDeleteCustomField() {
8392a043 206 $customGroup = $this->customGroupCreate(['extends' => 'Individual']);
207 $fields = [
08e37a2a 208 'custom_group_id' => $customGroup['id'],
8b3b9a2e 209 'label' => 'Throwaway Field',
d9136461 210 'dataType' => 'Memo',
211 'htmlType' => 'TextArea',
8392a043 212 ];
6a488035 213
08e37a2a 214 $customField = $this->customFieldCreate($fields);
215 $fieldObject = new CRM_Core_BAO_CustomField();
216 $fieldObject->id = $customField['id'];
217 $fieldObject->find(TRUE);
218 CRM_Core_BAO_CustomField::deleteField($fieldObject);
219 $this->assertDBNull('CRM_Core_DAO_CustomField', $customGroup['id'], 'id',
6a488035
TO
220 'custom_group_id', 'Database check for deleted Custom Field.'
221 );
08e37a2a 222 $this->customGroupDelete($customGroup['id']);
6a488035
TO
223 }
224
225 /**
08e37a2a 226 * Move a custom field from $groupA to $groupB.
227 *
228 * Make sure that data records are correctly matched and created.
6a488035 229 */
00be9182 230 public function testMoveField() {
6a488035 231 $countriesByName = array_flip(CRM_Core_PseudoConstant::country(FALSE, FALSE));
602b60e0 232 $this->assertTrue($countriesByName['Andorra'] > 0);
8392a043 233 $groups = [
234 'A' => $this->customGroupCreate([
92915c55
TO
235 'title' => 'Test_Group A',
236 'name' => 'test_group_a',
8392a043 237 'extends' => ['Individual'],
92915c55
TO
238 'style' => 'Inline',
239 'is_multiple' => 0,
240 'is_active' => 1,
241 'version' => 3,
8392a043 242 ]),
243 'B' => $this->customGroupCreate([
92915c55
TO
244 'title' => 'Test_Group B',
245 'name' => 'test_group_b',
8392a043 246 'extends' => ['Individual'],
92915c55
TO
247 'style' => 'Inline',
248 'is_multiple' => 0,
249 'is_active' => 1,
250 'version' => 3,
8392a043 251 ]),
252 ];
08e37a2a 253 $groupA = $groups['A']['values'][$groups['A']['id']];
254 $groupB = $groups['B']['values'][$groups['B']['id']];
8392a043 255 $countryA = $this->customFieldCreate([
08e37a2a 256 'custom_group_id' => $groups['A']['id'],
257 'label' => 'Country A',
258 'dataType' => 'Country',
259 'htmlType' => 'Select Country',
260 'default_value' => NULL,
8392a043 261 ]);
262 $countryB = $this->customFieldCreate([
08e37a2a 263 'custom_group_id' => $groups['A']['id'],
264 'label' => 'Country B',
265 'dataType' => 'Country',
266 'htmlType' => 'Select Country',
267 'default_value' => NULL,
8392a043 268 ]);
269 $countryC = $this->customFieldCreate([
08e37a2a 270 'custom_group_id' => $groups['B']['id'],
271 'label' => 'Country C',
272 'dataType' => 'Country',
273 'htmlType' => 'Select Country',
274 'default_value' => NULL,
8392a043 275 ]);
08e37a2a 276
8392a043 277 $fields = [
08e37a2a 278 'countryA' => $countryA['values'][$countryA['id']],
279 'countryB' => $countryB['values'][$countryB['id']],
280 'countryC' => $countryC['values'][$countryC['id']],
8392a043 281 ];
282 $contacts = [
283 'alice' => $this->individualCreate([
92915c55
TO
284 'first_name' => 'Alice',
285 'last_name' => 'Albertson',
602b60e0
SL
286 'custom_' . $fields['countryA']['id'] => $countriesByName['Andorra'],
287 'custom_' . $fields['countryB']['id'] => $countriesByName['Barbados'],
8392a043 288 ]),
289 'bob' => $this->individualCreate([
92915c55
TO
290 'first_name' => 'Bob',
291 'last_name' => 'Roberts',
602b60e0
SL
292 'custom_' . $fields['countryA']['id'] => $countriesByName['Austria'],
293 'custom_' . $fields['countryB']['id'] => $countriesByName['Bermuda'],
294 'custom_' . $fields['countryC']['id'] => $countriesByName['Chad'],
8392a043 295 ]),
296 'carol' => $this->individualCreate([
92915c55
TO
297 'first_name' => 'Carol',
298 'last_name' => 'Carolson',
602b60e0 299 'custom_' . $fields['countryC']['id'] => $countriesByName['Cambodia'],
8392a043 300 ]),
301 ];
6a488035
TO
302
303 // Move!
08e37a2a 304 CRM_Core_BAO_CustomField::moveField($fields['countryB']['id'], $groupB['id']);
6a488035
TO
305
306 // Group[A] no longer has fields[countryB]
307 $errorScope = CRM_Core_TemporaryErrorScope::useException();
308 try {
08e37a2a 309 $this->assertDBQuery(1, "SELECT {$fields['countryB']['column_name']} FROM " . $groupA['table_name']);
6a488035
TO
310 $this->fail('Expected exception when querying column on wrong table');
311 }
92915c55
TO
312 catch (PEAR_Exception$e) {
313 }
6a488035
TO
314 $errorScope = NULL;
315
316 // Alice: Group[B] has fields[countryB], but fields[countryC] did not exist before
317 $this->assertDBQuery(1,
08e37a2a 318 "SELECT count(*) FROM {$groupB['table_name']}
b2042573 319 WHERE entity_id = %1
08e37a2a 320 AND {$fields['countryB']['column_name']} = %3
321 AND {$fields['countryC']['column_name']} is null",
8392a043 322 [
323 1 => [$contacts['alice'], 'Integer'],
324 3 => [$countriesByName['Barbados'], 'Integer'],
325 ]
6a488035
TO
326 );
327
328 // Bob: Group[B] has merged fields[countryB] and fields[countryC] on the same record
329 $this->assertDBQuery(1,
08e37a2a 330 "SELECT count(*) FROM {$groupB['table_name']}
b2042573 331 WHERE entity_id = %1
08e37a2a 332 AND {$fields['countryB']['column_name']} = %3
333 AND {$fields['countryC']['column_name']} = %4",
8392a043 334 [
335 1 => [$contacts['bob'], 'Integer'],
336 3 => [$countriesByName['Bermuda'], 'Integer'],
337 4 => [$countriesByName['Chad'], 'Integer'],
338 ]
6a488035
TO
339 );
340
341 // Carol: Group[B] still has fields[countryC] but did not get fields[countryB]
342 $this->assertDBQuery(1,
08e37a2a 343 "SELECT count(*) FROM {$groupB['table_name']}
b2042573 344 WHERE entity_id = %1
08e37a2a 345 AND {$fields['countryB']['column_name']} is null
346 AND {$fields['countryC']['column_name']} = %4",
8392a043 347 [
348 1 => [$contacts['carol'], 'Integer'],
349 4 => [$countriesByName['Cambodia'], 'Integer'],
350 ]
6a488035
TO
351 );
352
08e37a2a 353 $this->customGroupDelete($groups['A']['id']);
354 $this->customGroupDelete($groupB['id']);
6a488035 355 }
96025800 356
c6b559da 357 /**
358 * Test get custom field id function.
359 */
360 public function testGetCustomFieldID() {
361 $this->createCustomField();
362 $fieldID = CRM_Core_BAO_CustomField::getCustomFieldID('testFld');
363 $this->assertEquals($this->customFieldID, $fieldID);
364
365 $fieldID = CRM_Core_BAO_CustomField::getCustomFieldID('testFld', 'new custom group');
366 $this->assertEquals($this->customFieldID, $fieldID);
30b6e002
PF
367
368 $fieldID = CRM_Core_BAO_CustomField::getCustomFieldID('testFld', 'new custom group', TRUE);
369 $this->assertEquals('custom_' . $this->customFieldID, $fieldID);
370
371 // create field with same name in a different group
372 $this->createCustomField('other custom group');
373 $otherFieldID = CRM_Core_BAO_CustomField::getCustomFieldID('testFld', 'other custom group');
374 // make sure it does not return the field ID of the first field
375 $this->assertNotEquals($fieldID, $otherFieldID);
c6b559da 376 }
377
378 /**
30b6e002
PF
379 * Create a custom field
380 *
381 * @param string $groupTitle
382 *
c6b559da 383 * @return array
384 */
30b6e002
PF
385 protected function createCustomField($groupTitle = 'new custom group') {
386 $customGroup = $this->customGroupCreate([
387 'extends' => 'Individual',
8392a043 388 'title' => $groupTitle,
30b6e002 389 ]);
8392a043 390 $fields = [
c6b559da 391 'label' => 'testFld',
392 'data_type' => 'String',
393 'html_type' => 'Text',
394 'custom_group_id' => $customGroup['id'],
8392a043 395 ];
c6b559da 396 $field = CRM_Core_BAO_CustomField::create($fields);
397 $this->customFieldID = $field->id;
398 return $customGroup;
399 }
400
8392a043 401 /**
402 * Tet the getFieldsForImport function.
403 */
404 public function testGetFieldsForImport() {
405 $this->entity = 'Contact';
406 $this->createCustomGroupWithFieldsOfAllTypes();
407 $expected = [
408 $this->getCustomFieldName('country') => [
409 'name' => $this->getCustomFieldName('country') ,
410 'type' => 1,
411 'title' => 'Country',
412 'headerPattern' => '//',
413 'import' => 1,
414 'custom_field_id' => $this->getCustomFieldID('country'),
415 'options_per_line' => NULL,
416 'text_length' => NULL,
417 'data_type' => 'Int',
418 'html_type' => 'Select Country',
419 'is_search_range' => '0',
420 ],
421 $this->getCustomFieldName('file') => [
422 'name' => $this->getCustomFieldName('file'),
423 'type' => 2,
424 'title' => 'Custom Field',
425 'headerPattern' => '//',
426 'import' => 1,
427 'custom_field_id' => $this->getCustomFieldID('file'),
428 'options_per_line' => NULL,
429 'text_length' => NULL,
430 'data_type' => 'File',
431 'html_type' => 'File',
432 'is_search_range' => '0',
433 ],
434 $this->getCustomFieldName('text') => [
435 'name' => $this->getCustomFieldName('text'),
436 'type' => 2,
437 'title' => 'Enter text here',
438 'headerPattern' => '//',
439 'import' => 1,
440 'custom_field_id' => $this->getCustomFieldID('text'),
441 'options_per_line' => NULL,
442 'text_length' => NULL,
443 'data_type' => 'String',
444 'html_type' => 'Text',
445 'is_search_range' => '0',
446 ],
447 $this->getCustomFieldName('select_string') => [
448 'name' => $this->getCustomFieldName('select_string'),
449 'type' => 2,
450 'title' => 'Pick Color',
451 'headerPattern' => '//',
452 'import' => 1,
453 'custom_field_id' => $this->getCustomFieldID('select_string'),
454 'options_per_line' => NULL,
455 'text_length' => NULL,
456 'data_type' => 'String',
457 'html_type' => 'Select',
458 'is_search_range' => '0',
459 ],
460 $this->getCustomFieldName('select_date') => [
461 'name' => $this->getCustomFieldName('select_date'),
462 'type' => 4,
463 'title' => 'test_date',
464 'headerPattern' => '//',
465 'import' => 1,
466 'custom_field_id' => $this->getCustomFieldID('select_date'),
467 'options_per_line' => NULL,
468 'text_length' => NULL,
469 'data_type' => 'Date',
470 'html_type' => 'Select Date',
471 'is_search_range' => '0',
472 'date_format' => 'mm/dd/yy',
473 'time_format' => '1',
474 ],
475 $this->getCustomFieldName('link') => [
476 'name' => $this->getCustomFieldName('link'),
477 'type' => 2,
478 'title' => 'test_link',
479 'headerPattern' => '//',
480 'import' => 1,
481 'custom_field_id' => $this->getCustomFieldID('link'),
482 'options_per_line' => NULL,
483 'text_length' => NULL,
484 'data_type' => 'Link',
485 'html_type' => 'Link',
486 'is_search_range' => '0',
487 ],
488 ];
489 $this->assertEquals($expected, CRM_Core_BAO_CustomField::getFieldsForImport());
490 }
491
6a488035 492}