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