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