3 * +--------------------------------------------------------------------+
4 * | CiviCRM version 4.7 |
5 * +--------------------------------------------------------------------+
6 * | Copyright CiviCRM LLC (c) 2004-2015 |
7 * +--------------------------------------------------------------------+
8 * | This file is a part of CiviCRM. |
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. |
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. |
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 * +--------------------------------------------------------------------+
28 require_once 'CiviTest/CiviUnitTestCase.php';
31 * Class api_v3_CustomValueTest
33 class api_v3_CustomValueTest
extends CiviUnitTestCase
{
34 protected $_apiversion = 3;
36 protected $optionGroup;
38 public $DBResetRequired = FALSE;
40 public function setUp() {
44 public function _populateOptionAndCustomGroup($type = NULL) {
46 'integer' => array(1, 2, 3),
47 'number' => array(10.11, 20.22, 30.33),
48 'string' => array(substr(sha1(rand()), 0, 4), substr(sha1(rand()), 0, 3), substr(sha1(rand()), 0, 2)),
49 //'country' => array_rand(CRM_Core_PseudoConstant::country(FALSE, FALSE), 3),
50 'state_province' => array_rand(CRM_Core_PseudoConstant
::stateProvince(FALSE, FALSE), 3),
55 $dataValues = !empty($type) ?
array($type => $dataValues[$type]) : $dataValues;
57 foreach ($dataValues as $dataType => $values) {
58 $this->optionGroup
[$dataType] = array('values' => $values);
59 if (!empty($values)) {
60 $result = $this->callAPISuccess('OptionGroup', 'create',
62 'name' => "{$dataType}_group",
63 'api.option_value.create' => array('label' => "$dataType 1", 'value' => $values[0]),
64 'api.option_value.create.1' => array('label' => "$dataType 2", 'value' => $values[1]),
65 'api.option_value.create.2' => array('label' => "$dataType 3", 'value' => $values[2]),
68 $this->optionGroup
[$dataType]['id'] = $result['id'];
70 elseif ($dataType == 'contact') {
71 for ($i = 0; $i < 3; $i++
) {
72 $result = $this->callAPISuccess('Contact', 'create', array('contact_type' => 'Individual', 'email' => substr(sha1(rand()), 0, 7) . '@yahoo.com'));
73 $this->optionGroup
[$dataType]['values'][$i] = $result['id'];
76 $this->ids
[$dataType] = $this->entityCustomGroupWithSingleFieldCreate("$dataType Custom Group", 'Contacts');
81 public function tearDown() {
82 $tablesToTruncate = array(
84 'civicrm_custom_field',
85 'civicrm_custom_group',
89 // true tells quickCleanup to drop any tables that might have been created in the test
90 $this->quickCleanup($tablesToTruncate, TRUE);
92 // cleanup created option group for each custom-set before running next test
93 if (!empty($this->optionGroup
)) {
94 foreach ($this->optionGroup
as $type => $value) {
95 if (!empty($value['id'])) {
96 $this->callAPISuccess('OptionGroup', 'delete', array('id' => $value['id']));
102 public function testCreateCustomValue() {
103 $this->_populateOptionAndCustomGroup();
105 $customFieldDataType = CRM_Core_BAO_CustomField
::dataType();
106 $dataToHtmlTypes = CRM_Core_BAO_CustomField
::dataToHtml();
109 foreach ($customFieldDataType as $dataType => $label) {
112 case 'StateProvince';
118 if (in_array($dataType, array('String', 'Link'))) {
119 $validSQLOperator = array('=', '!=', 'IN', 'NOT IN', 'LIKE', 'NOT LIKE', 'IS NOT NULL', 'IS NULL');
123 if ($dataType == 'StateProvince') {
124 $type = 'state_province';
126 elseif ($dataType == 'ContactReference') {
129 elseif ($dataType == 'Date') {
133 $type = $dataType == 'Int' ?
'integer' : 'number';
135 $validSQLOperator = array('=', '!=', 'IN', 'NOT IN', '<=', '>=', '>', '<', 'IS NOT NULL', 'IS NULL');
138 foreach ($dataToHtmlTypes[$count] as $html) {
140 'custom_group_id' => $this->ids
[$type]['custom_group_id'],
141 'label' => "$dataType - $html",
142 'data_type' => $dataType,
143 'html_type' => $html,
144 'default_value' => NULL,
146 if (!in_array($html, array('Text', 'TextArea')) && !in_array($dataType, array('Link', 'Date', 'ContactReference'))) {
147 $params +
= array('option_group_id' => $this->optionGroup
[$type]['id']);
149 $customField = $this->customFieldCreate($params);
150 $this->_testCustomValue($customField['values'][$customField['id']], $validSQLOperator, $type);
156 //TODO: Test case of Country fields remain as it throws foreign key contraint ONLY in test environment
163 public function _testCustomValue($customField, $sqlOps, $type) {
164 $isSerialized = CRM_Core_BAO_CustomField
::isSerialized($customField);
165 $customId = $customField['id'];
167 'contact_type' => 'Individual',
168 'email' => substr(sha1(rand()), 0, 7) . 'man1@yahoo.com',
170 $result = $this->callAPISuccess('Contact', 'create', $params);
171 $contactId = $result['id'];
174 $seperator = CRM_Core_DAO
::VALUE_SEPARATOR
;
176 $selectedValue = $this->optionGroup
[$type]['values'];
177 $notselectedValue = $selectedValue[$count];
178 unset($selectedValue[$count]);
180 elseif ($customField['html_type'] == 'Link') {
181 $selectedValue = "http://" . substr(sha1(rand()), 0, 7) . ".com";
182 $notselectedValue = "http://" . substr(sha1(rand()), 0, 7) . ".com";
184 elseif ($type == 'date') {
185 $selectedValue = date('Ymd');
186 $notselectedValue = $lesserSelectedValue = date('Ymd', strtotime('yesterday'));
187 $greaterSelectedValue = date('Ymd', strtotime('+ 1 day'));
189 elseif ($type == 'contact') {
190 $selectedValue = $this->optionGroup
[$type]['values'][1];
191 $notselectedValue = $this->optionGroup
[$type]['values'][0];
194 $selectedValue = $this->optionGroup
[$type]['values'][0];
195 $notselectedValue = $this->optionGroup
[$type]['values'][$count];
196 if (in_array(">", $sqlOps)) {
197 $greaterSelectedValue = $selectedValue +
1;
198 $lesserSelectedValue = $selectedValue - 1;
202 $params = array('entity_id' => $contactId, 'custom_' . $customId => $selectedValue);
203 $this->callAPISuccess('CustomValue', 'create', $params);
205 foreach ($sqlOps as $op) {
206 $qillOp = CRM_Utils_Array
::value($op, CRM_Core_SelectValues
::getSearchBuilderOperators(), $op);
207 $description = "\nFind Contact where '$customField[label]' $qillOp ";
210 $result = $this->callAPISuccess('Contact', 'Get', array('custom_' . $customId => (is_array($selectedValue) ?
implode(CRM_Core_DAO
::VALUE_SEPARATOR
, $selectedValue) : $selectedValue)));
211 $this->assertEquals($contactId, $result['id']);
212 echo $description . implode("[separator]", (array) $selectedValue);
216 $result = $this->callAPISuccess('Contact', 'Get', array('custom_' . $customId => array($op => $notselectedValue)));
217 $this->assertEquals(TRUE, array_key_exists($contactId, $result['values']));
218 echo $description . $notselectedValue;
228 // To be precise in for these operator we can't just rely on one contact,
229 // hence creating multiple contact with custom value less/more then $selectedValue respectively
230 $result = $this->callAPISuccess('Contact', 'create', array('contact_type' => 'Individual', 'email' => substr(sha1(rand()), 0, 7) . 'man2@yahoo.com'));
231 $contactId2 = $result['id'];
232 $this->callAPISuccess('CustomValue', 'create', array('entity_id' => $contactId2, 'custom_' . $customId => $lesserSelectedValue));
235 $result = $this->callAPISuccess('Contact', 'Get', array('custom_' . $customId => array($op => $lesserSelectedValue)));
236 $this->assertEquals($contactId, $result['id']);
237 echo $description . $lesserSelectedValue;
239 elseif ($op == '<') {
240 $result = $this->callAPISuccess('Contact', 'Get', array('custom_' . $customId => array($op => $selectedValue)));
241 $this->assertEquals($contactId2, $result['id']);
242 echo $description . $selectedValue;
245 $result = $this->callAPISuccess('Contact', 'create', array('contact_type' => 'Individual', 'email' => substr(sha1(rand()), 0, 7) . 'man3@yahoo.com'));
246 $contactId3 = $result['id'];
247 $this->callAPISuccess('CustomValue', 'create', array('entity_id' => $contactId3, 'custom_' . $customId => $greaterSelectedValue));
249 $result = $this->callAPISuccess('Contact', 'Get', array('custom_' . $customId => array($op => $selectedValue)));
250 echo $description . $selectedValue;
252 $this->assertEquals($contactId, $result['values'][$contactId]['id']);
254 $this->assertEquals($contactId3, $result['values'][$contactId3]['id']);
257 $this->assertEquals($contactId2, $result['values'][$contactId2]['id']);
259 $this->callAPISuccess('contact', 'delete', array('id' => $contactId3));
262 $this->callAPISuccess('contact', 'delete', array('id' => $contactId2));
266 $result = $this->callAPISuccess('Contact', 'Get', array('custom_' . $customId => array($op => (array) $selectedValue)));
267 $this->assertEquals($contactId, $result['id']);
268 echo $description . implode(",", (array) $selectedValue);
272 $result = $this->callAPISuccess('Contact', 'Get', array('custom_' . $customId => array($op => (array) $notselectedValue)));
273 $this->assertEquals($contactId, $result['id']);
274 echo $description . implode(",", (array) $notselectedValue);
278 $selectedValue = is_array($selectedValue) ?
$selectedValue[0] : $selectedValue;
279 $result = $this->callAPISuccess('Contact', 'Get', array('custom_' . $customId => array($op => "%$selectedValue%")));
280 $this->assertEquals($contactId, $result['id']);
281 echo $description . "%$selectedValue%";
285 $result = $this->callAPISuccess('Contact', 'Get', array('custom_' . $customId => array($op => $notselectedValue)));
286 $this->assertEquals($contactId, $result['id']);
287 echo $description . "'$notselectedValue'";
291 $result = $this->callAPISuccess('Contact', 'Get', array('custom_' . $customId => array($op => 1)));
292 $this->assertEquals(FALSE, array_key_exists($contactId, $result['values']));
297 $result = $this->callAPISuccess('Contact', 'Get', array('custom_' . $customId => array($op => 1)));
298 $this->assertEquals($contactId, $result['id']);
304 $this->callAPISuccess('Contact', 'delete', array('id' => $contactId));
308 * Ensure custom data is updated when option values are modified
310 * @link https://issues.civicrm.org/jira/browse/CRM-11856
312 * @throws \CiviCRM_API3_Exception
314 public function testAlterOptionValue() {
315 $this->_populateOptionAndCustomGroup('string');
317 $selectField = $this->customFieldCreate(array(
318 'custom_group_id' => $this->ids
['string']['custom_group_id'],
319 'label' => 'Custom Select',
320 'html_type' => 'Select',
321 'option_group_id' => $this->optionGroup
['string']['id'],
323 $selectField = civicrm_api3('customField', 'getsingle', array('id' => $selectField['id']));
324 $radioField = $this->customFieldCreate(array(
325 'custom_group_id' => $this->ids
['string']['custom_group_id'],
326 'label' => 'Custom Radio',
327 'html_type' => 'Radio',
328 'option_group_id' => $selectField['option_group_id'],
330 $multiSelectField = $this->customFieldCreate(array(
331 'custom_group_id' => $this->ids
['string']['custom_group_id'],
332 'label' => 'Custom Multi-Select',
333 'html_type' => 'Multi-Select',
334 'option_group_id' => $selectField['option_group_id'],
336 $selectName = 'custom_' . $selectField['id'];
337 $radioName = 'custom_' . $radioField['id'];
338 $multiSelectName = 'custom_' . $multiSelectField['id'];
339 $controlFieldName = 'custom_' . $this->ids
['string']['custom_field_id'];
342 'first_name' => 'abc4',
343 'last_name' => 'xyz4',
344 'contact_type' => 'Individual',
345 'email' => 'man4@yahoo.com',
346 $selectName => $this->optionGroup
['string']['values'][0],
347 $multiSelectName => $this->optionGroup
['string']['values'],
348 $radioName => $this->optionGroup
['string']['values'][1],
349 // The control group in a science experiment should be unaffected
350 $controlFieldName => $this->optionGroup
['string']['values'][2],
353 $contact = $this->callAPISuccess('Contact', 'create', $params);
355 $result = $this->callAPISuccess('Contact', 'getsingle', array(
356 'id' => $contact['id'],
357 'return' => array($selectName, $multiSelectName),
359 $this->assertEquals($params[$selectName], $result[$selectName]);
360 $this->assertEquals($params[$multiSelectName], $result[$multiSelectName]);
362 $this->callAPISuccess('OptionValue', 'create', array(
363 'value' => 'one-modified',
364 'option_group_id' => $selectField['option_group_id'],
365 'name' => 'string 1',
367 'match-mandatory' => array('option_group_id', 'name'),
371 $result = $this->callAPISuccess('Contact', 'getsingle', array(
372 'id' => $contact['id'],
373 'return' => array($selectName, $multiSelectName, $controlFieldName, $radioName),
375 // Ensure the relevant fields have been updated
376 $this->assertEquals('one-modified', $result[$selectName]);
377 $this->assertEquals(array('one-modified', $params[$radioName], $params[$controlFieldName]), $result[$multiSelectName]);
378 // This field should not have changed because we didn't alter this option
379 $this->assertEquals($params[$radioName], $result[$radioName]);
380 // This should not have changed because this field doesn't use the affected option group
381 $this->assertEquals($params[$controlFieldName], $result[$controlFieldName]);