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