Ian province abbreviation patch - issue 724
[civicrm-core.git] / tests / phpunit / api / v3 / CustomFieldTest.php
CommitLineData
6a488035 1<?php
b6708aeb 2/*
3 +--------------------------------------------------------------------+
81621fee 4| CiviCRM version 4.7 |
b6708aeb 5+--------------------------------------------------------------------+
e7112fa7 6| Copyright CiviCRM LLC (c) 2004-2015 |
b6708aeb 7+--------------------------------------------------------------------+
8| This file is a part of CiviCRM. |
9| |
10| CiviCRM is free software; you can copy, modify, and distribute it |
11| under the terms of the GNU Affero General Public License |
12| Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
13| |
14| CiviCRM is distributed in the hope that it will be useful, but |
15| WITHOUT ANY WARRANTY; without even the implied warranty of |
16| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
17| See the GNU Affero General Public License for more details. |
18| |
19| You should have received a copy of the GNU Affero General Public |
20| License and the CiviCRM Licensing Exception along |
21| with this program; if not, contact CiviCRM LLC |
22| at info[AT]civicrm[DOT]org. If you have questions about the |
23| GNU Affero General Public License or the licensing of CiviCRM, |
24| see the CiviCRM license FAQ at http://civicrm.org/licensing |
25+--------------------------------------------------------------------+
e70a7fc0 26 */
6a488035
TO
27
28/**
29 * Include class definitions
30 */
31require_once 'tests/phpunit/CiviTest/CiviUnitTestCase.php';
32
33
34/**
35 * Test APIv3 civicrm_create_custom_group
36 *
6c6e6187 37 * @package CiviCRM
6a488035
TO
38 */
39class api_v3_CustomFieldTest extends CiviUnitTestCase {
40 protected $_apiversion;
b7c9bc4c 41
00be9182 42 public function setUp() {
6a488035
TO
43 $this->_apiversion = 3;
44 parent::setUp();
45 }
46
00be9182 47 public function tearDown() {
6a488035 48 $tablesToTruncate = array(
b3c30fda
CW
49 'civicrm_contact',
50 'civicrm_file',
51 'civicrm_entity_file',
6a488035 52 );
b3c30fda 53 // true tells quickCleanup to drop custom_value tables that might have been created in the test
6a488035
TO
54 $this->quickCleanup($tablesToTruncate, TRUE);
55 }
56
57 /**
eceb18cc 58 * Check with no array.
6a488035 59 */
00be9182 60 public function testCustomFieldCreateNoArray() {
6a488035
TO
61 $fieldParams = NULL;
62
d0e1eff2 63 $customField = $this->callAPIFailure('custom_field', 'create', $fieldParams);
6a488035
TO
64 $this->assertEquals($customField['error_message'], 'Input variable `params` is not an array');
65 }
66
67 /**
eceb18cc 68 * Check with no label.
6a488035 69 */
00be9182 70 public function testCustomFieldCreateWithoutLabel() {
e830c6ae 71 $customGroup = $this->customGroupCreate(array('extends' => 'Individual', 'title' => 'text_test_group'));
6a488035
TO
72 $params = array(
73 'custom_group_id' => $customGroup['id'],
74 'name' => 'test_textfield2',
75 'html_type' => 'Text',
76 'data_type' => 'String',
77 'default_value' => 'abc',
78 'weight' => 4,
79 'is_required' => 1,
80 'is_searchable' => 0,
81 'is_active' => 1,
6a488035
TO
82 );
83
d0e1eff2 84 $customField = $this->callAPIFailure('custom_field', 'create', $params);
6a488035
TO
85 $this->assertEquals($customField['error_message'], 'Mandatory key(s) missing from params array: label');
86 }
87
88 /**
eceb18cc 89 * Check with edit.
6a488035 90 */
00be9182 91 public function testCustomFieldCreateWithEdit() {
e830c6ae 92 $customGroup = $this->customGroupCreate(array('extends' => 'Individual', 'title' => 'text_test_group'));
6a488035
TO
93 $params = array(
94 'custom_group_id' => $customGroup['id'],
95 'name' => 'test_textfield2',
96 'label' => 'Name1',
97 'html_type' => 'Text',
98 'data_type' => 'String',
99 'default_value' => 'abc',
100 'weight' => 4,
101 'is_required' => 1,
102 'is_searchable' => 0,
103 'is_active' => 1,
6a488035
TO
104 );
105
92915c55 106 $customField = $this->callAPIAndDocument('custom_field', 'create', $params, __FUNCTION__, __FILE__);
6a488035 107 $params['id'] = $customField['id'];
92915c55 108 $customField = $this->callAPISuccess('custom_field', 'create', $params);
6a488035 109
ba4a1892 110 $this->assertNotNull($customField['id']);
6a488035
TO
111 }
112
113 /**
eceb18cc 114 * Check without groupId.
6a488035 115 */
00be9182 116 public function testCustomFieldCreateWithoutGroupID() {
6a488035
TO
117 $fieldParams = array(
118 'name' => 'test_textfield1',
119 'label' => 'Name',
120 'html_type' => 'Text',
121 'data_type' => 'String',
122 'default_value' => 'abc',
123 'weight' => 4,
124 'is_required' => 1,
125 'is_searchable' => 0,
126 'is_active' => 1,
e830c6ae 127
6a488035
TO
128 );
129
d0e1eff2 130 $customField = $this->callAPIFailure('custom_field', 'create', $fieldParams);
6a488035
TO
131 $this->assertEquals($customField['error_message'], 'Mandatory key(s) missing from params array: custom_group_id');
132 }
133
134 /**
135 * Check for Each data type: loop through available form input types
ae5ffbb7 136 */
00be9182 137 public function testCustomFieldCreateAllAvailableFormInputs() {
e830c6ae 138 $gid = $this->customGroupCreate(array('extends' => 'Individual', 'title' => 'testAllFormInputs'));
6a488035
TO
139
140 $dtype = CRM_Core_BAO_CustomField::dataType();
141 $htype = CRM_Core_BAO_CustomField::dataToHtml();
142
143 $n = 0;
144 foreach ($dtype as $dkey => $dvalue) {
145 foreach ($htype[$n] as $hkey => $hvalue) {
146 //echo $dkey."][".$hvalue."\n";
147 $this->_loopingCustomFieldCreateTest($this->_buildParams($gid['id'], $hvalue, $dkey));
148 }
149 $n++;
150 }
151 }
6c6e6187 152 /*
e70a7fc0
TO
153 * Can't figure out the point of this?
154 */
4cbe18b8 155 /**
c490a46a 156 * @param array $params
4cbe18b8 157 */
00be9182 158 public function _loopingCustomFieldCreateTest($params) {
e830c6ae 159 $customField = $this->callAPISuccess('custom_field', 'create', $params);
6a488035
TO
160 $this->assertNotNull($customField['id']);
161 $this->getAndCheck($params, $customField['id'], 'CustomField');
162 }
163
4cbe18b8 164 /**
100fef9d 165 * @param int $gid
4cbe18b8
EM
166 * @param $htype
167 * @param $dtype
168 *
169 * @return array
170 */
00be9182 171 public function _buildParams($gid, $htype, $dtype) {
6a488035
TO
172 $params = $this->_buildBasicParams($gid, $htype, $dtype);
173 /* //Not Working for any type. Maybe redundant with testCustomFieldCreateWithOptionValues()
e70a7fc0
TO
174 if ($htype == 'Multi-Select')
175 $params = array_merge($params, array(
176 'option_label' => array( 'Label1','Label2'),
177 'option_value' => array( 'val1', 'val2' ),
178 'option_weight' => array( 1, 2),
179 'option_status' => array( 1, 1),
180 ));
181 */
6a488035
TO
182
183 return $params;
184 }
185
4cbe18b8 186 /**
100fef9d 187 * @param int $gid
4cbe18b8
EM
188 * @param $htype
189 * @param $dtype
190 *
191 * @return array
192 */
00be9182 193 public function _buildBasicParams($gid, $htype, $dtype) {
6a488035
TO
194 return array(
195 'custom_group_id' => $gid,
196 'label' => $dtype . $htype,
197 'html_type' => $htype,
198 'data_type' => $dtype,
199 'weight' => 4,
200 'is_required' => 0,
201 'is_searchable' => 0,
202 'is_active' => 1,
e830c6ae 203
6a488035
TO
204 );
205 }
206
207 /**
eceb18cc 208 * Test using example code.
6a488035
TO
209 */
210 /*function testCustomFieldCreateExample( )
e70a7fc0 211 {
6a488035
TO
212
213
e70a7fc0
TO
214 $customGroup = $this->customGroupCreate('Individual','date_test_group',3);
215 require_once 'api/v3/examples/CustomField/Create.php';
216 $result = custom_field_create_example();
217 $expectedResult = custom_field_create_expectedresult();
218 $this->assertEquals($result,$expectedResult);
219 }*/
6a488035
TO
220
221 /**
100fef9d 222 * Check with data type - Options with option_values
6a488035 223 */
00be9182 224 public function testCustomFieldCreateWithEmptyOptionGroup() {
e830c6ae 225 $customGroup = $this->customGroupCreate(array('extends' => 'Contact', 'title' => 'select_test_group'));
b958933f 226 $params = array(
227 'custom_group_id' => $customGroup['id'],
228 'label' => 'Country',
229 'html_type' => 'Select',
230 'data_type' => 'String',
231 'weight' => 4,
232 'is_required' => 1,
233 'is_searchable' => 0,
234 'is_active' => 1,
b958933f 235 );
236
e830c6ae 237 $customField = $this->callAPISuccess('custom_field', 'create', $params);
b958933f 238 $this->assertNotNull($customField['id']);
e830c6ae 239 $optionGroupID = $this->callAPISuccess('custom_field', 'getvalue', array(
b958933f 240 'id' => $customField['id'],
241 'return' => 'option_group_id',
242 ));
243
244 $this->assertTrue(is_numeric($optionGroupID) && ($optionGroupID > 0));
e830c6ae 245 $optionGroup = $this->callAPISuccess('option_group', 'getsingle', array(
ae5ffbb7 246 'id' => $optionGroupID,
92915c55 247 ));
6c6e6187 248 $this->assertEquals($optionGroup['title'], 'Country');
e830c6ae 249 $optionValueCount = $this->callAPISuccess('option_value', 'getcount', array(
ae5ffbb7 250 'option_group_id' => $optionGroupID,
92915c55 251 ));
b958933f 252 $this->assertEquals(0, $optionValueCount);
253 }
254
eebb53df 255 /**
eceb18cc 256 * Test custom field with existing option group.
eebb53df 257 */
00be9182 258 public function testCustomFieldExistingOptionGroup() {
eebb53df
JV
259 $customGroup = $this->customGroupCreate(array('extends' => 'Organization', 'title' => 'test_group'));
260 $params = array(
261 'custom_group_id' => $customGroup['id'],
262 // Just to say something:
263 'label' => 'Organization Gender',
264 'html_type' => 'Select',
265 'data_type' => 'Int',
266 'weight' => 4,
267 'is_required' => 1,
268 'is_searchable' => 0,
269 'is_active' => 1,
270 // Option group id 3: gender
271 'option_group_id' => 3,
272 );
273
274 $customField = $this->callAPISuccess('custom_field', 'create', $params);
275 $this->assertNotNull($customField['id']);
276 $optionGroupID = $this->callAPISuccess('custom_field', 'getvalue', array(
277 'id' => $customField['id'],
278 'return' => 'option_group_id',
279 ));
280
6c6e6187 281 $this->assertEquals($optionGroupID, 3);
eebb53df
JV
282 }
283
b958933f 284
3c70d501 285 /**
286 * Test custom field get works & return param works
287 */
9b873358 288 public function testCustomFieldGetReturnOptions() {
e830c6ae 289 $customGroup = $this->customGroupCreate(array('extends' => 'Individual', 'title' => 'test_group'));
b422b715 290 $customField = $this->customFieldCreate(array('custom_group_id' => $customGroup['id']));
3c70d501 291
e830c6ae 292 $result = $this->callAPISuccess('custom_field', 'getsingle', array(
3c70d501 293 'id' => $customField['id'],
294 'return' => 'data_type',
295 ));
296 $this->assertTrue(array_key_exists('data_type', $result));
297 $this->assertFalse(array_key_exists('custom_group_id', $result));
298 }
299
300 /**
301 * Test custom field get works & return param works
302 */
9b873358 303 public function testCustomFieldGetReturnArray() {
e830c6ae 304 $customGroup = $this->customGroupCreate(array('extends' => 'Individual', 'title' => 'test_group'));
b422b715 305 $customField = $this->customFieldCreate(array('custom_group_id' => $customGroup['id']));
3c70d501 306
e830c6ae 307 $result = $this->callAPISuccess('custom_field', 'getsingle', array(
92915c55 308 'id' => $customField['id'],
3c70d501 309 'return' => array('data_type'),
310 ));
311 $this->assertTrue(array_key_exists('data_type', $result));
312 $this->assertFalse(array_key_exists('custom_group_id', $result));
313 }
314
315 /**
316 * Test custom field get works & return param works
317 */
9b873358 318 public function testCustomFieldGetReturnTwoOptions() {
e830c6ae 319 $customGroup = $this->customGroupCreate(array('extends' => 'Individual', 'test_group'));
b422b715 320 $customField = $this->customFieldCreate(array('custom_group_id' => $customGroup['id']));
3c70d501 321
e830c6ae 322 $result = $this->callAPISuccess('custom_field', 'getsingle', array(
92915c55 323 'id' => $customField['id'],
3c70d501 324 'return' => 'data_type, custom_group_id',
325 ));
326 $this->assertTrue(array_key_exists('data_type', $result));
327 $this->assertTrue(array_key_exists('custom_group_id', $result));
328 $this->assertFalse(array_key_exists('label', $result));
329 }
330
00be9182 331 public function testCustomFieldCreateWithOptionValues() {
e830c6ae 332 $customGroup = $this->customGroupCreate(array('extends' => 'Contact', 'title' => 'select_test_group'));
6a488035
TO
333
334 $option_values = array(
6c6e6187 335 array(
92915c55 336 'weight' => 1,
6a488035
TO
337 'label' => 'Label1',
338 'value' => 1,
339 'is_active' => 1,
340 ),
341 array(
342 'weight' => 2,
343 'label' => 'Label2',
344 'value' => 2,
345 'is_active' => 1,
346 ),
347 );
348
349 $params = array(
350 'custom_group_id' => $customGroup['id'],
7f6d3dd3 351 'label' => 'Our special field',
6a488035
TO
352 'html_type' => 'Select',
353 'data_type' => 'String',
354 'weight' => 4,
355 'is_required' => 1,
356 'is_searchable' => 0,
357 'is_active' => 1,
358 'option_values' => $option_values,
e830c6ae 359
6a488035
TO
360 );
361
e830c6ae 362 $customField = $this->callAPISuccess('custom_field', 'create', $params);
6a488035 363
b958933f 364 $this->assertAPISuccess($customField);
6a488035
TO
365 $this->assertNotNull($customField['id']);
366 $getFieldsParams = array(
367 'options' => array('get_options' => 'custom_' . $customField['id']),
92915c55 368 'action' => 'create',
6a488035 369 );
5c49fee0 370 $description = "Demonstrates retrieving metadata with custom field options.";
6a488035 371 $subfile = "GetFieldsOptions";
a828d7b8 372 $fields = $this->callAPIAndDocument('contact', 'getfields', $getFieldsParams, __FUNCTION__, 'ContactTest.php', $description, $subfile);
6a488035
TO
373 $this->assertArrayHasKey('options', $fields['values']['custom_' . $customField['id']]);
374 $this->assertEquals('Label1', $fields['values']['custom_' . $customField['id']]['options'][1]);
375 $getOptionsArray = array(
376 'field' => 'custom_' . $customField['id'],
92915c55 377 );
5c49fee0 378 $description = "Demonstrates retrieving options for a custom field.";
6a488035 379 $subfile = "GetOptions";
a828d7b8 380 $result = $this->callAPIAndDocument('contact', 'getoptions', $getOptionsArray, __FUNCTION__, 'ContactTest.php', $description, '');
6a488035 381 $this->assertEquals('Label1', $result['values'][1]);
6a488035
TO
382 }
383
384 ///////////////// civicrm_custom_field_delete methods
385
386 /**
eceb18cc 387 * Check with no array.
6a488035 388 */
00be9182 389 public function testCustomFieldDeleteNoArray() {
6a488035 390 $params = NULL;
d0e1eff2 391 $customField = $this->callAPIFailure('custom_field', 'delete', $params);
6a488035
TO
392 $this->assertEquals($customField['error_message'], 'Input variable `params` is not an array');
393 }
394
395 /**
eceb18cc 396 * Check without Field ID.
6a488035 397 */
00be9182 398 public function testCustomFieldDeleteWithoutFieldID() {
e830c6ae 399 $params = array();
400 $customField = $this->callAPIFailure('custom_field', 'delete', $params,
401 'Mandatory key(s) missing from params array: id');
6a488035
TO
402 }
403
404 /**
eceb18cc 405 * Check without valid array.
6a488035 406 */
00be9182 407 public function testCustomFieldDelete() {
e830c6ae 408 $customGroup = $this->customGroupCreate(array('extends' => 'Individual', 'title' => 'test_group'));
b422b715 409 $customField = $this->customFieldCreate(array('custom_group_id' => $customGroup['id']));
ba4a1892 410 $this->assertNotNull($customField['id']);
6a488035
TO
411
412 $params = array(
6a488035
TO
413 'id' => $customField['id'],
414 );
e830c6ae 415 $result = $this->callAPIAndDocument('custom_field', 'delete', $params, __FUNCTION__, __FILE__);
6a488035 416
a15773db 417 $this->assertAPISuccess($result);
6a488035
TO
418 }
419
420 /**
eceb18cc 421 * Check for Option Value.
6a488035 422 */
00be9182 423 public function testCustomFieldOptionValueDelete() {
e830c6ae 424 $customGroup = $this->customGroupCreate(array('extends' => 'Contact', 'title' => 'ABC'));
6a488035 425 $customOptionValueFields = $this->customFieldOptionValueCreate($customGroup, 'fieldABC');
6a488035 426 $params = array(
6a488035
TO
427 'id' => $customOptionValueFields,
428 );
429
e830c6ae 430 $customField = $this->callAPISuccess('custom_field', 'delete', $customOptionValueFields);
6a488035 431 }
6b59896e
TO
432
433 /**
434 * If there's one custom group for "Contact" and one for "Activity", then "Contact.getfields"
435 * and "Activity.getfields" should return only their respective fields (not the other's fields),
436 * and unrelated entities should return no custom fields.
437 */
00be9182 438 public function testGetfields_CrossEntityPollution() {
6b59896e
TO
439 $auxEntities = array('Email', 'Address', 'LocBlock', 'Membership', 'ContributionPage', 'ReportInstance');
440 $allEntities = array_merge(array('Contact', 'Activity'), $auxEntities);
441
442 // Baseline - getfields doesn't reporting any customfields for any entities
443 foreach ($allEntities as $entity) {
444 $this->assertEquals(
445 array(),
446 $this->getCustomFieldKeys($this->callAPISuccess($entity, 'getfields', array())),
447 "Baseline custom fields for $entity should be empty"
448 );
449 }
450
451 // Add some fields
f8a3cd29 452 $contactGroup = $this->customGroupCreate(array('extends' => 'Contact', 'title' => 'test_group_c'));
92915c55
TO
453 $contactField = $this->customFieldCreate(array(
454 'custom_group_id' => $contactGroup['id'],
ae5ffbb7 455 'label' => 'For Contacts',
92915c55 456 ));
f8a3cd29
TO
457 $indivGroup = $this->customGroupCreate(array('extends' => 'Individual', 'title' => 'test_group_i'));
458 $indivField = $this->customFieldCreate(array('custom_group_id' => $indivGroup['id'], 'label' => 'For Individuals'));
459 $activityGroup = $this->customGroupCreate(array('extends' => 'Activity', 'title' => 'test_group_a'));
92915c55
TO
460 $activityField = $this->customFieldCreate(array(
461 'custom_group_id' => $activityGroup['id'],
ae5ffbb7 462 'label' => 'For Activities',
92915c55 463 ));
6b59896e 464
f8a3cd29
TO
465 // Check getfields
466 $this->assertEquals(
467 array('custom_' . $contactField['id'], 'custom_' . $indivField['id']),
468 $this->getCustomFieldKeys($this->callAPISuccess('Contact', 'getfields', array())),
469 'Contact custom fields'
470 );
471 $this->assertEquals(
472 array('custom_' . $contactField['id'], 'custom_' . $indivField['id']),
473 $this->getCustomFieldKeys($this->callAPISuccess('Individual', 'getfields', array())),
474 'Individual custom fields'
475 );
476 $this->assertEquals(
477 array('custom_' . $contactField['id']),
478 $this->getCustomFieldKeys($this->callAPISuccess('Organization', 'getfields', array())),
479 'Organization custom fields'
480 );
6b59896e
TO
481 $this->assertEquals(
482 array('custom_' . $activityField['id']),
483 $this->getCustomFieldKeys($this->callAPISuccess('Activity', 'getfields', array())),
484 'Activity custom fields'
485 );
486 foreach ($auxEntities as $entity) {
487 $this->assertEquals(
488 array(),
489 $this->getCustomFieldKeys($this->callAPISuccess($entity, 'getfields', array())),
490 "Custom fields for $entity should be empty"
491 );
492 }
493 }
494
b3c30fda
CW
495 /**
496 * Test setting and getting a custom file field value.
497 *
498 * Uses the "attachment" api for setting value.
499 */
500 public function testCustomFileField() {
501 $customGroup = $this->customGroupCreate(array('title' => 'attachment_test_group'));
502 $params = array(
503 'custom_group_id' => $customGroup['id'],
504 'name' => 'test_file_attachment',
505 'label' => 'test_file_attachment',
506 'html_type' => 'File',
507 'data_type' => 'File',
508 'is_active' => 1,
509 );
510 $customField = $this->callAPISuccess('custom_field', 'create', $params);
511 $cfId = 'custom_' . $customField['id'];
512
513 $cid = $this->individualCreate();
514
515 $attachment = $this->callAPISuccess('attachment', 'create', array(
516 'name' => CRM_Utils_String::createRandom(5, CRM_Utils_String::ALPHANUMERIC) . '_testCustomFileField.txt',
517 'mime_type' => 'text/plain',
518 'content' => 'My test content',
519 'field_name' => $cfId,
520 'entity_id' => $cid,
521 ));
522 $this->assertAttachmentExistence(TRUE, $attachment);
523
524 $result = $this->callAPISuccess('contact', 'getsingle', array(
525 'id' => $cid,
526 'return' => $cfId,
527 ));
528
529 $this->assertEquals($attachment['id'], $result[$cfId]);
530 }
531
4cbe18b8
EM
532 /**
533 * @param $getFieldsResult
534 *
535 * @return array
536 */
00be9182 537 public function getCustomFieldKeys($getFieldsResult) {
92915c55 538 $isCustom = function ($key) {
6b59896e
TO
539 return preg_match('/^custom_/', $key);
540 };
f8a3cd29
TO
541 $r = array_values(array_filter(array_keys($getFieldsResult['values']), $isCustom));
542 sort($r);
543 return $r;
6b59896e 544 }
96025800 545
6a488035 546}