[REF] Clarify variable & tighten use.
[civicrm-core.git] / tests / phpunit / api / v3 / JobTestCustomDataTest.php
CommitLineData
6c0c7017 1<?php
2/*
3 +--------------------------------------------------------------------+
7d61e75f 4 | Copyright CiviCRM LLC. All rights reserved. |
6c0c7017 5 | |
7d61e75f
TO
6 | This work is published under the GNU AGPLv3 license with some |
7 | permitted exceptions and without any warranty. For full license |
8 | and copyright information, see https://civicrm.org/licensing |
6c0c7017 9 +--------------------------------------------------------------------+
10 */
11
12/**
13 * File for the CiviCRM APIv3 job functions
14 *
15 * @package CiviCRM_APIv3
16 * @subpackage API_Job
17 *
ca5cec67 18 * @copyright CiviCRM LLC https://civicrm.org/licensing
6c0c7017 19 * @version $Id: Job.php 30879 2010-11-22 15:45:55Z shot $
20 *
21 */
22
23/**
24 * Tests for job api where custom data is involved.
25 *
26 * Set up for custom data won't work with useTransaction so these are not
27 * compatible with the other job test class.
28 *
29 * @group headless
30 */
69239109 31class api_v3_JobTestCustomDataTest extends CiviUnitTestCase {
6c0c7017 32 protected $_apiversion = 3;
33
34 public $_entity = 'Job';
6c0c7017 35
36 /**
37 * Custom group ID.
38 *
39 * @var int
40 */
41 public $customFieldID = NULL;
42
4ac6bdf3 43 /**
44 * ID of a custom field of integer type.
45 *
46 * @var int
47 */
48 public $customIntFieldID = NULL;
49
50 /**
51 * ID of a custom field of integer type.
52 *
53 * @var int
54 */
55 public $customBoolFieldID = NULL;
56
57 /**
58 * ID of a custom field of integer type.
59 *
60 * @var int
61 */
62 public $customStringCheckboxID = NULL;
63
6c0c7017 64 /**
65 * Custom Field ID.
66 *
67 * @var int
68 */
69 public $customGroupID = NULL;
70
71 public function setUp() {
72 parent::setUp();
4ac6bdf3 73 $customGroup = $this->customGroupCreate();
74 $this->customGroupID = $customGroup['id'];
9099cab3 75 $customField = $this->customFieldCreate([
4ac6bdf3 76 'custom_group_id' => $this->customGroupID,
77 'data_type' => 'Date',
78 'html_type' => 'Select Date',
79 'default_value' => '',
9099cab3 80 ]);
4ac6bdf3 81 $this->customFieldID = $customField['id'];
9099cab3 82 $customField = $this->customFieldCreate([
4ac6bdf3 83 'custom_group_id' => $this->customGroupID,
84 'data_type' => 'Integer',
85 'html_type' => 'Text',
86 'default_value' => '',
87 'label' => 'Int Field',
9099cab3 88 ]);
4ac6bdf3 89 $this->customIntFieldID = $customField['id'];
9099cab3 90 $customField = $this->customFieldCreate([
4ac6bdf3 91 'custom_group_id' => $this->customGroupID,
92 'data_type' => 'Boolean',
93 'html_type' => 'Radio',
94 'default_value' => '',
95 'label' => 'Radio Field',
9099cab3 96 ]);
4ac6bdf3 97 $this->customBoolFieldID = $customField['id'];
9099cab3 98 $customField = $this->customFieldCreate([
4ac6bdf3 99 'custom_group_id' => $this->customGroupID,
100 'data_type' => 'String',
101 'html_type' => 'CheckBox',
102 'default_value' => NULL,
103 'label' => 'checkbox Field',
9099cab3
CW
104 'option_values' => ['black' => 'black', 'white' => 'white'],
105 ]);
4ac6bdf3 106 $this->customStringCheckboxID = $customField['id'];
6c0c7017 107 }
108
109 /**
110 * Cleanup after tests.
403400d9 111 *
112 * @throws \CRM_Core_Exception
6c0c7017 113 */
114 public function tearDown() {
9099cab3 115 $this->quickCleanup(['civicrm_contact'], TRUE);
6c0c7017 116 parent::tearDown();
117 }
118
4ac6bdf3 119 /**
120 * Test the batch merge does not bork on custom date fields.
121 *
122 * @dataProvider getCheckboxData
123 *
124 * Test CRM-19074 checkbox field handling.
125 *
126 * Given a custom field with 2 checkboxes (black & white) possible values are:
127 * 1) SEPARATOR + black + SEPARATOR
128 * 2) SEPARATOR + white + SEPARATOR
129 * 3) SEPARATOR + black + SEPARATOR + white + SEPARATOR
130 * 3) '' (ie empty string means both set to 0)
131 * 4) NULL (ie not set)
132 * - in safe mode NULL is not a conflict with any option but the other
133 * combos are a conflict.
403400d9 134 *
135 * @param array $dataSet
136 *
137 * @throws \CRM_Core_Exception
4ac6bdf3 138 */
139 public function testBatchMergeCheckboxCustomFieldHandling($dataSet) {
140 $customFieldLabel = 'custom_' . $this->customStringCheckboxID;
9099cab3
CW
141 $contact1Params = is_array($dataSet['contacts'][0]) ? [$customFieldLabel => $dataSet['contacts'][0]] : [];
142 $contact2Params = is_array($dataSet['contacts'][1]) ? [$customFieldLabel => $dataSet['contacts'][1]] : [];
4ac6bdf3 143 $contactID = $this->individualCreate($contact1Params);
144 $this->individualCreate($contact2Params);
9099cab3 145 $result = $this->callAPISuccess('Job', 'process_batch_merge', ['mode' => $dataSet['mode']]);
403400d9 146 $this->assertCount($dataSet['merged'], $result['values']['merged']);
147 $this->assertCount($dataSet['skipped'], $result['values']['skipped']);
9099cab3 148 $contact = $this->callAPISuccess('Contact', 'getsingle', ['id' => $contactID, 'return' => $customFieldLabel]);
4ac6bdf3 149 $this->assertEquals($dataSet['expected'], $contact[$customFieldLabel]);
150 }
151
152 /**
153 * Get the various data combinations for a checkbox field.
154 *
155 * @return array
156 */
157 public function getCheckboxData() {
9099cab3
CW
158 $data = [
159 [
160 'null_merges_with_set' => [
4ac6bdf3 161 'mode' => 'safe',
9099cab3 162 'contacts' => [
4ac6bdf3 163 NULL,
9099cab3
CW
164 ['black'],
165 ],
4ac6bdf3 166 'skipped' => 0,
167 'merged' => 1,
9099cab3
CW
168 'expected' => ['black'],
169 ],
170 ],
171 [
172 'null_merges_with_set_reverse' => [
4ac6bdf3 173 'mode' => 'safe',
9099cab3
CW
174 'contacts' => [
175 ['black'],
4ac6bdf3 176 NULL,
9099cab3 177 ],
4ac6bdf3 178 'skipped' => 0,
179 'merged' => 1,
9099cab3 180 'expected' => ['black'],
4ac6bdf3 181
9099cab3
CW
182 ],
183 ],
184 [
185 'empty_conflicts_with_set' => [
4ac6bdf3 186 'mode' => 'safe',
9099cab3
CW
187 'contacts' => [
188 ['white'],
189 ['black'],
190 ],
4ac6bdf3 191 'skipped' => 1,
192 'merged' => 0,
9099cab3
CW
193 'expected' => ['white'],
194 ],
195 ],
196 [
197 'empty_conflicts_with_set' => [
4ac6bdf3 198 'mode' => 'aggressive',
9099cab3
CW
199 'contacts' => [
200 ['white'],
201 ['black'],
202 ],
4ac6bdf3 203 'skipped' => 0,
204 'merged' => 1,
9099cab3
CW
205 'expected' => ['white'],
206 ],
207 ],
208 ];
4ac6bdf3 209 return $data;
210 }
39b959db 211
6c0c7017 212 /**
213 * Test the batch merge does not bork on custom date fields.
214 *
215 * Test CRM-18674 date custom field handling.
216 */
217 public function testBatchMergeDateCustomFieldHandling() {
6c0c7017 218 $customFieldLabel = 'custom_' . $this->customFieldID;
219 $contactID = $this->individualCreate();
9099cab3
CW
220 $this->individualCreate([$customFieldLabel => '2012-12-03']);
221 $result = $this->callAPISuccess('Job', 'process_batch_merge', []);
6c0c7017 222 $this->assertEquals(1, count($result['values']['merged']));
9099cab3 223 $contact = $this->callAPISuccess('Contact', 'getsingle', ['id' => $contactID, 'return' => $customFieldLabel]);
6c0c7017 224 $this->assertEquals('2012-12-03 00:00:00', $contact[$customFieldLabel]);
225 }
226
227 /**
228 * Test the batch merge does not bork on custom date fields.
229 *
230 * Test CRM-18674 date custom field handling.
231 */
232 public function testBatchMergeDateCustomFieldHandlingIsView() {
9099cab3 233 $this->customFieldCreate([
4b047375
CR
234 'label' => 'OnlyView',
235 'custom_group_id' => $this->customGroupID,
6c0c7017 236 'is_view' => 1,
9099cab3 237 ]);
6c0c7017 238 $customFieldLabel = 'custom_' . $this->customFieldID;
239 $contactID = $this->individualCreate();
9099cab3
CW
240 $this->individualCreate([$customFieldLabel => '2012-11-03']);
241 $result = $this->callAPISuccess('Job', 'process_batch_merge', []);
6c0c7017 242 $this->assertEquals(1, count($result['values']['merged']));
9099cab3 243 $contact = $this->callAPISuccess('Contact', 'getsingle', ['id' => $contactID, 'return' => $customFieldLabel]);
4b047375 244 $this->assertEquals('2012-11-03 00:00:00', $contact[$customFieldLabel]);
6c0c7017 245 }
246
247 /**
248 * Check we get a conflict on the custom field.
249 */
250 public function testBatchMergeDateCustomFieldConflict() {
6c0c7017 251 $customFieldLabel = 'custom_' . $this->customFieldID;
9099cab3
CW
252 $contactID = $this->individualCreate([$customFieldLabel => '2012-11-03']);
253 $this->individualCreate([$customFieldLabel => '2013-11-03']);
254 $result = $this->callAPISuccess('Job', 'process_batch_merge', []);
6c0c7017 255 $this->assertEquals(0, count($result['values']['merged']));
256 $this->assertEquals(1, count($result['values']['skipped']));
9099cab3 257 $contact = $this->callAPISuccess('Contact', 'getsingle', ['id' => $contactID, 'return' => $customFieldLabel]);
6c0c7017 258 $this->assertEquals('2012-11-03 00:00:00', $contact[$customFieldLabel]);
259 }
260
261 /**
262 * Check we get a conflict on the custom field.
263 */
264 public function testBatchMergeDateCustomFieldNoConflict() {
6c0c7017 265 $customFieldLabel = 'custom_' . $this->customFieldID;
9099cab3
CW
266 $contactID = $this->individualCreate([$customFieldLabel => '2012-11-03']);
267 $this->individualCreate([$customFieldLabel => '2012-11-03']);
268 $result = $this->callAPISuccess('Job', 'process_batch_merge', []);
6c0c7017 269 $this->assertEquals(1, count($result['values']['merged']));
270 $this->assertEquals(0, count($result['values']['skipped']));
9099cab3 271 $contact = $this->callAPISuccess('Contact', 'getsingle', ['id' => $contactID, 'return' => $customFieldLabel]);
6c0c7017 272 $this->assertEquals('2012-11-03 00:00:00', $contact[$customFieldLabel]);
273 }
274
e2cecb9c 275 /**
276 * Check we get a no conflict on the custom field & integer merges.
277 */
278 public function testBatchMergeIntCustomFieldNoConflict() {
4ac6bdf3 279 $customFieldLabel = 'custom_' . $this->customIntFieldID;
9099cab3
CW
280 $contactID = $this->individualCreate([]);
281 $this->individualCreate([$customFieldLabel => 20]);
282 $result = $this->callAPISuccess('Job', 'process_batch_merge', []);
e2cecb9c 283 $this->assertEquals(1, count($result['values']['merged']));
284 $this->assertEquals(0, count($result['values']['skipped']));
9099cab3 285 $contact = $this->callAPISuccess('Contact', 'getsingle', ['id' => $contactID, 'return' => $customFieldLabel]);
e2cecb9c 286 $this->assertEquals(20, $contact[$customFieldLabel]);
287 }
288
289 /**
290 * Check we get a conflict on the integer custom field.
291 */
292 public function testBatchMergeIntCustomFieldConflict() {
4ac6bdf3 293 $customFieldLabel = 'custom_' . $this->customIntFieldID;
9099cab3
CW
294 $contactID = $this->individualCreate([$customFieldLabel => 20]);
295 $this->individualCreate([$customFieldLabel => 1]);
296 $result = $this->callAPISuccess('Job', 'process_batch_merge', []);
e2cecb9c 297 $this->assertEquals(0, count($result['values']['merged']));
298 $this->assertEquals(1, count($result['values']['skipped']));
9099cab3 299 $contact = $this->callAPISuccess('Contact', 'getsingle', ['id' => $contactID, 'return' => $customFieldLabel]);
e2cecb9c 300 $this->assertEquals(20, $contact[$customFieldLabel]);
301 }
302
303 /**
304 * Check we get a conflict on the integer custom field when the conflicted field is 0.
305 */
306 public function testBatchMergeIntCustomFieldConflictZero() {
4ac6bdf3 307 $customFieldLabel = 'custom_' . $this->customIntFieldID;
9099cab3
CW
308 $contactID = $this->individualCreate([$customFieldLabel => 0]);
309 $this->individualCreate([$customFieldLabel => 20]);
310 $result = $this->callAPISuccess('Job', 'process_batch_merge', []);
e2cecb9c 311 $this->assertEquals(0, count($result['values']['merged']));
312 $this->assertEquals(1, count($result['values']['skipped']));
9099cab3 313 $contact = $this->callAPISuccess('Contact', 'getsingle', ['id' => $contactID, 'return' => $customFieldLabel]);
e2cecb9c 314 $this->assertEquals(0, $contact[$customFieldLabel]);
315 }
316
6c0c7017 317 /**
4ac6bdf3 318 * Using the api with check perms set to off, make sure custom data is merged.
6c0c7017 319 *
320 * Test CRM-18674 date custom field handling.
321 */
322 public function testBatchMergeDateCustomFieldConflictAndNoCheckPerms() {
9099cab3 323 CRM_Core_Config::singleton()->userPermissionClass->permissions = ['access CiviCRM', 'edit my contact'];
4ac6bdf3 324 CRM_Core_DAO::executeQuery("DELETE FROM civicrm_cache");
325 CRM_Utils_System::flushCache();
6c0c7017 326 $customFieldLabel = 'custom_' . $this->customFieldID;
9099cab3
CW
327 $contactID = $this->individualCreate([$customFieldLabel => '2012-11-03']);
328 $this->individualCreate([$customFieldLabel => '2013-11-03']);
329 $result = $this->callAPISuccess('Job', 'process_batch_merge', ['check_permissions' => 0]);
6c0c7017 330 $this->assertEquals(0, count($result['values']['merged']));
331 $this->assertEquals(1, count($result['values']['skipped']));
9099cab3 332 $contact = $this->callAPISuccess('Contact', 'getsingle', ['id' => $contactID, 'return' => $customFieldLabel]);
6c0c7017 333 $this->assertEquals('2012-11-03 00:00:00', $contact[$customFieldLabel]);
334 }
335
336 /**
4ac6bdf3 337 * Using the api with check perms set to off, make sure custom data is merged.
338 *
339 * Test CRM-18674 date custom field handling.
6c0c7017 340 */
4ac6bdf3 341 public function testBatchMergeDateCustomFieldNoConflictAndNoCheckPerms() {
9099cab3 342 CRM_Core_Config::singleton()->userPermissionClass->permissions = ['access CiviCRM', 'edit my contact'];
4ac6bdf3 343 CRM_Core_DAO::executeQuery("DELETE FROM civicrm_cache");
344 CRM_Utils_System::flushCache();
345 $customFieldLabel = 'custom_' . $this->customFieldID;
346 $contactID = $this->individualCreate();
9099cab3
CW
347 $this->individualCreate([$customFieldLabel => '2013-11-03']);
348 $result = $this->callAPISuccess('Job', 'process_batch_merge', ['check_permissions' => 0]);
4ac6bdf3 349 $this->assertEquals(1, count($result['values']['merged']));
350 $this->assertEquals(0, count($result['values']['skipped']));
9099cab3 351 $contact = $this->callAPISuccess('Contact', 'getsingle', ['id' => $contactID, 'return' => $customFieldLabel]);
4ac6bdf3 352 $this->assertEquals('2013-11-03 00:00:00', $contact[$customFieldLabel]);
6c0c7017 353 }
354
355 /**
4ac6bdf3 356 * Using the api with check perms set to off, make sure custom data is merged.
357 *
c8f7094b 358 * Test CRM-19113 custom data lost when permissions in play.
6c0c7017 359 */
4ac6bdf3 360 public function testBatchMergeIntCustomFieldNoConflictAndNoCheckPerms() {
9099cab3 361 CRM_Core_Config::singleton()->userPermissionClass->permissions = ['access CiviCRM', 'edit my contact'];
4ac6bdf3 362 CRM_Core_DAO::executeQuery("DELETE FROM civicrm_cache");
363 CRM_Utils_System::flushCache();
364 $customFieldLabel = 'custom_' . $this->customIntFieldID;
9099cab3
CW
365 $contactID = $this->individualCreate(['custom_' . $this->customBoolFieldID => 1]);
366 $this->individualCreate([$customFieldLabel => 1, 'custom_' . $this->customBoolFieldID => 1]);
367 $result = $this->callAPISuccess('Job', 'process_batch_merge', ['check_permissions' => 0]);
4ac6bdf3 368 $this->assertEquals(1, count($result['values']['merged']));
369 $this->assertEquals(0, count($result['values']['skipped']));
9099cab3 370 $contact = $this->callAPISuccess('Contact', 'getsingle', [
c8f7094b 371 'id' => $contactID,
9099cab3
CW
372 'return' => [$customFieldLabel, 'custom_' . $this->customBoolFieldID],
373 ]);
4ac6bdf3 374 $this->assertEquals(1, $contact[$customFieldLabel]);
c8f7094b 375 $this->assertEquals(1, $contact['custom_' . $this->customBoolFieldID]);
4ac6bdf3 376 }
377
378 /**
379 * Check we get a conflict on the customs field when the data conflicts for booleans.
380 */
381 public function testBatchMergeCustomFieldConflicts() {
9099cab3
CW
382 $this->individualCreate(['custom_' . $this->customBoolFieldID => 0]);
383 $this->individualCreate(['custom_' . $this->customBoolFieldID => 1]);
384 $result = $this->callAPISuccess('Job', 'process_batch_merge', []);
4ac6bdf3 385 $this->assertEquals(0, count($result['values']['merged']));
386 $this->assertEquals(1, count($result['values']['skipped']));
387 }
388
389 /**
390 * Check we get a conflict on the customs field when the data conflicts for booleans (reverse).
391 */
392 public function testBatchMergeCustomFieldConflictsReverse() {
9099cab3
CW
393 $this->individualCreate(['custom_' . $this->customBoolFieldID => 1]);
394 $this->individualCreate(['custom_' . $this->customBoolFieldID => 0]);
395 $result = $this->callAPISuccess('Job', 'process_batch_merge', []);
4ac6bdf3 396 $this->assertEquals(0, count($result['values']['merged']));
397 $this->assertEquals(1, count($result['values']['skipped']));
398 }
399
400 /**
401 * Check we get a conflict on the customs field when the data conflicts for booleans (reverse).
9a248526 402 *
403 * @throws \CRM_Core_Exception
4ac6bdf3 404 */
9a248526 405 public function testBatchMergeCustomFieldNoConflictsOneBlank() {
9099cab3 406 $this->individualCreate(['custom_' . $this->customBoolFieldID => 1]);
4ac6bdf3 407 $this->individualCreate();
9099cab3 408 $result = $this->callAPISuccess('Job', 'process_batch_merge', []);
9a248526 409 $this->assertCount(1, $result['values']['merged']);
410 $this->assertCount(0, $result['values']['skipped']);
4ac6bdf3 411 }
412
413 /**
414 * Check we get a conflict on the customs field when the data conflicts for booleans (reverse).
9a248526 415 *
416 * @throws \CRM_Core_Exception
4ac6bdf3 417 */
9a248526 418 public function testBatchMergeCustomFieldNoConflictsOneBlankReverse() {
419 $contactID = $this->individualCreate();
9099cab3
CW
420 $this->individualCreate(['custom_' . $this->customBoolFieldID => 1]);
421 $result = $this->callAPISuccess('Job', 'process_batch_merge', []);
9a248526 422 $this->assertCount(1, $result['values']['merged']);
423 $this->assertCount(0, $result['values']['skipped']);
424 $this->assertEquals(1, $this->callAPISuccessGetValue('Contact', ['id' => $contactID, 'return' => 'custom_' . $this->customBoolFieldID]));
6c0c7017 425 }
426
427}