Merge branch 4.5 into master
[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 return $params;
182 }
183
184 /**
185 * @param int $gid
186 * @param $htype
187 * @param $dtype
188 *
189 * @return array
190 */
191 public function _buildBasicParams($gid, $htype, $dtype) {
192 return array(
193 'custom_group_id' => $gid,
194 'label' => $dtype . $htype,
195 'html_type' => $htype,
196 'data_type' => $dtype,
197 'weight' => 4,
198 'is_required' => 0,
199 'is_searchable' => 0,
200 'is_active' => 1,
201
202 );
203 }
204
205 /**
206 * Test using example code
207 */
208 /*function testCustomFieldCreateExample( )
209 {
210
211
212 $customGroup = $this->customGroupCreate('Individual','date_test_group',3);
213 require_once 'api/v3/examples/CustomField/Create.php';
214 $result = custom_field_create_example();
215 $expectedResult = custom_field_create_expectedresult();
216 $this->assertEquals($result,$expectedResult);
217 }*/
218
219 /**
220 * Check with data type - Options with option_values
221 */
222 public function testCustomFieldCreateWithEmptyOptionGroup() {
223 $customGroup = $this->customGroupCreate(array('extends' => 'Contact', 'title' => 'select_test_group'));
224 $params = array(
225 'custom_group_id' => $customGroup['id'],
226 'label' => 'Country',
227 'html_type' => 'Select',
228 'data_type' => 'String',
229 'weight' => 4,
230 'is_required' => 1,
231 'is_searchable' => 0,
232 'is_active' => 1,
233 );
234
235 $customField = $this->callAPISuccess('custom_field', 'create', $params);
236 $this->assertNotNull($customField['id']);
237 $optionGroupID = $this->callAPISuccess('custom_field', 'getvalue', array(
238 'id' => $customField['id'],
239 'return' => 'option_group_id',
240 ));
241
242 $this->assertTrue(is_numeric($optionGroupID) && ($optionGroupID > 0));
243 $optionGroup = $this->callAPISuccess('option_group', 'getsingle', array(
244 'id' => $optionGroupID));
245 $this->assertEquals($optionGroup['title'], 'Country');
246 $optionValueCount = $this->callAPISuccess('option_value', 'getcount', array(
247 'option_group_id' => $optionGroupID));
248 $this->assertEquals(0, $optionValueCount);
249 }
250
251 /**
252 * Test custom field with existing option group
253 */
254 public function testCustomFieldExistingOptionGroup() {
255 $customGroup = $this->customGroupCreate(array('extends' => 'Organization', 'title' => 'test_group'));
256 $params = array(
257 'custom_group_id' => $customGroup['id'],
258 // Just to say something:
259 'label' => 'Organization Gender',
260 'html_type' => 'Select',
261 'data_type' => 'Int',
262 'weight' => 4,
263 'is_required' => 1,
264 'is_searchable' => 0,
265 'is_active' => 1,
266 // Option group id 3: gender
267 'option_group_id' => 3,
268 );
269
270 $customField = $this->callAPISuccess('custom_field', 'create', $params);
271 $this->assertNotNull($customField['id']);
272 $optionGroupID = $this->callAPISuccess('custom_field', 'getvalue', array(
273 'id' => $customField['id'],
274 'return' => 'option_group_id',
275 ));
276
277 $this->assertEquals($optionGroupID, 3);
278 }
279
280
281 /**
282 * Test custom field get works & return param works
283 */
284 public function testCustomFieldGetReturnOptions() {
285 $customGroup = $this->customGroupCreate(array('extends' => 'Individual', 'title' => 'test_group'));
286 $customField = $this->customFieldCreate(array('custom_group_id' => $customGroup['id']));
287
288 $result = $this->callAPISuccess('custom_field', 'getsingle', array(
289 'id' => $customField['id'],
290 'return' => 'data_type',
291 ));
292 $this->assertTrue(array_key_exists('data_type', $result));
293 $this->assertFalse(array_key_exists('custom_group_id', $result));
294 }
295
296 /**
297 * Test custom field get works & return param works
298 */
299 public function testCustomFieldGetReturnArray() {
300 $customGroup = $this->customGroupCreate(array('extends' => 'Individual', 'title' => 'test_group'));
301 $customField = $this->customFieldCreate(array('custom_group_id' => $customGroup['id']));
302
303 $result = $this->callAPISuccess('custom_field', 'getsingle', array(
304 'id' => $customField['id'],
305 'return' => array('data_type'),
306 ));
307 $this->assertTrue(array_key_exists('data_type', $result));
308 $this->assertFalse(array_key_exists('custom_group_id', $result));
309 }
310
311 /**
312 * Test custom field get works & return param works
313 */
314 public function testCustomFieldGetReturnTwoOptions() {
315 $customGroup = $this->customGroupCreate(array('extends' => 'Individual', 'test_group'));
316 $customField = $this->customFieldCreate(array('custom_group_id' => $customGroup['id']));
317
318 $result = $this->callAPISuccess('custom_field', 'getsingle', array(
319 'id' => $customField['id'],
320 'return' => 'data_type, custom_group_id',
321 ));
322 $this->assertTrue(array_key_exists('data_type', $result));
323 $this->assertTrue(array_key_exists('custom_group_id', $result));
324 $this->assertFalse(array_key_exists('label', $result));
325 }
326
327 public function testCustomFieldCreateWithOptionValues() {
328 $customGroup = $this->customGroupCreate(array('extends' => 'Contact', 'title' => 'select_test_group'));
329
330 $option_values = array(
331 array(
332 'weight' => 1,
333 'label' => 'Label1',
334 'value' => 1,
335 'is_active' => 1,
336 ),
337 array(
338 'weight' => 2,
339 'label' => 'Label2',
340 'value' => 2,
341 'is_active' => 1,
342 ),
343 );
344
345 $params = array(
346 'custom_group_id' => $customGroup['id'],
347 'label' => 'Our special field',
348 'html_type' => 'Select',
349 'data_type' => 'String',
350 'weight' => 4,
351 'is_required' => 1,
352 'is_searchable' => 0,
353 'is_active' => 1,
354 'option_values' => $option_values,
355
356 );
357
358 $customField = $this->callAPISuccess('custom_field', 'create', $params);
359
360 $this->assertAPISuccess($customField);
361 $this->assertNotNull($customField['id']);
362 $getFieldsParams = array(
363 'options' => array('get_options' => 'custom_' . $customField['id']),
364 'action' => 'create',
365 );
366 $description = "Demonstrate retrieving metadata with custom field options";
367 $subfile = "GetFieldsOptions";
368 $fields = $this->callAPIAndDocument('contact', 'getfields', $getFieldsParams, __FUNCTION__, 'ContactTest.php', $description, $subfile, 'GetFields');
369 $this->assertArrayHasKey('options', $fields['values']['custom_' . $customField['id']]);
370 $this->assertEquals('Label1', $fields['values']['custom_' . $customField['id']]['options'][1]);
371 $getOptionsArray = array(
372 'field' => 'custom_' . $customField['id'],
373 );
374 $description = "Demonstrates retrieving options for a custom field";
375 $subfile = "GetOptions";
376 $result = $this->callAPIAndDocument('contact', 'getoptions', $getOptionsArray, __FUNCTION__, 'ContactTest.php', $description, '', 'getoptions');
377 $this->assertEquals('Label1', $result['values'][1]);
378 }
379
380 ///////////////// civicrm_custom_field_delete methods
381
382 /**
383 * Check with no array
384 */
385 public function testCustomFieldDeleteNoArray() {
386 $params = NULL;
387 $customField = $this->callAPIFailure('custom_field', 'delete', $params);
388 $this->assertEquals($customField['error_message'], 'Input variable `params` is not an array');
389 }
390
391 /**
392 * Check without Field ID
393 */
394 public function testCustomFieldDeleteWithoutFieldID() {
395 $params = array();
396 $customField = $this->callAPIFailure('custom_field', 'delete', $params,
397 'Mandatory key(s) missing from params array: id');
398 }
399
400 /**
401 * Check without valid array
402 */
403 public function testCustomFieldDelete() {
404 $customGroup = $this->customGroupCreate(array('extends' => 'Individual', 'title' => 'test_group'));
405 $customField = $this->customFieldCreate(array('custom_group_id' => $customGroup['id']));
406 $this->assertNotNull($customField['id'], 'in line ' . __LINE__);
407
408 $params = array(
409 'id' => $customField['id'],
410 );
411 $result = $this->callAPIAndDocument('custom_field', 'delete', $params, __FUNCTION__, __FILE__);
412
413 $this->assertAPISuccess($result, 'in line ' . __LINE__);
414 }
415
416 /**
417 * Check for Option Value
418 */
419 public function testCustomFieldOptionValueDelete() {
420 $customGroup = $this->customGroupCreate(array('extends' => 'Contact', 'title' => 'ABC'));
421 $customOptionValueFields = $this->customFieldOptionValueCreate($customGroup, 'fieldABC');
422 $params = array(
423 'id' => $customOptionValueFields,
424 );
425
426 $customField = $this->callAPISuccess('custom_field', 'delete', $customOptionValueFields);
427 }
428
429 /**
430 * If there's one custom group for "Contact" and one for "Activity", then "Contact.getfields"
431 * and "Activity.getfields" should return only their respective fields (not the other's fields),
432 * and unrelated entities should return no custom fields.
433 */
434 public function testGetfields_CrossEntityPollution() {
435 $auxEntities = array('Email', 'Address', 'LocBlock', 'Membership', 'ContributionPage', 'ReportInstance');
436 $allEntities = array_merge(array('Contact', 'Activity'), $auxEntities);
437
438 // Baseline - getfields doesn't reporting any customfields for any entities
439 foreach ($allEntities as $entity) {
440 $this->assertEquals(
441 array(),
442 $this->getCustomFieldKeys($this->callAPISuccess($entity, 'getfields', array())),
443 "Baseline custom fields for $entity should be empty"
444 );
445 }
446
447 // Add some fields
448 $contactGroup = $this->customGroupCreate(array('extends' => 'Contact', 'title' => 'test_group_c'));
449 $contactField = $this->customFieldCreate(array('custom_group_id' => $contactGroup['id'], 'label' => 'For Contacts'));
450 $indivGroup = $this->customGroupCreate(array('extends' => 'Individual', 'title' => 'test_group_i'));
451 $indivField = $this->customFieldCreate(array('custom_group_id' => $indivGroup['id'], 'label' => 'For Individuals'));
452 $activityGroup = $this->customGroupCreate(array('extends' => 'Activity', 'title' => 'test_group_a'));
453 $activityField = $this->customFieldCreate(array('custom_group_id' => $activityGroup['id'], 'label' => 'For Activities'));
454
455 // Check getfields
456 $this->assertEquals(
457 array('custom_' . $contactField['id'], 'custom_' . $indivField['id']),
458 $this->getCustomFieldKeys($this->callAPISuccess('Contact', 'getfields', array())),
459 'Contact custom fields'
460 );
461 $this->assertEquals(
462 array('custom_' . $contactField['id'], 'custom_' . $indivField['id']),
463 $this->getCustomFieldKeys($this->callAPISuccess('Individual', 'getfields', array())),
464 'Individual custom fields'
465 );
466 $this->assertEquals(
467 array('custom_' . $contactField['id']),
468 $this->getCustomFieldKeys($this->callAPISuccess('Organization', 'getfields', array())),
469 'Organization custom fields'
470 );
471 $this->assertEquals(
472 array('custom_' . $activityField['id']),
473 $this->getCustomFieldKeys($this->callAPISuccess('Activity', 'getfields', array())),
474 'Activity custom fields'
475 );
476 foreach ($auxEntities as $entity) {
477 $this->assertEquals(
478 array(),
479 $this->getCustomFieldKeys($this->callAPISuccess($entity, 'getfields', array())),
480 "Custom fields for $entity should be empty"
481 );
482 }
483 }
484
485 /**
486 * @param $getFieldsResult
487 *
488 * @return array
489 */
490 public function getCustomFieldKeys($getFieldsResult) {
491 $isCustom = function($key) {
492 return preg_match('/^custom_/', $key);
493 };
494 $r = array_values(array_filter(array_keys($getFieldsResult['values']), $isCustom));
495 sort($r);
496 return $r;
497 }
498 }