Commit | Line | Data |
---|---|---|
6a488035 | 1 | <?php |
fc928539 | 2 | /** |
92915c55 | 3 | * +--------------------------------------------------------------------+ |
2fe49090 | 4 | * | CiviCRM version 5 | |
92915c55 | 5 | * +--------------------------------------------------------------------+ |
6b83d5bd | 6 | * | Copyright CiviCRM LLC (c) 2004-2019 | |
92915c55 TO |
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 | * +--------------------------------------------------------------------+ | |
6c6e6187 | 26 | */ |
6a488035 | 27 | |
e9479dcf EM |
28 | /** |
29 | * Class api_v3_CustomValueTest | |
acb109b7 | 30 | * @group headless |
e9479dcf | 31 | */ |
6a488035 | 32 | class api_v3_CustomValueTest extends CiviUnitTestCase { |
6c6e6187 | 33 | protected $_apiversion = 3; |
f9a5aadd | 34 | |
ec28b24d | 35 | protected $optionGroup; |
b7c9bc4c | 36 | |
6a488035 TO |
37 | public $DBResetRequired = FALSE; |
38 | ||
00be9182 | 39 | public function setUp() { |
6a488035 | 40 | parent::setUp(); |
ec28b24d | 41 | } |
42 | ||
6fca1a34 | 43 | public function _populateOptionAndCustomGroup($type = NULL) { |
9099cab3 CW |
44 | $dataValues = [ |
45 | 'integer' => [1, 2, 3], | |
46 | 'number' => [10.11, 20.22, 30.33], | |
47 | 'string' => [substr(sha1(rand()), 0, 4) . '(', substr(sha1(rand()), 0, 3) . '|', substr(sha1(rand()), 0, 2) . ','], | |
f9887f64 | 48 | // 'country' => array_rand(CRM_Core_PseudoConstant::country(FALSE, FALSE), 3), |
49 | // This does not work in the test at the moment due to caching issues. | |
50 | //'state_province' => array_rand(CRM_Core_PseudoConstant::stateProvince(FALSE, FALSE), 3), | |
ec28b24d | 51 | 'date' => NULL, |
a6d226f4 | 52 | 'contact' => NULL, |
872a35c1 | 53 | 'boolean' => NULL, |
9099cab3 | 54 | ]; |
ec28b24d | 55 | |
9099cab3 | 56 | $dataValues = !empty($type) ? [$type => $dataValues[$type]] : $dataValues; |
6fca1a34 | 57 | |
ec28b24d | 58 | foreach ($dataValues as $dataType => $values) { |
9099cab3 | 59 | $this->optionGroup[$dataType] = ['values' => $values]; |
ec28b24d | 60 | if (!empty($values)) { |
ec28b24d | 61 | $result = $this->callAPISuccess('OptionGroup', 'create', |
9099cab3 | 62 | [ |
ec28b24d | 63 | 'name' => "{$dataType}_group", |
9099cab3 CW |
64 | 'api.option_value.create' => ['label' => "$dataType 1", 'value' => $values[0]], |
65 | 'api.option_value.create.1' => ['label' => "$dataType 2", 'value' => $values[1]], | |
66 | 'api.option_value.create.2' => ['label' => "$dataType 3", 'value' => $values[2]], | |
67 | ] | |
ec28b24d | 68 | ); |
69 | $this->optionGroup[$dataType]['id'] = $result['id']; | |
70 | } | |
a6d226f4 | 71 | elseif ($dataType == 'contact') { |
f819588f | 72 | for ($i = 0; $i < 3; $i++) { |
9099cab3 | 73 | $result = $this->callAPISuccess('Contact', 'create', ['contact_type' => 'Individual', 'email' => substr(sha1(rand()), 0, 7) . '@yahoo.com']); |
a6d226f4 | 74 | $this->optionGroup[$dataType]['values'][$i] = $result['id']; |
75 | } | |
76 | } | |
ec28b24d | 77 | $this->ids[$dataType] = $this->entityCustomGroupWithSingleFieldCreate("$dataType Custom Group", 'Contacts'); |
78 | } | |
79 | ||
6a488035 TO |
80 | } |
81 | ||
00be9182 | 82 | public function tearDown() { |
9099cab3 | 83 | $tablesToTruncate = [ |
6a488035 TO |
84 | 'civicrm_email', |
85 | 'civicrm_custom_field', | |
86 | 'civicrm_custom_group', | |
87 | 'civicrm_contact', | |
9099cab3 | 88 | ]; |
6a488035 TO |
89 | |
90 | // true tells quickCleanup to drop any tables that might have been created in the test | |
91 | $this->quickCleanup($tablesToTruncate, TRUE); | |
6fca1a34 | 92 | |
93 | // cleanup created option group for each custom-set before running next test | |
94 | if (!empty($this->optionGroup)) { | |
95 | foreach ($this->optionGroup as $type => $value) { | |
96 | if (!empty($value['id'])) { | |
9099cab3 | 97 | $count = $this->callAPISuccess('OptionGroup', 'get', ['id' => $value['id']]); |
a60c0bc8 | 98 | if ((bool) $count['count']) { |
9099cab3 | 99 | $this->callAPISuccess('OptionGroup', 'delete', ['id' => $value['id']]); |
a60c0bc8 | 100 | } |
6fca1a34 | 101 | } |
102 | } | |
103 | } | |
6a488035 TO |
104 | } |
105 | ||
106 | public function testCreateCustomValue() { | |
6fca1a34 | 107 | $this->_populateOptionAndCustomGroup(); |
9099cab3 | 108 | $this->_customField = $this->customFieldCreate(['custom_group_id' => $this->ids['string']['custom_group_id']]); |
0ec36ef1 | 109 | $this->_customFieldID = $this->_customField['id']; |
6fca1a34 | 110 | |
ec28b24d | 111 | $customFieldDataType = CRM_Core_BAO_CustomField::dataType(); |
112 | $dataToHtmlTypes = CRM_Core_BAO_CustomField::dataToHtml(); | |
113 | $count = 0; | |
9099cab3 | 114 | $optionSupportingHTMLTypes = ['Select', 'Radio', 'CheckBox', 'Autocomplete-Select', 'Multi-Select']; |
6a488035 | 115 | |
ec28b24d | 116 | foreach ($customFieldDataType as $dataType => $label) { |
ec28b24d | 117 | switch ($dataType) { |
f9887f64 | 118 | // case 'Country': |
119 | // case 'StateProvince': | |
ec28b24d | 120 | case 'String': |
121 | case 'Link': | |
122 | case 'Int': | |
123 | case 'Float': | |
124 | case 'Money': | |
872a35c1 | 125 | case 'Date': |
872a35c1 | 126 | case 'Boolean': |
127 | ||
128 | //Based on the custom field data-type choose desired SQL operators(to test with) and basic $type | |
9099cab3 CW |
129 | if (in_array($dataType, ['String', 'Link'])) { |
130 | $validSQLOperators = ['=', '!=', 'IN', 'NOT IN', 'LIKE', 'NOT LIKE', 'IS NOT NULL', 'IS NULL']; | |
ec28b24d | 131 | $type = 'string'; |
132 | } | |
872a35c1 | 133 | elseif ($dataType == 'Boolean') { |
9099cab3 | 134 | $validSQLOperators = ['=', '!=', 'IS NOT NULL', 'IS NULL']; |
872a35c1 | 135 | $type = 'boolean'; |
136 | } | |
ec28b24d | 137 | else { |
872a35c1 | 138 | if ($dataType == 'Country') { |
139 | $type = 'country'; | |
140 | } | |
141 | elseif ($dataType == 'StateProvince') { | |
ec28b24d | 142 | $type = 'state_province'; |
143 | } | |
a6d226f4 | 144 | elseif ($dataType == 'ContactReference') { |
145 | $type = 'contact'; | |
146 | } | |
147 | elseif ($dataType == 'Date') { | |
148 | $type = 'date'; | |
149 | } | |
ec28b24d | 150 | else { |
a6d226f4 | 151 | $type = $dataType == 'Int' ? 'integer' : 'number'; |
ec28b24d | 152 | } |
9099cab3 | 153 | $validSQLOperators = ['=', '!=', 'IN', 'NOT IN', '<=', '>=', '>', '<', 'IS NOT NULL', 'IS NULL']; |
ec28b24d | 154 | } |
6a488035 | 155 | |
872a35c1 | 156 | //Create custom field of $dataType and html-type $html |
ec28b24d | 157 | foreach ($dataToHtmlTypes[$count] as $html) { |
f9887f64 | 158 | // per CRM-18568 the like operator does not currently work for fields with options. |
159 | // the LIKE operator could potentially bypass ACLs (as could IS NOT NULL) and some thought needs to be given | |
160 | // to it. | |
161 | if (in_array($html, $optionSupportingHTMLTypes)) { | |
9099cab3 | 162 | $validSQLOperators = array_diff($validSQLOperators, ['LIKE', 'NOT LIKE']); |
f9887f64 | 163 | } |
9099cab3 | 164 | $params = [ |
ec28b24d | 165 | 'custom_group_id' => $this->ids[$type]['custom_group_id'], |
166 | 'label' => "$dataType - $html", | |
167 | 'data_type' => $dataType, | |
168 | 'html_type' => $html, | |
169 | 'default_value' => NULL, | |
9099cab3 CW |
170 | ]; |
171 | if (!in_array($html, ['Text', 'TextArea']) && !in_array($dataType, ['Link', 'Date', 'ContactReference', 'Boolean'])) { | |
172 | $params += ['option_group_id' => $this->optionGroup[$type]['id']]; | |
ec28b24d | 173 | } |
174 | $customField = $this->customFieldCreate($params); | |
872a35c1 | 175 | //Now test with $validSQLOperator SQL operators against its custom value(s) |
176 | $this->_testCustomValue($customField['values'][$customField['id']], $validSQLOperators, $type); | |
ec28b24d | 177 | } |
178 | $count++; | |
179 | break; | |
6a488035 | 180 | |
ec28b24d | 181 | default: |
f9887f64 | 182 | // skipping File data-type & state province due to caching issues |
ec28b24d | 183 | $count++; |
184 | break; | |
185 | } | |
186 | } | |
187 | } | |
6a488035 | 188 | |
ec28b24d | 189 | public function _testCustomValue($customField, $sqlOps, $type) { |
190 | $isSerialized = CRM_Core_BAO_CustomField::isSerialized($customField); | |
191 | $customId = $customField['id']; | |
9099cab3 | 192 | $params = [ |
6a488035 | 193 | 'contact_type' => 'Individual', |
ec28b24d | 194 | 'email' => substr(sha1(rand()), 0, 7) . 'man1@yahoo.com', |
9099cab3 | 195 | ]; |
fc928539 | 196 | $result = $this->callAPISuccess('Contact', 'create', $params); |
ec28b24d | 197 | $contactId = $result['id']; |
6a488035 | 198 | |
8007b543 | 199 | $count = rand(1, 2); |
f9887f64 | 200 | |
ec28b24d | 201 | if ($isSerialized) { |
202 | $selectedValue = $this->optionGroup[$type]['values']; | |
203 | $notselectedValue = $selectedValue[$count]; | |
204 | unset($selectedValue[$count]); | |
205 | } | |
206 | elseif ($customField['html_type'] == 'Link') { | |
207 | $selectedValue = "http://" . substr(sha1(rand()), 0, 7) . ".com"; | |
208 | $notselectedValue = "http://" . substr(sha1(rand()), 0, 7) . ".com"; | |
209 | } | |
210 | elseif ($type == 'date') { | |
211 | $selectedValue = date('Ymd'); | |
a6d226f4 | 212 | $notselectedValue = $lesserSelectedValue = date('Ymd', strtotime('yesterday')); |
213 | $greaterSelectedValue = date('Ymd', strtotime('+ 1 day')); | |
214 | } | |
215 | elseif ($type == 'contact') { | |
216 | $selectedValue = $this->optionGroup[$type]['values'][1]; | |
217 | $notselectedValue = $this->optionGroup[$type]['values'][0]; | |
ec28b24d | 218 | } |
872a35c1 | 219 | elseif ($type == 'boolean') { |
220 | $selectedValue = 1; | |
221 | $notselectedValue = 0; | |
222 | } | |
ec28b24d | 223 | else { |
224 | $selectedValue = $this->optionGroup[$type]['values'][0]; | |
225 | $notselectedValue = $this->optionGroup[$type]['values'][$count]; | |
a6d226f4 | 226 | if (in_array(">", $sqlOps)) { |
227 | $greaterSelectedValue = $selectedValue + 1; | |
228 | $lesserSelectedValue = $selectedValue - 1; | |
229 | } | |
ec28b24d | 230 | } |
6a488035 | 231 | |
0ec36ef1 JP |
232 | $params = [ |
233 | 'entity_id' => $contactId, | |
234 | 'custom_' . $customId => $selectedValue, | |
235 | "custom_{$this->_customFieldID}" => "Test String Value for {$this->_customFieldID}", | |
236 | ]; | |
ec28b24d | 237 | $this->callAPISuccess('CustomValue', 'create', $params); |
6c6e6187 | 238 | |
bc3c9f57 JP |
239 | //Test for different return value syntax. |
240 | $returnValues = [ | |
241 | ['return' => "custom_{$customId}"], | |
242 | ['return' => ["custom_{$customId}"]], | |
243 | ["return.custom_{$customId}" => 1], | |
0ec36ef1 JP |
244 | ['return' => ["custom_{$customId}", "custom_{$this->_customFieldID}"]], |
245 | ["return.custom_{$customId}" => 1, "return.custom_{$this->_customFieldID}" => 1], | |
bc3c9f57 | 246 | ]; |
0ec36ef1 | 247 | foreach ($returnValues as $key => $val) { |
bc3c9f57 | 248 | $params = array_merge($val, [ |
bc3c9f57 JP |
249 | 'entity_id' => $contactId, |
250 | ]); | |
251 | $customValue = $this->callAPISuccess('CustomValue', 'get', $params); | |
252 | if (is_array($selectedValue)) { | |
253 | $expected = array_values($selectedValue); | |
0ec36ef1 | 254 | $this->checkArrayEquals($expected, $customValue['values'][$customId]['latest']); |
bc3c9f57 JP |
255 | } |
256 | elseif ($type == 'date') { | |
0ec36ef1 | 257 | $this->assertEquals($selectedValue, date('Ymd', strtotime(str_replace('.', '/', $customValue['values'][$customId]['latest'])))); |
bc3c9f57 JP |
258 | } |
259 | else { | |
0ec36ef1 JP |
260 | $this->assertEquals($selectedValue, $customValue['values'][$customId]['latest']); |
261 | } | |
262 | if ($key > 2) { | |
263 | $this->assertEquals("Test String Value for {$this->_customFieldID}", $customValue['values'][$this->_customFieldID]['latest']); | |
bc3c9f57 JP |
264 | } |
265 | } | |
266 | ||
ec28b24d | 267 | foreach ($sqlOps as $op) { |
a6d226f4 | 268 | $qillOp = CRM_Utils_Array::value($op, CRM_Core_SelectValues::getSearchBuilderOperators(), $op); |
ec28b24d | 269 | switch ($op) { |
a6d226f4 | 270 | case '=': |
9099cab3 | 271 | $result = $this->callAPISuccess('Contact', 'Get', ['custom_' . $customId => (is_array($selectedValue) ? implode(CRM_Core_DAO::VALUE_SEPARATOR, $selectedValue) : $selectedValue)]); |
a6d226f4 | 272 | $this->assertEquals($contactId, $result['id']); |
a6d226f4 | 273 | break; |
842ee194 | 274 | |
ec28b24d | 275 | case '!=': |
9099cab3 | 276 | $result = $this->callAPISuccess('Contact', 'Get', ['custom_' . $customId => [$op => $notselectedValue]]); |
a4a68fa4 | 277 | $this->assertEquals(TRUE, array_key_exists($contactId, $result['values'])); |
ec28b24d | 278 | break; |
6c6e6187 | 279 | |
ec28b24d | 280 | case '>': |
281 | case '<': | |
282 | case '>=': | |
283 | case '<=': | |
a6d226f4 | 284 | if ($isSerialized) { |
285 | continue; | |
286 | } | |
ec28b24d | 287 | // To be precise in for these operator we can't just rely on one contact, |
288 | // hence creating multiple contact with custom value less/more then $selectedValue respectively | |
9099cab3 | 289 | $result = $this->callAPISuccess('Contact', 'create', ['contact_type' => 'Individual', 'email' => substr(sha1(rand()), 0, 7) . 'man2@yahoo.com']); |
ec28b24d | 290 | $contactId2 = $result['id']; |
9099cab3 | 291 | $this->callAPISuccess('CustomValue', 'create', ['entity_id' => $contactId2, 'custom_' . $customId => $lesserSelectedValue]); |
842ee194 | 292 | |
ec28b24d | 293 | if ($op == '>') { |
9099cab3 | 294 | $result = $this->callAPISuccess('Contact', 'Get', ['custom_' . $customId => [$op => $lesserSelectedValue]]); |
ec28b24d | 295 | $this->assertEquals($contactId, $result['id']); |
296 | } | |
297 | elseif ($op == '<') { | |
9099cab3 | 298 | $result = $this->callAPISuccess('Contact', 'Get', ['custom_' . $customId => [$op => $selectedValue]]); |
ec28b24d | 299 | $this->assertEquals($contactId2, $result['id']); |
300 | } | |
301 | else { | |
9099cab3 | 302 | $result = $this->callAPISuccess('Contact', 'create', ['contact_type' => 'Individual', 'email' => substr(sha1(rand()), 0, 7) . 'man3@yahoo.com']); |
ec28b24d | 303 | $contactId3 = $result['id']; |
9099cab3 | 304 | $this->callAPISuccess('CustomValue', 'create', ['entity_id' => $contactId3, 'custom_' . $customId => $greaterSelectedValue]); |
842ee194 | 305 | |
9099cab3 | 306 | $result = $this->callAPISuccess('Contact', 'Get', ['custom_' . $customId => [$op => $selectedValue]]); |
ec28b24d | 307 | |
308 | $this->assertEquals($contactId, $result['values'][$contactId]['id']); | |
309 | if ($op == '>=') { | |
310 | $this->assertEquals($contactId3, $result['values'][$contactId3]['id']); | |
311 | } | |
312 | else { | |
313 | $this->assertEquals($contactId2, $result['values'][$contactId2]['id']); | |
314 | } | |
9099cab3 | 315 | $this->callAPISuccess('contact', 'delete', ['id' => $contactId3]); |
ec28b24d | 316 | } |
317 | ||
9099cab3 | 318 | $this->callAPISuccess('contact', 'delete', ['id' => $contactId2]); |
ec28b24d | 319 | break; |
320 | ||
321 | case 'IN': | |
9099cab3 | 322 | $result = $this->callAPISuccess('Contact', 'Get', ['custom_' . $customId => [$op => (array) $selectedValue]]); |
ec28b24d | 323 | $this->assertEquals($contactId, $result['id']); |
324 | break; | |
325 | ||
326 | case 'NOT IN': | |
9099cab3 | 327 | $result = $this->callAPISuccess('Contact', 'Get', ['custom_' . $customId => [$op => (array) $notselectedValue]]); |
ec28b24d | 328 | $this->assertEquals($contactId, $result['id']); |
329 | break; | |
330 | ||
331 | case 'LIKE': | |
a6d226f4 | 332 | $selectedValue = is_array($selectedValue) ? $selectedValue[0] : $selectedValue; |
9099cab3 | 333 | $result = $this->callAPISuccess('Contact', 'Get', ['custom_' . $customId => [$op => "%$selectedValue%"]]); |
ec28b24d | 334 | $this->assertEquals($contactId, $result['id']); |
335 | break; | |
6a488035 | 336 | |
ec28b24d | 337 | case 'NOT LIKE': |
9099cab3 | 338 | $result = $this->callAPISuccess('Contact', 'Get', ['custom_' . $customId => [$op => $notselectedValue]]); |
ec28b24d | 339 | $this->assertEquals($contactId, $result['id']); |
340 | break; | |
6c6e6187 | 341 | |
ec28b24d | 342 | case 'IS NULL': |
9099cab3 | 343 | $result = $this->callAPISuccess('Contact', 'Get', ['custom_' . $customId => [$op => 1]]); |
ec28b24d | 344 | $this->assertEquals(FALSE, array_key_exists($contactId, $result['values'])); |
345 | break; | |
842ee194 | 346 | |
ec28b24d | 347 | case 'IS NOT NULL': |
9099cab3 | 348 | $result = $this->callAPISuccess('Contact', 'Get', ['custom_' . $customId => [$op => 1]]); |
ec28b24d | 349 | $this->assertEquals($contactId, $result['id']); |
350 | break; | |
351 | } | |
352 | } | |
6c6e6187 | 353 | |
9099cab3 | 354 | $this->callAPISuccess('Contact', 'delete', ['id' => $contactId]); |
842ee194 | 355 | } |
96025800 | 356 | |
58eaa092 CW |
357 | /** |
358 | * Ensure custom data is updated when option values are modified | |
359 | * | |
360 | * @link https://issues.civicrm.org/jira/browse/CRM-11856 | |
361 | * | |
362 | * @throws \CiviCRM_API3_Exception | |
363 | */ | |
364 | public function testAlterOptionValue() { | |
6fca1a34 | 365 | $this->_populateOptionAndCustomGroup('string'); |
366 | ||
9099cab3 | 367 | $selectField = $this->customFieldCreate([ |
6fca1a34 | 368 | 'custom_group_id' => $this->ids['string']['custom_group_id'], |
58eaa092 CW |
369 | 'label' => 'Custom Select', |
370 | 'html_type' => 'Select', | |
6fca1a34 | 371 | 'option_group_id' => $this->optionGroup['string']['id'], |
9099cab3 CW |
372 | ]); |
373 | $selectField = civicrm_api3('customField', 'getsingle', ['id' => $selectField['id']]); | |
374 | $radioField = $this->customFieldCreate([ | |
6fca1a34 | 375 | 'custom_group_id' => $this->ids['string']['custom_group_id'], |
58eaa092 CW |
376 | 'label' => 'Custom Radio', |
377 | 'html_type' => 'Radio', | |
378 | 'option_group_id' => $selectField['option_group_id'], | |
9099cab3 CW |
379 | ]); |
380 | $multiSelectField = $this->customFieldCreate([ | |
6fca1a34 | 381 | 'custom_group_id' => $this->ids['string']['custom_group_id'], |
58eaa092 CW |
382 | 'label' => 'Custom Multi-Select', |
383 | 'html_type' => 'Multi-Select', | |
384 | 'option_group_id' => $selectField['option_group_id'], | |
9099cab3 | 385 | ]); |
58eaa092 CW |
386 | $selectName = 'custom_' . $selectField['id']; |
387 | $radioName = 'custom_' . $radioField['id']; | |
388 | $multiSelectName = 'custom_' . $multiSelectField['id']; | |
6fca1a34 | 389 | $controlFieldName = 'custom_' . $this->ids['string']['custom_field_id']; |
58eaa092 | 390 | |
9099cab3 | 391 | $params = [ |
58eaa092 CW |
392 | 'first_name' => 'abc4', |
393 | 'last_name' => 'xyz4', | |
394 | 'contact_type' => 'Individual', | |
395 | 'email' => 'man4@yahoo.com', | |
6fca1a34 | 396 | $selectName => $this->optionGroup['string']['values'][0], |
397 | $multiSelectName => $this->optionGroup['string']['values'], | |
398 | $radioName => $this->optionGroup['string']['values'][1], | |
58eaa092 | 399 | // The control group in a science experiment should be unaffected |
6fca1a34 | 400 | $controlFieldName => $this->optionGroup['string']['values'][2], |
9099cab3 | 401 | ]; |
58eaa092 CW |
402 | |
403 | $contact = $this->callAPISuccess('Contact', 'create', $params); | |
404 | ||
9099cab3 | 405 | $result = $this->callAPISuccess('Contact', 'getsingle', [ |
58eaa092 | 406 | 'id' => $contact['id'], |
9099cab3 CW |
407 | 'return' => [$selectName, $multiSelectName], |
408 | ]); | |
6fca1a34 | 409 | $this->assertEquals($params[$selectName], $result[$selectName]); |
410 | $this->assertEquals($params[$multiSelectName], $result[$multiSelectName]); | |
58eaa092 | 411 | |
9099cab3 | 412 | $this->callAPISuccess('OptionValue', 'create', [ |
58eaa092 CW |
413 | 'value' => 'one-modified', |
414 | 'option_group_id' => $selectField['option_group_id'], | |
6fca1a34 | 415 | 'name' => 'string 1', |
9099cab3 CW |
416 | 'options' => [ |
417 | 'match-mandatory' => ['option_group_id', 'name'], | |
418 | ], | |
419 | ]); | |
58eaa092 | 420 | |
9099cab3 | 421 | $result = $this->callAPISuccess('Contact', 'getsingle', [ |
58eaa092 | 422 | 'id' => $contact['id'], |
9099cab3 CW |
423 | 'return' => [$selectName, $multiSelectName, $controlFieldName, $radioName], |
424 | ]); | |
58eaa092 CW |
425 | // Ensure the relevant fields have been updated |
426 | $this->assertEquals('one-modified', $result[$selectName]); | |
9099cab3 | 427 | $this->assertEquals(['one-modified', $params[$radioName], $params[$controlFieldName]], $result[$multiSelectName]); |
58eaa092 | 428 | // This field should not have changed because we didn't alter this option |
6fca1a34 | 429 | $this->assertEquals($params[$radioName], $result[$radioName]); |
58eaa092 | 430 | // This should not have changed because this field doesn't use the affected option group |
6fca1a34 | 431 | $this->assertEquals($params[$controlFieldName], $result[$controlFieldName]); |
f36d17d2 | 432 | // Add test of proof that multivalue fields. |
9099cab3 | 433 | $this->callAPISuccess('CustomValue', 'create', [ |
f36d17d2 | 434 | 'entity_id' => $contact['id'], |
9099cab3 CW |
435 | $multiSelectName => [$params[$radioName], $params[$controlFieldName]], |
436 | ]); | |
437 | $result = $this->callAPISuccess('Contact', 'getsingle', [ | |
f36d17d2 | 438 | 'id' => $contact['id'], |
9099cab3 CW |
439 | 'return' => [$selectName, $multiSelectName, $controlFieldName, $radioName], |
440 | ]); | |
f36d17d2 | 441 | |
9099cab3 | 442 | $this->assertEquals([$params[$radioName], $params[$controlFieldName]], $result[$multiSelectName]); |
58eaa092 CW |
443 | } |
444 | ||
24871985 | 445 | public function testGettree() { |
9099cab3 | 446 | $cg = $this->callAPISuccess('CustomGroup', 'create', [ |
24871985 CW |
447 | 'title' => 'TestGettree', |
448 | 'extends' => 'Individual', | |
9099cab3 CW |
449 | ]); |
450 | $cf = $this->callAPISuccess('CustomField', 'create', [ | |
24871985 CW |
451 | 'custom_group_id' => $cg['id'], |
452 | 'label' => 'Got Options', | |
453 | 'name' => 'got_options', | |
454 | "data_type" => "String", | |
455 | "html_type" => "Multi-Select", | |
9099cab3 CW |
456 | 'option_values' => ['1' => 'One', '2' => 'Two', '3' => 'Three'], |
457 | ]); | |
24871985 | 458 | $fieldName = 'custom_' . $cf['id']; |
9099cab3 | 459 | $contact = $this->individualCreate([$fieldName => ['2', '3']]); |
0b330e6d CW |
460 | |
461 | // Verify values are formatted correctly | |
9099cab3 CW |
462 | $tree = $this->callAPISuccess('CustomValue', 'gettree', ['entity_type' => 'Contact', 'entity_id' => $contact]); |
463 | $this->assertEquals(['2', '3'], $tree['values']['TestGettree']['fields']['got_options']['value']['data']); | |
24871985 | 464 | $this->assertEquals('Two, Three', $tree['values']['TestGettree']['fields']['got_options']['value']['display']); |
0b330e6d CW |
465 | |
466 | // Try limiting the return params | |
9099cab3 | 467 | $tree = $this->callAPISuccess('CustomValue', 'gettree', [ |
0b330e6d CW |
468 | 'entity_type' => 'Contact', |
469 | 'entity_id' => $contact, | |
9099cab3 | 470 | 'return' => [ |
0b330e6d CW |
471 | 'custom_group.id', |
472 | 'custom_field.id', | |
9099cab3 CW |
473 | ], |
474 | ]); | |
475 | $this->assertEquals(['2', '3'], $tree['values']['TestGettree']['fields']['got_options']['value']['data']); | |
e6446db2 | 476 | $this->assertEquals('Two, Three', $tree['values']['TestGettree']['fields']['got_options']['value']['display']); |
9099cab3 | 477 | $this->assertEquals(['id', 'fields'], array_keys($tree['values']['TestGettree'])); |
0b330e6d | 478 | |
e6446db2 | 479 | // Ensure display values are returned even if data is not |
9099cab3 | 480 | $tree = $this->callAPISuccess('CustomValue', 'gettree', [ |
e6446db2 CW |
481 | 'entity_type' => 'Contact', |
482 | 'entity_id' => $contact, | |
9099cab3 | 483 | 'return' => [ |
e6446db2 | 484 | 'custom_value.display', |
9099cab3 CW |
485 | ], |
486 | ]); | |
e6446db2 CW |
487 | $this->assertEquals('Two, Three', $tree['values']['TestGettree']['fields']['got_options']['value']['display']); |
488 | $this->assertFalse(isset($tree['values']['TestGettree']['fields']['got_options']['value']['data'])); | |
489 | ||
0b330e6d CW |
490 | // Verify that custom set appears for individuals even who don't have any custom data |
491 | $contact2 = $this->individualCreate(); | |
9099cab3 | 492 | $tree = $this->callAPISuccess('CustomValue', 'gettree', ['entity_type' => 'Contact', 'entity_id' => $contact2]); |
0b330e6d CW |
493 | $this->assertArrayHasKey('TestGettree', $tree['values']); |
494 | ||
495 | // Verify that custom set doesn't appear for other contact types | |
496 | $org = $this->organizationCreate(); | |
9099cab3 | 497 | $tree = $this->callAPISuccess('CustomValue', 'gettree', ['entity_type' => 'Contact', 'entity_id' => $org]); |
0b330e6d CW |
498 | $this->assertArrayNotHasKey('TestGettree', $tree['values']); |
499 | ||
500 | } | |
501 | ||
502 | public function testGettree_getfields() { | |
9099cab3 | 503 | $fields = $this->callAPISuccess('CustomValue', 'getfields', ['api_action' => 'gettree']); |
0b330e6d CW |
504 | $fields = $fields['values']; |
505 | $this->assertTrue((bool) $fields['entity_id']['api.required']); | |
506 | $this->assertTrue((bool) $fields['entity_type']['api.required']); | |
507 | $this->assertEquals('custom_group.id', $fields['custom_group.id']['name']); | |
508 | $this->assertEquals('custom_field.id', $fields['custom_field.id']['name']); | |
509 | $this->assertEquals('custom_value.id', $fields['custom_value.id']['name']); | |
24871985 CW |
510 | } |
511 | ||
63b7d442 AS |
512 | /** |
513 | * Test that custom fields in greeting strings are updated. | |
514 | */ | |
515 | public function testUpdateCustomGreetings() { | |
516 | // Create a custom group with one field. | |
9099cab3 | 517 | $customGroupResult = $this->callAPISuccess('CustomGroup', 'create', [ |
63b7d442 AS |
518 | 'sequential' => 1, |
519 | 'title' => "test custom group", | |
520 | 'extends' => "Individual", | |
9099cab3 CW |
521 | ]); |
522 | $customFieldResult = $this->callAPISuccess('CustomField', 'create', [ | |
63b7d442 AS |
523 | 'custom_group_id' => $customGroupResult['id'], |
524 | 'label' => "greeting test", | |
525 | 'data_type' => "String", | |
526 | 'html_type' => "Text", | |
9099cab3 | 527 | ]); |
63b7d442 AS |
528 | $customFieldId = $customFieldResult['id']; |
529 | ||
530 | // Create a contact with an email greeting format that includes the new custom field. | |
9099cab3 | 531 | $contactResult = $this->callAPISuccess('Contact', 'create', [ |
63b7d442 AS |
532 | 'contact_type' => 'Individual', |
533 | 'email' => substr(sha1(rand()), 0, 7) . '@yahoo.com', | |
534 | 'email_greeting_id' => "Customized", | |
535 | 'email_greeting_custom' => "Dear {contact.custom_{$customFieldId}}", | |
9099cab3 | 536 | ]); |
63b7d442 AS |
537 | $cid = $contactResult['id']; |
538 | ||
539 | // Define testing values. | |
540 | $uniq = uniqid(); | |
541 | $testGreetingValue = "Dear $uniq"; | |
542 | ||
543 | // Update contact's custom field with CustomValue.create | |
9099cab3 | 544 | $customValueResult = $this->callAPISuccess('CustomValue', 'create', [ |
63b7d442 AS |
545 | 'entity_id' => $cid, |
546 | "custom_{$customFieldId}" => $uniq, | |
547 | 'entity_table' => "civicrm_contact", | |
9099cab3 | 548 | ]); |
63b7d442 | 549 | |
9099cab3 | 550 | $contact = $this->callAPISuccessGetSingle('Contact', ['id' => $cid, 'return' => 'email_greeting']); |
63b7d442 AS |
551 | $this->assertEquals($testGreetingValue, $contact['email_greeting_display']); |
552 | ||
553 | } | |
554 | ||
5498def2 T |
555 | /** |
556 | * Creates a multi-valued custom field set and creates a contact with mutliple values for it. | |
557 | * | |
558 | * @return array | |
559 | */ | |
560 | private function _testGetCustomValueMultiple() { | |
561 | $fieldIDs = $this->CustomGroupMultipleCreateWithFields(); | |
562 | $customFieldValues = []; | |
563 | foreach ($fieldIDs['custom_field_id'] as $id) { | |
564 | $customFieldValues["custom_{$id}"] = "field_{$id}_value_1"; | |
565 | } | |
566 | $this->assertNotEmpty($customFieldValues); | |
567 | $contactParams = [ | |
568 | 'first_name' => 'Jane', | |
569 | 'last_name' => 'Doe', | |
570 | 'contact_type' => 'Individual', | |
571 | ]; | |
572 | $contact = $this->callAPISuccess('Contact', 'create', array_merge($contactParams, $customFieldValues)); | |
573 | foreach ($fieldIDs['custom_field_id'] as $id) { | |
574 | $customFieldValues["custom_{$id}"] = "field_{$id}_value_2"; | |
575 | } | |
576 | $result = $this->callAPISuccess('Contact', 'create', array_merge(['id' => $contact['id']], $customFieldValues)); | |
577 | return [ | |
578 | $contact['id'], | |
579 | $customFieldValues, | |
580 | ]; | |
581 | } | |
582 | ||
583 | /** | |
584 | * Test that specific custom values can be retrieved while using return with comma separated values as genererated by the api explorer. | |
585 | * ['return' => 'custom_1,custom_2'] | |
586 | */ | |
587 | public function testGetCustomValueReturnMultipleApiExplorer() { | |
588 | list($cid, $customFieldValues) = $this->_testGetCustomValueMultiple(); | |
589 | $result = $this->callAPISuccess('CustomValue', 'get', [ | |
590 | 'return' => implode(',', array_keys($customFieldValues)), | |
591 | 'entity_id' => $cid, | |
592 | ]); | |
593 | $this->assertEquals(count($customFieldValues), $result['count']); | |
594 | } | |
595 | ||
596 | /** | |
597 | * Test that specific custom values can be retrieved while using return with array style syntax. | |
598 | * ['return => ['custom_1', 'custom_2']] | |
599 | */ | |
600 | public function testGetCustomValueReturnMultipleArray() { | |
601 | list($cid, $customFieldValues) = $this->_testGetCustomValueMultiple(); | |
602 | $result = $this->callAPISuccess('CustomValue', 'get', [ | |
603 | 'return' => array_keys($customFieldValues), | |
604 | 'entity_id' => $cid, | |
605 | ]); | |
606 | $this->assertEquals(count($customFieldValues), $result['count']); | |
607 | } | |
608 | ||
609 | /** | |
610 | * Test that specific custom values can be retrieved while using a list of return parameters. | |
611 | * [['return.custom_1' => '1'], ['return.custom_2' => '1']] | |
612 | */ | |
613 | public function testGetCustomValueReturnMultipleList() { | |
614 | list($cid, $customFieldValues) = $this->_testGetCustomValueMultiple(); | |
615 | $returnArray = []; | |
616 | foreach ($customFieldValues as $field => $value) { | |
617 | $returnArray["return.{$field}"] = 1; | |
618 | } | |
619 | $result = $this->callAPISuccess('CustomValue', 'get', array_merge($returnArray, ['entity_id' => $cid])); | |
620 | $this->assertEquals(count($customFieldValues), $result['count']); | |
621 | } | |
622 | ||
afbd0c22 JP |
623 | /** |
624 | * Test getdisplayvalue api and verify if it returns | |
625 | * the custom text for display. | |
626 | */ | |
627 | public function testGetDisplayValue() { | |
628 | list($cid, $customFieldValues) = $this->_testGetCustomValueMultiple(); | |
629 | foreach ($customFieldValues as $field => $value) { | |
630 | list(, $customFieldID) = explode("_", $field); | |
631 | $result = $this->callAPISuccess('CustomValue', 'getdisplayvalue', [ | |
632 | 'entity_id' => $cid, | |
633 | 'custom_field_id' => $customFieldID, | |
634 | ]); | |
635 | $expectedValue = [ | |
636 | 'display' => $value, | |
637 | 'raw' => $value, | |
638 | ]; | |
639 | $this->checkArrayEquals($result['values'][$customFieldID], $expectedValue); | |
640 | ||
641 | $customDisplayValue = $this->callAPISuccess('CustomValue', 'getdisplayvalue', [ | |
642 | 'entity_id' => $cid, | |
643 | 'custom_field_id' => $customFieldID, | |
644 | 'custom_field_value' => "Test Custom Display - {$value}", | |
645 | ]); | |
646 | $expectedValue = [ | |
647 | 'display' => "Test Custom Display - {$value}", | |
648 | 'raw' => "Test Custom Display - {$value}", | |
649 | ]; | |
650 | $this->checkArrayEquals($customDisplayValue['values'][$customFieldID], $expectedValue); | |
651 | } | |
652 | } | |
653 | ||
ef10e0b5 | 654 | } |