Merge pull request #4944 from civicrm/batch-5.part2
[civicrm-core.git] / tests / phpunit / api / v3 / CustomFieldTest.php
CommitLineData
6a488035 1<?php
b6708aeb 2/*
3 +--------------------------------------------------------------------+
39de6fd5 4| CiviCRM version 4.6 |
b6708aeb 5+--------------------------------------------------------------------+
06a1bc01 6| Copyright CiviCRM LLC (c) 2004-2014 |
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+--------------------------------------------------------------------+
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(
92915c55
TO
49 'civicrm_custom_group',
50 'civicrm_custom_field',
6a488035
TO
51 );
52 // true tells quickCleanup to drop any tables that might have been created in the test
53 $this->quickCleanup($tablesToTruncate, TRUE);
54 }
55
56 /**
100fef9d 57 * Check with no array
6a488035 58 */
00be9182 59 public function testCustomFieldCreateNoArray() {
6a488035
TO
60 $fieldParams = NULL;
61
d0e1eff2 62 $customField = $this->callAPIFailure('custom_field', 'create', $fieldParams);
6a488035
TO
63 $this->assertEquals($customField['error_message'], 'Input variable `params` is not an array');
64 }
65
66 /**
100fef9d 67 * Check with no label
6a488035 68 */
00be9182 69 public function testCustomFieldCreateWithoutLabel() {
e830c6ae 70 $customGroup = $this->customGroupCreate(array('extends' => 'Individual', 'title' => 'text_test_group'));
6a488035
TO
71 $params = array(
72 'custom_group_id' => $customGroup['id'],
73 'name' => 'test_textfield2',
74 'html_type' => 'Text',
75 'data_type' => 'String',
76 'default_value' => 'abc',
77 'weight' => 4,
78 'is_required' => 1,
79 'is_searchable' => 0,
80 'is_active' => 1,
6a488035
TO
81 );
82
d0e1eff2 83 $customField = $this->callAPIFailure('custom_field', 'create', $params);
6a488035
TO
84 $this->assertEquals($customField['error_message'], 'Mandatory key(s) missing from params array: label');
85 }
86
87 /**
100fef9d 88 * Check with edit
6a488035 89 */
00be9182 90 public function testCustomFieldCreateWithEdit() {
e830c6ae 91 $customGroup = $this->customGroupCreate(array('extends' => 'Individual', 'title' => 'text_test_group'));
6a488035
TO
92 $params = array(
93 'custom_group_id' => $customGroup['id'],
94 'name' => 'test_textfield2',
95 'label' => 'Name1',
96 'html_type' => 'Text',
97 'data_type' => 'String',
98 'default_value' => 'abc',
99 'weight' => 4,
100 'is_required' => 1,
101 'is_searchable' => 0,
102 'is_active' => 1,
6a488035
TO
103 );
104
92915c55 105 $customField = $this->callAPIAndDocument('custom_field', 'create', $params, __FUNCTION__, __FILE__);
6a488035 106 $params['id'] = $customField['id'];
92915c55 107 $customField = $this->callAPISuccess('custom_field', 'create', $params);
6a488035 108
6a488035
TO
109 $this->assertNotNull($customField['id'], 'in line ' . __LINE__);
110 }
111
112 /**
100fef9d 113 * Check without groupId
6a488035 114 */
00be9182 115 public function testCustomFieldCreateWithoutGroupID() {
6a488035
TO
116 $fieldParams = array(
117 'name' => 'test_textfield1',
118 'label' => 'Name',
119 'html_type' => 'Text',
120 'data_type' => 'String',
121 'default_value' => 'abc',
122 'weight' => 4,
123 'is_required' => 1,
124 'is_searchable' => 0,
125 'is_active' => 1,
e830c6ae 126
6a488035
TO
127 );
128
d0e1eff2 129 $customField = $this->callAPIFailure('custom_field', 'create', $fieldParams);
6a488035
TO
130 $this->assertEquals($customField['error_message'], 'Mandatory key(s) missing from params array: custom_group_id');
131 }
132
133 /**
134 * Check for Each data type: loop through available form input types
ae5ffbb7 135 */
00be9182 136 public function testCustomFieldCreateAllAvailableFormInputs() {
e830c6ae 137 $gid = $this->customGroupCreate(array('extends' => 'Individual', 'title' => 'testAllFormInputs'));
6a488035
TO
138
139 $dtype = CRM_Core_BAO_CustomField::dataType();
140 $htype = CRM_Core_BAO_CustomField::dataToHtml();
141
142 $n = 0;
143 foreach ($dtype as $dkey => $dvalue) {
144 foreach ($htype[$n] as $hkey => $hvalue) {
145 //echo $dkey."][".$hvalue."\n";
146 $this->_loopingCustomFieldCreateTest($this->_buildParams($gid['id'], $hvalue, $dkey));
147 }
148 $n++;
149 }
150 }
6c6e6187
TO
151 /*
152 * Can't figure out the point of this?
153 */
4cbe18b8 154 /**
c490a46a 155 * @param array $params
4cbe18b8 156 */
00be9182 157 public function _loopingCustomFieldCreateTest($params) {
e830c6ae 158 $customField = $this->callAPISuccess('custom_field', 'create', $params);
6a488035
TO
159 $this->assertNotNull($customField['id']);
160 $this->getAndCheck($params, $customField['id'], 'CustomField');
161 }
162
4cbe18b8 163 /**
100fef9d 164 * @param int $gid
4cbe18b8
EM
165 * @param $htype
166 * @param $dtype
167 *
168 * @return array
169 */
00be9182 170 public function _buildParams($gid, $htype, $dtype) {
6a488035
TO
171 $params = $this->_buildBasicParams($gid, $htype, $dtype);
172 /* //Not Working for any type. Maybe redundant with testCustomFieldCreateWithOptionValues()
173 if ($htype == 'Multi-Select')
174 $params = array_merge($params, array(
175 'option_label' => array( 'Label1','Label2'),
176 'option_value' => array( 'val1', 'val2' ),
177 'option_weight' => array( 1, 2),
178 'option_status' => array( 1, 1),
179 ));
6c6e6187 180 */
6a488035
TO
181
182 return $params;
183 }
184
4cbe18b8 185 /**
100fef9d 186 * @param int $gid
4cbe18b8
EM
187 * @param $htype
188 * @param $dtype
189 *
190 * @return array
191 */
00be9182 192 public function _buildBasicParams($gid, $htype, $dtype) {
6a488035
TO
193 return array(
194 'custom_group_id' => $gid,
195 'label' => $dtype . $htype,
196 'html_type' => $htype,
197 'data_type' => $dtype,
198 'weight' => 4,
199 'is_required' => 0,
200 'is_searchable' => 0,
201 'is_active' => 1,
e830c6ae 202
6a488035
TO
203 );
204 }
205
206 /**
207 * Test using example code
208 */
209 /*function testCustomFieldCreateExample( )
210 {
211
212
213 $customGroup = $this->customGroupCreate('Individual','date_test_group',3);
3ec6e38d 214 require_once 'api/v3/examples/CustomField/Create.php';
6a488035
TO
215 $result = custom_field_create_example();
216 $expectedResult = custom_field_create_expectedresult();
217 $this->assertEquals($result,$expectedResult);
218 }*/
219
220 /**
100fef9d 221 * Check with data type - Options with option_values
6a488035 222 */
00be9182 223 public function testCustomFieldCreateWithEmptyOptionGroup() {
e830c6ae 224 $customGroup = $this->customGroupCreate(array('extends' => 'Contact', 'title' => 'select_test_group'));
b958933f 225 $params = array(
226 'custom_group_id' => $customGroup['id'],
227 'label' => 'Country',
228 'html_type' => 'Select',
229 'data_type' => 'String',
230 'weight' => 4,
231 'is_required' => 1,
232 'is_searchable' => 0,
233 'is_active' => 1,
b958933f 234 );
235
e830c6ae 236 $customField = $this->callAPISuccess('custom_field', 'create', $params);
b958933f 237 $this->assertNotNull($customField['id']);
e830c6ae 238 $optionGroupID = $this->callAPISuccess('custom_field', 'getvalue', array(
b958933f 239 'id' => $customField['id'],
240 'return' => 'option_group_id',
241 ));
242
243 $this->assertTrue(is_numeric($optionGroupID) && ($optionGroupID > 0));
e830c6ae 244 $optionGroup = $this->callAPISuccess('option_group', 'getsingle', array(
ae5ffbb7 245 'id' => $optionGroupID,
92915c55 246 ));
6c6e6187 247 $this->assertEquals($optionGroup['title'], 'Country');
e830c6ae 248 $optionValueCount = $this->callAPISuccess('option_value', 'getcount', array(
ae5ffbb7 249 'option_group_id' => $optionGroupID,
92915c55 250 ));
b958933f 251 $this->assertEquals(0, $optionValueCount);
252 }
253
eebb53df
JV
254 /**
255 * Test custom field with existing option group
256 */
00be9182 257 public function testCustomFieldExistingOptionGroup() {
eebb53df
JV
258 $customGroup = $this->customGroupCreate(array('extends' => 'Organization', 'title' => 'test_group'));
259 $params = array(
260 'custom_group_id' => $customGroup['id'],
261 // Just to say something:
262 'label' => 'Organization Gender',
263 'html_type' => 'Select',
264 'data_type' => 'Int',
265 'weight' => 4,
266 'is_required' => 1,
267 'is_searchable' => 0,
268 'is_active' => 1,
269 // Option group id 3: gender
270 'option_group_id' => 3,
271 );
272
273 $customField = $this->callAPISuccess('custom_field', 'create', $params);
274 $this->assertNotNull($customField['id']);
275 $optionGroupID = $this->callAPISuccess('custom_field', 'getvalue', array(
276 'id' => $customField['id'],
277 'return' => 'option_group_id',
278 ));
279
6c6e6187 280 $this->assertEquals($optionGroupID, 3);
eebb53df
JV
281 }
282
b958933f 283
3c70d501 284 /**
285 * Test custom field get works & return param works
286 */
9b873358 287 public function testCustomFieldGetReturnOptions() {
e830c6ae 288 $customGroup = $this->customGroupCreate(array('extends' => 'Individual', 'title' => 'test_group'));
b422b715 289 $customField = $this->customFieldCreate(array('custom_group_id' => $customGroup['id']));
3c70d501 290
e830c6ae 291 $result = $this->callAPISuccess('custom_field', 'getsingle', array(
3c70d501 292 'id' => $customField['id'],
293 'return' => 'data_type',
294 ));
295 $this->assertTrue(array_key_exists('data_type', $result));
296 $this->assertFalse(array_key_exists('custom_group_id', $result));
297 }
298
299 /**
300 * Test custom field get works & return param works
301 */
9b873358 302 public function testCustomFieldGetReturnArray() {
e830c6ae 303 $customGroup = $this->customGroupCreate(array('extends' => 'Individual', 'title' => 'test_group'));
b422b715 304 $customField = $this->customFieldCreate(array('custom_group_id' => $customGroup['id']));
3c70d501 305
e830c6ae 306 $result = $this->callAPISuccess('custom_field', 'getsingle', array(
92915c55 307 'id' => $customField['id'],
3c70d501 308 'return' => array('data_type'),
309 ));
310 $this->assertTrue(array_key_exists('data_type', $result));
311 $this->assertFalse(array_key_exists('custom_group_id', $result));
312 }
313
314 /**
315 * Test custom field get works & return param works
316 */
9b873358 317 public function testCustomFieldGetReturnTwoOptions() {
e830c6ae 318 $customGroup = $this->customGroupCreate(array('extends' => 'Individual', 'test_group'));
b422b715 319 $customField = $this->customFieldCreate(array('custom_group_id' => $customGroup['id']));
3c70d501 320
e830c6ae 321 $result = $this->callAPISuccess('custom_field', 'getsingle', array(
92915c55 322 'id' => $customField['id'],
3c70d501 323 'return' => 'data_type, custom_group_id',
324 ));
325 $this->assertTrue(array_key_exists('data_type', $result));
326 $this->assertTrue(array_key_exists('custom_group_id', $result));
327 $this->assertFalse(array_key_exists('label', $result));
328 }
329
00be9182 330 public function testCustomFieldCreateWithOptionValues() {
e830c6ae 331 $customGroup = $this->customGroupCreate(array('extends' => 'Contact', 'title' => 'select_test_group'));
6a488035
TO
332
333 $option_values = array(
6c6e6187 334 array(
92915c55 335 'weight' => 1,
6a488035
TO
336 'label' => 'Label1',
337 'value' => 1,
338 'is_active' => 1,
339 ),
340 array(
341 'weight' => 2,
342 'label' => 'Label2',
343 'value' => 2,
344 'is_active' => 1,
345 ),
346 );
347
348 $params = array(
349 'custom_group_id' => $customGroup['id'],
7f6d3dd3 350 'label' => 'Our special field',
6a488035
TO
351 'html_type' => 'Select',
352 'data_type' => 'String',
353 'weight' => 4,
354 'is_required' => 1,
355 'is_searchable' => 0,
356 'is_active' => 1,
357 'option_values' => $option_values,
e830c6ae 358
6a488035
TO
359 );
360
e830c6ae 361 $customField = $this->callAPISuccess('custom_field', 'create', $params);
6a488035 362
b958933f 363 $this->assertAPISuccess($customField);
6a488035
TO
364 $this->assertNotNull($customField['id']);
365 $getFieldsParams = array(
366 'options' => array('get_options' => 'custom_' . $customField['id']),
92915c55 367 'action' => 'create',
6a488035 368 );
92915c55 369 $description = "Demonstrate retrieving metadata with custom field options";
6a488035 370 $subfile = "GetFieldsOptions";
6c6e6187 371 $fields = $this->callAPIAndDocument('contact', 'getfields', $getFieldsParams, __FUNCTION__, 'ContactTest.php', $description, $subfile, 'GetFields');
6a488035
TO
372 $this->assertArrayHasKey('options', $fields['values']['custom_' . $customField['id']]);
373 $this->assertEquals('Label1', $fields['values']['custom_' . $customField['id']]['options'][1]);
374 $getOptionsArray = array(
375 'field' => 'custom_' . $customField['id'],
92915c55 376 );
6a488035
TO
377 $description = "Demonstrates retrieving options for a custom field";
378 $subfile = "GetOptions";
e830c6ae 379 $result = $this->callAPIAndDocument('contact', 'getoptions', $getOptionsArray, __FUNCTION__, 'ContactTest.php', $description, '', 'getoptions');
6a488035 380 $this->assertEquals('Label1', $result['values'][1]);
6a488035
TO
381 }
382
383 ///////////////// civicrm_custom_field_delete methods
384
385 /**
100fef9d 386 * Check with no array
6a488035 387 */
00be9182 388 public function testCustomFieldDeleteNoArray() {
6a488035 389 $params = NULL;
d0e1eff2 390 $customField = $this->callAPIFailure('custom_field', 'delete', $params);
6a488035
TO
391 $this->assertEquals($customField['error_message'], 'Input variable `params` is not an array');
392 }
393
394 /**
100fef9d 395 * Check without Field ID
6a488035 396 */
00be9182 397 public function testCustomFieldDeleteWithoutFieldID() {
e830c6ae 398 $params = array();
399 $customField = $this->callAPIFailure('custom_field', 'delete', $params,
400 'Mandatory key(s) missing from params array: id');
6a488035
TO
401 }
402
403 /**
100fef9d 404 * Check without valid array
6a488035 405 */
00be9182 406 public function testCustomFieldDelete() {
e830c6ae 407 $customGroup = $this->customGroupCreate(array('extends' => 'Individual', 'title' => 'test_group'));
b422b715 408 $customField = $this->customFieldCreate(array('custom_group_id' => $customGroup['id']));
6a488035
TO
409 $this->assertNotNull($customField['id'], 'in line ' . __LINE__);
410
411 $params = array(
6a488035
TO
412 'id' => $customField['id'],
413 );
e830c6ae 414 $result = $this->callAPIAndDocument('custom_field', 'delete', $params, __FUNCTION__, __FILE__);
6a488035 415
791c263c 416 $this->assertAPISuccess($result, 'in line ' . __LINE__);
6a488035
TO
417 }
418
419 /**
100fef9d 420 * Check for Option Value
6a488035 421 */
00be9182 422 public function testCustomFieldOptionValueDelete() {
e830c6ae 423 $customGroup = $this->customGroupCreate(array('extends' => 'Contact', 'title' => 'ABC'));
6a488035 424 $customOptionValueFields = $this->customFieldOptionValueCreate($customGroup, 'fieldABC');
6a488035 425 $params = array(
6a488035
TO
426 'id' => $customOptionValueFields,
427 );
428
e830c6ae 429 $customField = $this->callAPISuccess('custom_field', 'delete', $customOptionValueFields);
6a488035 430 }
6b59896e
TO
431
432 /**
433 * If there's one custom group for "Contact" and one for "Activity", then "Contact.getfields"
434 * and "Activity.getfields" should return only their respective fields (not the other's fields),
435 * and unrelated entities should return no custom fields.
436 */
00be9182 437 public function testGetfields_CrossEntityPollution() {
6b59896e
TO
438 $auxEntities = array('Email', 'Address', 'LocBlock', 'Membership', 'ContributionPage', 'ReportInstance');
439 $allEntities = array_merge(array('Contact', 'Activity'), $auxEntities);
440
441 // Baseline - getfields doesn't reporting any customfields for any entities
442 foreach ($allEntities as $entity) {
443 $this->assertEquals(
444 array(),
445 $this->getCustomFieldKeys($this->callAPISuccess($entity, 'getfields', array())),
446 "Baseline custom fields for $entity should be empty"
447 );
448 }
449
450 // Add some fields
f8a3cd29 451 $contactGroup = $this->customGroupCreate(array('extends' => 'Contact', 'title' => 'test_group_c'));
92915c55
TO
452 $contactField = $this->customFieldCreate(array(
453 'custom_group_id' => $contactGroup['id'],
ae5ffbb7 454 'label' => 'For Contacts',
92915c55 455 ));
f8a3cd29
TO
456 $indivGroup = $this->customGroupCreate(array('extends' => 'Individual', 'title' => 'test_group_i'));
457 $indivField = $this->customFieldCreate(array('custom_group_id' => $indivGroup['id'], 'label' => 'For Individuals'));
458 $activityGroup = $this->customGroupCreate(array('extends' => 'Activity', 'title' => 'test_group_a'));
92915c55
TO
459 $activityField = $this->customFieldCreate(array(
460 'custom_group_id' => $activityGroup['id'],
ae5ffbb7 461 'label' => 'For Activities',
92915c55 462 ));
6b59896e 463
f8a3cd29
TO
464 // Check getfields
465 $this->assertEquals(
466 array('custom_' . $contactField['id'], 'custom_' . $indivField['id']),
467 $this->getCustomFieldKeys($this->callAPISuccess('Contact', 'getfields', array())),
468 'Contact custom fields'
469 );
470 $this->assertEquals(
471 array('custom_' . $contactField['id'], 'custom_' . $indivField['id']),
472 $this->getCustomFieldKeys($this->callAPISuccess('Individual', 'getfields', array())),
473 'Individual custom fields'
474 );
475 $this->assertEquals(
476 array('custom_' . $contactField['id']),
477 $this->getCustomFieldKeys($this->callAPISuccess('Organization', 'getfields', array())),
478 'Organization custom fields'
479 );
6b59896e
TO
480 $this->assertEquals(
481 array('custom_' . $activityField['id']),
482 $this->getCustomFieldKeys($this->callAPISuccess('Activity', 'getfields', array())),
483 'Activity custom fields'
484 );
485 foreach ($auxEntities as $entity) {
486 $this->assertEquals(
487 array(),
488 $this->getCustomFieldKeys($this->callAPISuccess($entity, 'getfields', array())),
489 "Custom fields for $entity should be empty"
490 );
491 }
492 }
493
4cbe18b8
EM
494 /**
495 * @param $getFieldsResult
496 *
497 * @return array
498 */
00be9182 499 public function getCustomFieldKeys($getFieldsResult) {
92915c55 500 $isCustom = function ($key) {
6b59896e
TO
501 return preg_match('/^custom_/', $key);
502 };
f8a3cd29
TO
503 $r = array_values(array_filter(array_keys($getFieldsResult['values']), $isCustom));
504 sort($r);
505 return $r;
6b59896e 506 }
6a488035 507}