style warning fix
[civicrm-core.git] / tests / phpunit / api / v3 / ContactTest.php
CommitLineData
6a488035
TO
1<?php
2/**
381fa321 3 * @file
4 * File for the TestContact class.
6a488035
TO
5 *
6 * (PHP 5)
7 *
6c6e6187
TO
8 * @author Walt Haas <walt@dharmatech.org> (801) 534-1262
9 * @copyright Copyright CiviCRM LLC (C) 2009
10 * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html
6a488035 11 * GNU Affero General Public License version 3
6c6e6187
TO
12 * @version $Id: ContactTest.php 31254 2010-12-15 10:09:29Z eileen $
13 * @package CiviCRM
6a488035
TO
14 *
15 * This file is part of CiviCRM
16 *
17 * CiviCRM is free software; you can redistribute it and/or
18 * modify it under the terms of the GNU Affero General Public License
19 * as published by the Free Software Foundation; either version 3 of
20 * the License, or (at your option) any later version.
21 *
22 * CiviCRM is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 * GNU Affero General Public License for more details.
26 *
27 * You should have received a copy of the GNU Affero General Public
28 * License along with this program. If not, see
29 * <http://www.gnu.org/licenses/>.
30 */
31
6a488035
TO
32/**
33 * Test APIv3 civicrm_contact* functions
34 *
6c6e6187
TO
35 * @package CiviCRM_APIv3
36 * @subpackage API_Contact
acb109b7 37 * @group headless
6a488035 38 */
6a488035
TO
39class api_v3_ContactTest extends CiviUnitTestCase {
40 public $DBResetRequired = FALSE;
41 protected $_apiversion;
42 protected $_entity;
43 protected $_params;
b7c9bc4c 44
f6722559 45 protected $_contactID;
6c6e6187 46 protected $_financialTypeId = 1;
6a488035 47
6a488035 48 /**
381fa321 49 * Test setup for every test.
6a488035 50 *
d177a2a6
EM
51 * Connect to the database, truncate the tables that will be used
52 * and redirect stdin to a temporary file
6a488035
TO
53 */
54 public function setUp() {
381fa321 55 // Connect to the database.
6a488035
TO
56 parent::setUp();
57 $this->_apiversion = 3;
f6722559 58 $this->_entity = 'contact';
59 $this->_params = array(
6a488035
TO
60 'first_name' => 'abc1',
61 'contact_type' => 'Individual',
62 'last_name' => 'xyz1',
6a488035 63 );
6a488035
TO
64 }
65
701a69da 66 /**
67 * Restore the DB for the next test.
68 *
69 * @throws \Exception
70 */
00be9182 71 public function tearDown() {
1ca22999 72 $this->callAPISuccess('Setting', 'create', array('includeOrderByClause' => TRUE));
6a488035
TO
73 // truncate a few tables
74 $tablesToTruncate = array(
6a488035
TO
75 'civicrm_email',
76 'civicrm_contribution',
77 'civicrm_line_item',
78 'civicrm_website',
e635f9d4
TO
79 'civicrm_relationship',
80 'civicrm_uf_match',
405f289b 81 'civicrm_phone',
e9e27a80 82 'civicrm_address',
1ca22999 83 'civicrm_acl_contact_cache',
5ea06a7b 84 'civicrm_activity_contact',
85 'civicrm_activity',
6a488035
TO
86 );
87
f6722559 88 $this->quickCleanup($tablesToTruncate, TRUE);
1ca22999 89 parent::tearDown();
6a488035
TO
90 }
91
92 /**
381fa321 93 * Test civicrm_contact_create.
6a488035 94 *
381fa321 95 * Verify that attempt to create individual contact with only
96 * first and last names succeeds
6a488035 97 */
00be9182 98 public function testAddCreateIndividual() {
6a488035
TO
99 $oldCount = CRM_Core_DAO::singleValueQuery('select count(*) from civicrm_contact');
100 $params = array(
101 'first_name' => 'abc1',
102 'contact_type' => 'Individual',
103 'last_name' => 'xyz1',
6a488035
TO
104 );
105
f6722559 106 $contact = $this->callAPISuccess('contact', 'create', $params);
fe482240
EM
107 $this->assertTrue(is_numeric($contact['id']));
108 $this->assertTrue($contact['id'] > 0);
6a488035 109 $newCount = CRM_Core_DAO::singleValueQuery('select count(*) from civicrm_contact');
6c6e6187 110 $this->assertEquals($oldCount + 1, $newCount);
6a488035 111
6a488035
TO
112 $this->assertDBState('CRM_Contact_DAO_Contact',
113 $contact['id'],
114 $params
115 );
116 }
117
ec52a65a 118 /**
119 * Test that it is possible to prevent cache clearing via option.
120 *
121 * Cache clearing is bypassed if 'options' => array('do_not_reset_cache' => 1 is used.
122 */
123 public function testCreateIndividualNoCacheClear() {
124
125 $contact = $this->callAPISuccess('contact', 'create', $this->_params);
126 $groupID = $this->groupCreate();
127
128 $this->putGroupContactCacheInClearableState($groupID, $contact);
129
130 $this->callAPISuccess('contact', 'create', array('id' => $contact['id']));
131 $this->assertEquals(0, CRM_Core_DAO::singleValueQuery("SELECT count(*) FROM civicrm_group_contact_cache"));
132
133 // Rinse & repeat, but with the option.
134 $this->putGroupContactCacheInClearableState($groupID, $contact);
135 $this->callAPISuccess('contact', 'create', array('id' => $contact['id'], 'options' => array('do_not_reset_cache' => 1)));
136 $this->assertEquals(1, CRM_Core_DAO::singleValueQuery("SELECT count(*) FROM civicrm_group_contact_cache"));
137 }
138
3a15378c 139 /**
140 * Test for international string acceptance (CRM-10210).
141 *
142 * @dataProvider getInternationalStrings
143 *
144 * @param string $string
145 * String to be tested.
146 *
147 * @throws \Exception
148 */
149 public function testInternationalStrings($string) {
150 $this->callAPISuccess('Contact', 'create', array_merge(
151 $this->_params,
152 array('first_name' => $string)
153 ));
154 $result = $this->callAPISuccessGetSingle('Contact', array('first_name' => $string));
155 $this->assertEquals($string, $result['first_name']);
156
157 $organizationParams = array(
158 'organization_name' => $string,
159 'contact_type' => 'Organization',
160 );
161
162 $this->callAPISuccess('Contact', 'create', $organizationParams);
163 $result = $this->callAPISuccessGetSingle('Contact', $organizationParams);
164 $this->assertEquals($string, $result['organization_name']);
165 }
166
167 /**
168 * Get international string data for testing against api calls.
169 */
170 public function getInternationalStrings() {
171 $invocations = array();
172 $invocations[] = array('Scarabée');
173 $invocations[] = array('Iñtërnâtiônàlizætiøn');
174 $invocations[] = array('これは日本語のテキストです。読めますか');
175 $invocations[] = array('देखें हिन्दी कैसी नजर आती है। अरे वाह ये तो नजर आती है।');
176 return $invocations;
177 }
178
b99f9616 179 /**
180 * Test civicrm_contact_create.
181 *
182 * Verify that preferred language can be set.
183 */
184 public function testAddCreateIndividualWithPreferredLanguage() {
185 $params = array(
186 'first_name' => 'abc1',
187 'contact_type' => 'Individual',
188 'last_name' => 'xyz1',
189 'preferred_language' => 'es_ES',
190 );
191
192 $contact = $this->callAPISuccess('contact', 'create', $params);
193 $this->getAndCheck($params, $contact['id'], 'Contact');
194 }
195
6a488035 196 /**
381fa321 197 * Test civicrm_contact_create with sub-types.
6a488035 198 *
381fa321 199 * Verify that sub-types are created successfully and not deleted by subsequent updates.
6a488035 200 */
00be9182 201 public function testIndividualSubType() {
6a488035
TO
202 $params = array(
203 'first_name' => 'test abc',
204 'contact_type' => 'Individual',
205 'last_name' => 'test xyz',
206 'contact_sub_type' => array('Student', 'Staff'),
5896d037 207 );
f6722559 208 $contact = $this->callAPISuccess('contact', 'create', $params);
6a488035
TO
209 $cid = $contact['id'];
210
211 $params = array(
212 'id' => $cid,
213 'middle_name' => 'foo',
6a488035 214 );
f6722559 215 $this->callAPISuccess('contact', 'create', $params);
6a488035
TO
216 unset($params['middle_name']);
217
f6722559 218 $contact = $this->callAPISuccess('contact', 'get', $params);
6a488035 219
fe482240 220 $this->assertEquals(array('Student', 'Staff'), $contact['values'][$cid]['contact_sub_type']);
6a488035
TO
221 }
222
35fbf8a2
MM
223 /**
224 * Verify that we can retreive contacts of different sub types
225 */
226 public function testGetMultipleContactSubTypes() {
227
228 // This test presumes that there are no parents or students in the dataset
229
230 // create a student
231 $student = $this->callAPISuccess('contact', 'create', array(
232 'email' => 'student@example.com',
233 'contact_type' => 'Individual',
234 'contact_sub_type' => 'Student',
235 ));
236
237 // create a parent
238 $parent = $this->callAPISuccess('contact', 'create', array(
239 'email' => 'parent@example.com',
240 'contact_type' => 'Individual',
241 'contact_sub_type' => 'Parent',
242 ));
243
244 // create a parent
245 $contact = $this->callAPISuccess('contact', 'create', array(
246 'email' => 'parent@example.com',
247 'contact_type' => 'Individual',
248 ));
249
250 // get all students and parents
251 $getParams = array('contact_sub_type' => array('IN' => array('Parent', 'Student')));
252 $result = civicrm_api3('contact', 'get', $getParams);
253
254 // check that we retrieved the student and the parent
255 $this->assertArrayHasKey($student['id'], $result['values']);
256 $this->assertArrayHasKey($parent['id'], $result['values']);
257 $this->assertEquals(2, $result['count']);
258
259 }
260
6a488035 261 /**
381fa321 262 * Verify that attempt to create contact with empty params fails.
6a488035 263 */
00be9182 264 public function testCreateEmptyContact() {
f6722559 265 $this->callAPIFailure('contact', 'create', array());
6a488035
TO
266 }
267
268 /**
381fa321 269 * Verify that attempt to create contact with bad contact type fails.
6a488035 270 */
00be9182 271 public function testCreateBadTypeContact() {
6a488035
TO
272 $params = array(
273 'email' => 'man1@yahoo.com',
274 'contact_type' => 'Does not Exist',
6a488035 275 );
6c6e6187 276 $this->callAPIFailure('contact', 'create', $params, "'Does not Exist' is not a valid option for field contact_type");
6a488035
TO
277 }
278
279 /**
381fa321 280 * Verify that attempt to create individual contact without required fields fails.
6a488035 281 */
00be9182 282 public function testCreateBadRequiredFieldsIndividual() {
6a488035
TO
283 $params = array(
284 'middle_name' => 'This field is not required',
285 'contact_type' => 'Individual',
286 );
4b58ed3b 287 $this->callAPIFailure('contact', 'create', $params);
6a488035
TO
288 }
289
290 /**
381fa321 291 * Verify that attempt to create household contact without required fields fails.
6a488035 292 */
00be9182 293 public function testCreateBadRequiredFieldsHousehold() {
6a488035
TO
294 $params = array(
295 'middle_name' => 'This field is not required',
296 'contact_type' => 'Household',
297 );
4b58ed3b 298 $this->callAPIFailure('contact', 'create', $params);
6a488035
TO
299 }
300
301 /**
381fa321 302 * Test required field check.
303 *
304 * Verify that attempt to create organization contact without required fields fails.
6a488035 305 */
00be9182 306 public function testCreateBadRequiredFieldsOrganization() {
6a488035
TO
307 $params = array(
308 'middle_name' => 'This field is not required',
309 'contact_type' => 'Organization',
310 );
311
4b58ed3b 312 $this->callAPIFailure('contact', 'create', $params);
6a488035
TO
313 }
314
315 /**
381fa321 316 * Verify that attempt to create individual contact with only an email succeeds.
6a488035 317 */
00be9182 318 public function testCreateEmailIndividual() {
57f8e7f0 319 $primaryEmail = 'man3@yahoo.com';
320 $notPrimaryEmail = 'man4@yahoo.com';
6a488035 321 $params = array(
57f8e7f0 322 'email' => $primaryEmail,
6a488035
TO
323 'contact_type' => 'Individual',
324 'location_type_id' => 1,
6a488035
TO
325 );
326
57f8e7f0 327 $contact1 = $this->callAPISuccess('contact', 'create', $params);
328
329 $this->assertEquals(3, $contact1['id']);
330 $email1 = $this->callAPISuccess('email', 'get', array('contact_id' => $contact1['id']));
331 $this->assertEquals(1, $email1['count']);
332 $this->assertEquals($primaryEmail, $email1['values'][$email1['id']]['email']);
333
334 $email2 = $this->callAPISuccess('email', 'create', array('contact_id' => $contact1['id'], 'is_primary' => 0, 'email' => $notPrimaryEmail));
335
336 // Case 1: Check with criteria primary 'email' => array('IS NOT NULL' => 1)
337 $result = $this->callAPISuccess('contact', 'get', array('email' => array('IS NOT NULL' => 1)));
338 $primaryEmailContactIds = array_keys($result['values']);
339 $this->assertEquals($primaryEmail, $email1['values'][$email1['id']]['email']);
340
341 // Case 2: Check with criteria primary 'email' => array('<>' => '')
342 $result = $this->callAPISuccess('contact', 'get', array('email' => array('<>' => '')));
343 $primaryEmailContactIds = array_keys($result['values']);
344 $this->assertEquals($primaryEmail, $email1['values'][$email1['id']]['email']);
f6722559 345
57f8e7f0 346 // Case 3: Check with email_id='primary email id'
347 $result = $this->callAPISuccess('contact', 'get', array('email_id' => $email1['id']));
348 $this->assertEquals(1, $result['count']);
349 $this->assertEquals($contact1['id'], $result['id']);
6a488035 350
57f8e7f0 351 $this->callAPISuccess('contact', 'delete', $contact1);
6a488035
TO
352 }
353
354 /**
381fa321 355 * Test creating individual by name.
356 *
357 * Verify create individual contact with only first and last names succeeds.
6a488035 358 */
00be9182 359 public function testCreateNameIndividual() {
6a488035
TO
360 $params = array(
361 'first_name' => 'abc1',
362 'contact_type' => 'Individual',
363 'last_name' => 'xyz1',
6a488035 364 );
6a488035 365
c8747697 366 $this->callAPISuccess('contact', 'create', $params);
6a488035
TO
367 }
368
c10e7177 369 /**
370 * Test creating individual by display_name.
371 *
372 * Display name & sort name should be set.
373 */
374 public function testCreateDisplayNameIndividual() {
375 $params = array(
376 'display_name' => 'abc1',
377 'contact_type' => 'Individual',
378 );
379
380 $contact = $this->callAPISuccess('contact', 'create', $params);
381 $params['sort_name'] = 'abc1';
382 $this->getAndCheck($params, $contact['id'], 'contact');
383 }
384
6a488035 385 /**
381fa321 386 * Test old keys still work.
387 *
388 * Verify that attempt to create individual contact with
d177a2a6 389 * first and last names and old key values works
6a488035 390 */
00be9182 391 public function testCreateNameIndividualOldKeys() {
6a488035
TO
392 $params = array(
393 'individual_prefix' => 'Dr.',
394 'first_name' => 'abc1',
395 'contact_type' => 'Individual',
396 'last_name' => 'xyz1',
397 'individual_suffix' => 'Jr.',
6a488035
TO
398 );
399
f6722559 400 $contact = $this->callAPISuccess('contact', 'create', $params);
6ecbca5b 401 $result = $this->callAPISuccess('contact', 'getsingle', array('id' => $contact['id']));
fd651abc 402
a1255c80
CW
403 $this->assertArrayKeyExists('prefix_id', $result);
404 $this->assertArrayKeyExists('suffix_id', $result);
405 $this->assertArrayKeyExists('gender_id', $result);
406 $this->assertEquals(4, $result['prefix_id']);
407 $this->assertEquals(1, $result['suffix_id']);
6a488035
TO
408 }
409
410 /**
381fa321 411 * Test preferred keys work.
412 *
413 * Verify that attempt to create individual contact with
d177a2a6 414 * first and last names and old key values works
6a488035 415 */
381fa321 416 public function testCreateNameIndividualRecommendedKeys2() {
6a488035
TO
417 $params = array(
418 'prefix_id' => 'Dr.',
419 'first_name' => 'abc1',
420 'contact_type' => 'Individual',
421 'last_name' => 'xyz1',
422 'suffix_id' => 'Jr.',
423 'gender_id' => 'Male',
6a488035
TO
424 );
425
f6722559 426 $contact = $this->callAPISuccess('contact', 'create', $params);
6ecbca5b 427 $result = $this->callAPISuccess('contact', 'getsingle', array('id' => $contact['id']));
fd651abc 428
a1255c80
CW
429 $this->assertArrayKeyExists('prefix_id', $result);
430 $this->assertArrayKeyExists('suffix_id', $result);
431 $this->assertArrayKeyExists('gender_id', $result);
432 $this->assertEquals(4, $result['prefix_id']);
433 $this->assertEquals(1, $result['suffix_id']);
6a488035
TO
434 }
435
436 /**
381fa321 437 * Test household name is sufficient for create.
438 *
439 * Verify that attempt to create household contact with only
d177a2a6 440 * household name succeeds
6a488035 441 */
00be9182 442 public function testCreateNameHousehold() {
6a488035
TO
443 $params = array(
444 'household_name' => 'The abc Household',
445 'contact_type' => 'Household',
6a488035 446 );
c8747697 447 $this->callAPISuccess('contact', 'create', $params);
6a488035
TO
448 }
449
450 /**
381fa321 451 * Test organization name is sufficient for create.
452 *
453 * Verify that attempt to create organization contact with only
d177a2a6 454 * organization name succeeds.
6a488035 455 */
00be9182 456 public function testCreateNameOrganization() {
6a488035
TO
457 $params = array(
458 'organization_name' => 'The abc Organization',
459 'contact_type' => 'Organization',
6a488035 460 );
c8747697 461 $this->callAPISuccess('contact', 'create', $params);
6a488035 462 }
5896d037 463
6a488035 464 /**
381fa321 465 * Verify that attempt to create organization contact without organization name fails.
6a488035 466 */
00be9182 467 public function testCreateNoNameOrganization() {
6a488035
TO
468 $params = array(
469 'first_name' => 'The abc Organization',
470 'contact_type' => 'Organization',
6a488035 471 );
4b58ed3b 472 $this->callAPIFailure('contact', 'create', $params);
6a488035 473 }
5896d037 474
ea33395c
TO
475 /**
476 * Check that permissions on API key are restricted (CRM-18112).
477 */
478 public function testCreateApiKey() {
479 $config = CRM_Core_Config::singleton();
480 $contactId = $this->individualCreate(array(
481 'first_name' => 'A',
482 'last_name' => 'B',
483 ));
484
485 // Allow edit -- because permissions aren't being checked
486 $config->userPermissionClass->permissions = array();
487 $result = $this->callAPISuccess('Contact', 'create', array(
488 'id' => $contactId,
489 'api_key' => 'original',
490 ));
491 $this->assertEquals('original', $result['values'][$contactId]['api_key']);
492
493 // Allow edit -- because we have adequate permission
494 $config->userPermissionClass->permissions = array('access CiviCRM', 'edit all contacts', 'edit api keys');
495 $result = $this->callAPISuccess('Contact', 'create', array(
496 'check_permissions' => 1,
497 'id' => $contactId,
498 'api_key' => 'abcd1234',
499 ));
500 $this->assertEquals('abcd1234', $result['values'][$contactId]['api_key']);
501
502 // Disallow edit -- because we don't have permission
503 $config->userPermissionClass->permissions = array('access CiviCRM', 'edit all contacts');
504 $result = $this->callAPIFailure('Contact', 'create', array(
505 'check_permissions' => 1,
506 'id' => $contactId,
507 'api_key' => 'defg4321',
508 ));
509 $this->assertRegExp(';Permission denied to modify api key;', $result['error_message']);
510
511 // Return everything -- because permissions are not being checked
512 $config->userPermissionClass->permissions = array();
513 $result = $this->callAPISuccess('Contact', 'create', array(
514 'id' => $contactId,
515 'first_name' => 'A2',
516 ));
517 $this->assertEquals('A2', $result['values'][$contactId]['first_name']);
518 $this->assertEquals('B', $result['values'][$contactId]['last_name']);
519 $this->assertEquals('abcd1234', $result['values'][$contactId]['api_key']);
520
521 // Return everything -- because we have adequate permission
522 $config->userPermissionClass->permissions = array('access CiviCRM', 'edit all contacts', 'edit api keys');
523 $result = $this->callAPISuccess('Contact', 'create', array(
524 'check_permissions' => 1,
525 'id' => $contactId,
526 'first_name' => 'A3',
527 ));
528 $this->assertEquals('A3', $result['values'][$contactId]['first_name']);
529 $this->assertEquals('B', $result['values'][$contactId]['last_name']);
530 $this->assertEquals('abcd1234', $result['values'][$contactId]['api_key']);
531
532 // Restricted return -- because we don't have permission
533 $config->userPermissionClass->permissions = array('access CiviCRM', 'edit all contacts');
534 $result = $this->callAPISuccess('Contact', 'create', array(
535 'check_permissions' => 1,
536 'id' => $contactId,
537 'first_name' => 'A4',
538 ));
539 $this->assertEquals('A4', $result['values'][$contactId]['first_name']);
540 $this->assertEquals('B', $result['values'][$contactId]['last_name']);
541 $this->assertTrue(empty($result['values'][$contactId]['api_key']));
542 }
543
6a488035 544 /**
381fa321 545 * Check with complete array + custom field.
546 *
6a488035
TO
547 * Note that the test is written on purpose without any
548 * variables specific to participant so it can be replicated into other entities
549 * and / or moved to the automated test suite
550 */
00be9182 551 public function testCreateWithCustom() {
6a488035
TO
552 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__, __FILE__);
553
554 $params = $this->_params;
555 $params['custom_' . $ids['custom_field_id']] = "custom string";
5c49fee0 556 $description = "This demonstrates setting a custom field through the API.";
fb32de45 557 $result = $this->callAPIAndDocument($this->_entity, 'create', $params, __FUNCTION__, __FILE__, $description);
6a488035 558
5896d037 559 $check = $this->callAPISuccess($this->_entity, 'get', array(
92915c55
TO
560 'return.custom_' . $ids['custom_field_id'] => 1,
561 'id' => $result['id'],
562 ));
4b58ed3b 563 $this->assertEquals("custom string", $check['values'][$check['id']]['custom_' . $ids['custom_field_id']]);
6a488035
TO
564
565 $this->customFieldDelete($ids['custom_field_id']);
566 $this->customGroupDelete($ids['custom_group_id']);
567 }
568
fe6daa04 569 /**
381fa321 570 * CRM-12773 - expectation is that civicrm quietly ignores fields without values.
fe6daa04 571 */
00be9182 572 public function testCreateWithNULLCustomCRM12773() {
fe6daa04 573 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__, __FILE__);
574 $params = $this->_params;
575 $params['custom_' . $ids['custom_field_id']] = NULL;
4b58ed3b 576 $this->callAPISuccess('contact', 'create', $params);
fe6daa04 577 $this->customFieldDelete($ids['custom_field_id']);
578 $this->customGroupDelete($ids['custom_group_id']);
579 }
580
9747df8a 581 /**
582 * CRM-14232 test preferred language set to site default if not passed.
583 */
584 public function testCreatePreferredLanguageUnset() {
585 $this->callAPISuccess('Contact', 'create', array(
586 'first_name' => 'Snoop',
587 'last_name' => 'Dog',
588 'contact_type' => 'Individual')
589 );
590 $result = $this->callAPISuccessGetSingle('Contact', array('last_name' => 'Dog'));
591 $this->assertEquals('en_US', $result['preferred_language']);
592 }
593
594 /**
595 * CRM-14232 test preferred language returns setting if not passed.
596 */
597 public function testCreatePreferredLanguageSet() {
598 $this->callAPISuccess('Setting', 'create', array('contact_default_language' => 'fr_FR'));
599 $this->callAPISuccess('Contact', 'create', array(
600 'first_name' => 'Snoop',
601 'last_name' => 'Dog',
602 'contact_type' => 'Individual',
603 ));
604 $result = $this->callAPISuccessGetSingle('Contact', array('last_name' => 'Dog'));
605 $this->assertEquals('fr_FR', $result['preferred_language']);
606 }
607
608 /**
609 * CRM-14232 test preferred language returns setting if not passed where setting is NULL.
610 */
611 public function testCreatePreferredLanguageNull() {
612 $this->callAPISuccess('Setting', 'create', array('contact_default_language' => 'null'));
613 $this->callAPISuccess('Contact', 'create', array(
614 'first_name' => 'Snoop',
615 'last_name' => 'Dog',
616 'contact_type' => 'Individual',
617 )
618 );
619 $result = $this->callAPISuccessGetSingle('Contact', array('last_name' => 'Dog'));
620 $this->assertEquals(NULL, $result['preferred_language']);
621 }
622
623 /**
624 * CRM-14232 test preferred language returns setting if not passed where setting is NULL.
625 */
626 public function testCreatePreferredLanguagePassed() {
627 $this->callAPISuccess('Setting', 'create', array('contact_default_language' => 'null'));
628 $this->callAPISuccess('Contact', 'create', array(
629 'first_name' => 'Snoop',
630 'last_name' => 'Dog',
631 'contact_type' => 'Individual',
632 'preferred_language' => 'en_AU',
633 ));
634 $result = $this->callAPISuccessGetSingle('Contact', array('last_name' => 'Dog'));
635 $this->assertEquals('en_AU', $result['preferred_language']);
636 }
637
2930d67a 638 /**
639 * CRM-15792 - create/update datetime field for contact.
640 */
641 public function testCreateContactCustomFldDateTime() {
642 $customGroup = $this->customGroupCreate(array('extends' => 'Individual', 'title' => 'datetime_test_group'));
643 $dateTime = CRM_Utils_Date::currentDBDate();
644 //check date custom field is saved along with time when time_format is set
645 $params = array(
646 'first_name' => 'abc3',
647 'last_name' => 'xyz3',
648 'contact_type' => 'Individual',
649 'email' => 'man3@yahoo.com',
650 'api.CustomField.create' => array(
651 'custom_group_id' => $customGroup['id'],
652 'name' => 'test_datetime',
653 'label' => 'Demo Date',
654 'html_type' => 'Select Date',
655 'data_type' => 'Date',
656 'time_format' => 2,
657 'weight' => 4,
658 'is_required' => 1,
659 'is_searchable' => 0,
660 'is_active' => 1,
661 ),
662 );
663
3c27d467 664 $result = $this->callAPISuccess('Contact', 'create', $params);
2930d67a 665 $customFldId = $result['values'][$result['id']]['api.CustomField.create']['id'];
ba4a1892 666 $this->assertNotNull($result['id']);
a15773db 667 $this->assertNotNull($customFldId);
2930d67a 668
669 $params = array(
670 'id' => $result['id'],
671 "custom_{$customFldId}" => $dateTime,
672 'api.CustomValue.get' => 1,
673 );
674
3c27d467 675 $result = $this->callAPISuccess('Contact', 'create', $params);
ba4a1892 676 $this->assertNotNull($result['id']);
2930d67a 677 $customFldDate = date("YmdHis", strtotime($result['values'][$result['id']]['api.CustomValue.get']['values'][0]['latest']));
a15773db 678 $this->assertNotNull($customFldDate);
2930d67a 679 $this->assertEquals($dateTime, $customFldDate);
680 $customValueId = $result['values'][$result['id']]['api.CustomValue.get']['values'][0]['id'];
681 $dateTime = date('Ymd');
682 //date custom field should not contain time part when time_format is null
683 $params = array(
684 'id' => $result['id'],
685 'api.CustomField.create' => array(
41755648 686 'id' => $customFldId,
2930d67a 687 'html_type' => 'Select Date',
688 'data_type' => 'Date',
689 'time_format' => '',
690 ),
691 'api.CustomValue.create' => array(
692 'id' => $customValueId,
693 'entity_id' => $result['id'],
694 "custom_{$customFldId}" => $dateTime,
695 ),
696 'api.CustomValue.get' => 1,
697 );
3c27d467 698 $result = $this->callAPISuccess('Contact', 'create', $params);
ba4a1892 699 $this->assertNotNull($result['id']);
2930d67a 700 $customFldDate = date("Ymd", strtotime($result['values'][$result['id']]['api.CustomValue.get']['values'][0]['latest']));
701 $customFldTime = date("His", strtotime($result['values'][$result['id']]['api.CustomValue.get']['values'][0]['latest']));
a15773db 702 $this->assertNotNull($customFldDate);
2930d67a 703 $this->assertEquals($dateTime, $customFldDate);
704 $this->assertEquals(000000, $customFldTime);
3c27d467 705 $this->callAPISuccess('Contact', 'create', $params);
2930d67a 706 }
707
fe6daa04 708
d424ffde 709 /**
381fa321 710 * Test creating a current employer through API.
6a488035 711 */
5896d037 712 public function testContactCreateCurrentEmployer() {
381fa321 713 // Here we will just do the get for set-up purposes.
f6722559 714 $count = $this->callAPISuccess('contact', 'getcount', array(
6a488035 715 'organization_name' => 'new employer org',
21dfd5f5 716 'contact_type' => 'Organization',
6a488035
TO
717 ));
718 $this->assertEquals(0, $count);
f6722559 719 $employerResult = $this->callAPISuccess('contact', 'create', array_merge($this->_params, array(
5896d037
TO
720 'current_employer' => 'new employer org',
721 )
6a488035 722 ));
bb043d6f
E
723 // do it again as an update to check it doesn't cause an error
724 $employerResult = $this->callAPISuccess('contact', 'create', array_merge($this->_params, array(
6c6e6187 725 'current_employer' => 'new employer org',
21dfd5f5 726 'id' => $employerResult['id'],
5896d037 727 )
bb043d6f 728 ));
f6722559 729 $expectedCount = 1;
4b58ed3b 730 $this->callAPISuccess('contact', 'getcount', array(
5896d037 731 'organization_name' => 'new employer org',
21dfd5f5 732 'contact_type' => 'Organization',
5896d037
TO
733 ),
734 $expectedCount);
6a488035 735
f6722559 736 $result = $this->callAPISuccess('contact', 'getsingle', array(
6a488035
TO
737 'id' => $employerResult['id'],
738 ));
739
740 $this->assertEquals('new employer org', $result['current_employer']);
741
742 }
5896d037 743
d424ffde 744 /**
381fa321 745 * Test creating a current employer through API.
746 *
747 * Check it will re-activate a de-activated employer
d424ffde 748 */
5896d037 749 public function testContactCreateDuplicateCurrentEmployerEnables() {
381fa321 750 // Set up - create employer relationship.
bb043d6f 751 $employerResult = $this->callAPISuccess('contact', 'create', array_merge($this->_params, array(
5896d037
TO
752 'current_employer' => 'new employer org',
753 )
bb043d6f 754 ));
6c6e6187 755 $relationship = $this->callAPISuccess('relationship', 'get', array(
bb043d6f 756 'contact_id_a' => $employerResult['id'],
6c6e6187 757 ));
bb043d6f
E
758
759 //disable & check it is disabled
760 $this->callAPISuccess('relationship', 'create', array('id' => $relationship['id'], 'is_active' => 0));
6c6e6187 761 $this->callAPISuccess('relationship', 'getvalue', array(
bb043d6f 762 'id' => $relationship['id'],
21dfd5f5 763 'return' => 'is_active',
bb043d6f
E
764 ), 0);
765
381fa321 766 // Re-set the current employer - thus enabling the relationship.
4b58ed3b 767 $this->callAPISuccess('contact', 'create', array_merge($this->_params, array(
6c6e6187 768 'current_employer' => 'new employer org',
21dfd5f5 769 'id' => $employerResult['id'],
5896d037 770 )
bb043d6f
E
771 ));
772 //check is_active is now 1
6c6e6187 773 $relationship = $this->callAPISuccess('relationship', 'getsingle', array(
5896d037
TO
774 'return' => 'is_active',
775 ));
6c6e6187 776 $this->assertEquals(1, $relationship['is_active']);
bb043d6f
E
777 }
778
8f32b005 779 /**
381fa321 780 * Check deceased contacts are not retrieved.
781 *
782 * Note at time of writing the default is to return default. This should possibly be changed & test added.
8f32b005 783 */
00be9182 784 public function testGetDeceasedRetrieved() {
4b58ed3b 785 $this->callAPISuccess($this->_entity, 'create', $this->_params);
5896d037 786 $c2 = $this->callAPISuccess($this->_entity, 'create', array(
92915c55
TO
787 'first_name' => 'bb',
788 'last_name' => 'ccc',
789 'contact_type' => 'Individual',
790 'is_deceased' => 1,
791 ));
8f32b005 792 $result = $this->callAPISuccess($this->_entity, 'get', array('is_deceased' => 0));
793 $this->assertFalse(array_key_exists($c2['id'], $result['values']));
794 }
6a488035 795
c490a46a 796 /**
381fa321 797 * Test that sort works - old syntax.
c490a46a 798 */
00be9182 799 public function testGetSort() {
f6722559 800 $c1 = $this->callAPISuccess($this->_entity, 'create', $this->_params);
5896d037 801 $c2 = $this->callAPISuccess($this->_entity, 'create', array(
92915c55
TO
802 'first_name' => 'bb',
803 'last_name' => 'ccc',
804 'contact_type' => 'Individual',
805 ));
5896d037
TO
806 $result = $this->callAPISuccess($this->_entity, 'get', array(
807 'sort' => 'first_name ASC',
808 'return.first_name' => 1,
809 'sequential' => 1,
810 'rowCount' => 1,
c8747697 811 'contact_type' => 'Individual',
5896d037 812 ));
6a488035
TO
813
814 $this->assertEquals('abc1', $result['values'][0]['first_name']);
f6722559 815 $result = $this->callAPISuccess($this->_entity, 'get', array(
816 'sort' => 'first_name DESC',
817 'return.first_name' => 1,
818 'sequential' => 1,
819 'rowCount' => 1,
820 ));
6a488035
TO
821 $this->assertEquals('bb', $result['values'][0]['first_name']);
822
f6722559 823 $this->callAPISuccess($this->_entity, 'delete', array('id' => $c1['id']));
824 $this->callAPISuccess($this->_entity, 'delete', array('id' => $c2['id']));
6a488035 825 }
5896d037 826
d424ffde 827 /**
381fa321 828 * Test that we can retrieve contacts using array syntax.
829 *
830 * I.e 'id' => array('IN' => array('3,4')).
d424ffde 831 */
00be9182 832 public function testGetINIDArray() {
78c0bfc0 833 $c1 = $this->callAPISuccess($this->_entity, 'create', $this->_params);
5896d037 834 $c2 = $this->callAPISuccess($this->_entity, 'create', array(
92915c55
TO
835 'first_name' => 'bb',
836 'last_name' => 'ccc',
837 'contact_type' => 'Individual',
838 ));
5896d037 839 $c3 = $this->callAPISuccess($this->_entity, 'create', array(
92915c55
TO
840 'first_name' => 'hh',
841 'last_name' => 'll',
842 'contact_type' => 'Individual',
843 ));
78c0bfc0 844 $result = $this->callAPISuccess($this->_entity, 'get', array('id' => array('IN' => array($c1['id'], $c3['id']))));
845 $this->assertEquals(2, $result['count']);
846 $this->assertEquals(array($c1['id'], $c3['id']), array_keys($result['values']));
847 $this->callAPISuccess($this->_entity, 'delete', array('id' => $c1['id']));
848 $this->callAPISuccess($this->_entity, 'delete', array('id' => $c2['id']));
849 $this->callAPISuccess($this->_entity, 'delete', array('id' => $c3['id']));
850 }
5896d037 851
d424ffde 852 /**
381fa321 853 * Test variants on deleted behaviour.
6a488035 854 */
00be9182 855 public function testGetDeleted() {
6a488035 856 $params = $this->_params;
f6722559 857 $contact1 = $this->callAPISuccess('contact', 'create', $params);
6a488035
TO
858 $params['is_deleted'] = 1;
859 $params['last_name'] = 'bcd';
f6722559 860 $contact2 = $this->callAPISuccess('contact', 'create', $params);
c8747697 861 $countActive = $this->callAPISuccess('contact', 'getcount', array(
862 'showAll' => 'active',
863 'contact_type' => 'Individual',
864 ));
865 $countAll = $this->callAPISuccess('contact', 'getcount', array('showAll' => 'all', 'contact_type' => 'Individual'));
866 $countTrash = $this->callAPISuccess('contact', 'getcount', array('showAll' => 'trash', 'contact_type' => 'Individual'));
867 $countDefault = $this->callAPISuccess('contact', 'getcount', array('contact_type' => 'Individual'));
f6722559 868 $countDeleted = $this->callAPISuccess('contact', 'getcount', array(
c8747697 869 'contact_type' => 'Individual',
f6722559 870 'contact_is_deleted' => 1,
5896d037 871 ));
f6722559 872 $countNotDeleted = $this->callAPISuccess('contact', 'getcount', array(
873 'contact_is_deleted' => 0,
c8747697 874 'contact_type' => 'Individual',
5896d037 875 ));
f6722559 876 $this->callAPISuccess('contact', 'delete', array('id' => $contact1['id']));
877 $this->callAPISuccess('contact', 'delete', array('id' => $contact2['id']));
c8747697 878 $this->assertEquals(1, $countNotDeleted, 'contact_is_deleted => 0 is respected');
fe482240
EM
879 $this->assertEquals(1, $countActive);
880 $this->assertEquals(1, $countTrash);
881 $this->assertEquals(2, $countAll);
882 $this->assertEquals(1, $countDeleted);
c8747697 883 $this->assertEquals(1, $countDefault, 'Only active by default in line');
6a488035 884 }
c490a46a
CW
885
886 /**
381fa321 887 * Test that sort works - new syntax.
c490a46a 888 */
381fa321 889 public function testGetSortNewSyntax() {
5896d037
TO
890 $c1 = $this->callAPISuccess($this->_entity, 'create', $this->_params);
891 $c2 = $this->callAPISuccess($this->_entity, 'create', array(
92915c55
TO
892 'first_name' => 'bb',
893 'last_name' => 'ccc',
894 'contact_type' => 'Individual',
895 ));
f6722559 896 $result = $this->callAPISuccess($this->_entity, 'getvalue', array(
6a488035 897 'return' => 'first_name',
c8747697 898 'contact_type' => 'Individual',
5896d037
TO
899 'options' => array(
900 'limit' => 1,
901 'sort' => 'first_name',
902 ),
903 ));
c8747697 904 $this->assertEquals('abc1', $result);
6a488035 905
f6722559 906 $result = $this->callAPISuccess($this->_entity, 'getvalue', array(
5896d037 907 'return' => 'first_name',
c8747697 908 'contact_type' => 'Individual',
5896d037
TO
909 'options' => array(
910 'limit' => 1,
911 'sort' => 'first_name DESC',
912 ),
913 ));
6a488035
TO
914 $this->assertEquals('bb', $result);
915
f6722559 916 $this->callAPISuccess($this->_entity, 'delete', array('id' => $c1['id']));
917 $this->callAPISuccess($this->_entity, 'delete', array('id' => $c2['id']));
6a488035 918 }
c490a46a 919
c4bc3d5a
JV
920 /**
921 * Test sort and limit for chained relationship get.
922 *
923 * https://issues.civicrm.org/jira/browse/CRM-15983
924 */
925 public function testSortLimitChainedRelationshipGetCRM15983() {
926 // Some contact
927 $create_result_1 = $this->callAPISuccess('contact', 'create', array(
928 'first_name' => 'Jules',
929 'last_name' => 'Smos',
930 'contact_type' => 'Individual',
931 ));
932
933 // Create another contact with two relationships.
934 $create_params = array(
935 'first_name' => 'Jos',
936 'last_name' => 'Smos',
937 'contact_type' => 'Individual',
938 'api.relationship.create' => array(
939 array(
940 'contact_id_a' => '$value.id',
941 'contact_id_b' => $create_result_1['id'],
942 // spouse of:
943 'relationship_type_id' => 2,
944 'start_date' => '2005-01-12',
945 'end_date' => '2006-01-11',
946 'description' => 'old',
947 ),
948 array(
949 'contact_id_a' => '$value.id',
950 'contact_id_b' => $create_result_1['id'],
951 // spouse of (was married twice :))
952 'relationship_type_id' => 2,
953 'start_date' => '2006-07-01',
954 'end_date' => '2010-07-01',
955 'description' => 'new',
956 ),
957 ),
958 );
959 $create_result = $this->callAPISuccess('contact', 'create', $create_params);
960
961 // Try to retrieve the contact and the most recent relationship.
962 $get_params = array(
963 'sequential' => 1,
964 'id' => $create_result['id'],
965 'api.relationship.get' => array(
966 'contact_id_a' => '$value.id',
967 'options' => array(
968 'limit' => '1',
969 'sort' => 'start_date DESC',
970 )),
971 );
972 $get_result = $this->callAPISuccess('contact', 'getsingle', $get_params);
973
974 // Clean up.
975 $this->callAPISuccess('contact', 'delete', array(
976 'id' => $create_result['id'],
977 ));
978
979 // Assert.
980 $this->assertEquals(1, $get_result['api.relationship.get']['count']);
981 $this->assertEquals('new', $get_result['api.relationship.get']['values'][0]['description']);
982 }
983
c490a46a 984 /**
381fa321 985 * Test apostrophe works in get & create.
6a488035 986 */
00be9182 987 public function testGetApostropheCRM10857() {
6a488035 988 $params = array_merge($this->_params, array('last_name' => "O'Connor"));
4b58ed3b 989 $this->callAPISuccess($this->_entity, 'create', $params);
f6722559 990 $result = $this->callAPISuccess($this->_entity, 'getsingle', array(
6a488035
TO
991 'last_name' => "O'Connor",
992 'sequential' => 1,
993 ));
994 $this->assertEquals("O'Connor", $result['last_name'], 'in line' . __LINE__);
995 }
996
997 /**
381fa321 998 * Check with complete array + custom field.
999 *
6a488035
TO
1000 * Note that the test is written on purpose without any
1001 * variables specific to participant so it can be replicated into other entities
1002 * and / or moved to the automated test suite
1003 */
00be9182 1004 public function testGetWithCustom() {
6a488035
TO
1005 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__, __FILE__);
1006
1007 $params = $this->_params;
1008 $params['custom_' . $ids['custom_field_id']] = "custom string";
5c49fee0 1009 $description = "This demonstrates setting a custom field through the API.";
6a488035 1010 $subfile = "CustomFieldGet";
f6722559 1011 $result = $this->callAPISuccess($this->_entity, 'create', $params);
6a488035 1012
5896d037 1013 $check = $this->callAPIAndDocument($this->_entity, 'get', array(
92915c55
TO
1014 'return.custom_' . $ids['custom_field_id'] => 1,
1015 'id' => $result['id'],
1016 ), __FUNCTION__, __FILE__, $description, $subfile);
6a488035 1017
4b58ed3b 1018 $this->assertEquals("custom string", $check['values'][$check['id']]['custom_' . $ids['custom_field_id']]);
f6722559 1019 $fields = ($this->callAPISuccess('contact', 'getfields', $params));
6a488035
TO
1020 $this->assertTrue(is_array($fields['values']['custom_' . $ids['custom_field_id']]));
1021 $this->customFieldDelete($ids['custom_field_id']);
1022 $this->customGroupDelete($ids['custom_group_id']);
1023 }
c490a46a
CW
1024
1025 /**
381fa321 1026 * Check with complete array + custom field.
1027 *
c490a46a
CW
1028 * Note that the test is written on purpose without any
1029 * variables specific to participant so it can be replicated into other entities
1030 * and / or moved to the automated test suite
1031 */
00be9182 1032 public function testGetWithCustomReturnSyntax() {
6a488035
TO
1033 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__, __FILE__);
1034
1035 $params = $this->_params;
1036 $params['custom_' . $ids['custom_field_id']] = "custom string";
5c49fee0 1037 $description = "This demonstrates setting a custom field through the API.";
6a488035 1038 $subfile = "CustomFieldGetReturnSyntaxVariation";
f6722559 1039 $result = $this->callAPISuccess($this->_entity, 'create', $params);
1040 $params = array('return' => 'custom_' . $ids['custom_field_id'], 'id' => $result['id']);
1041 $check = $this->callAPIAndDocument($this->_entity, 'get', $params, __FUNCTION__, __FILE__, $description, $subfile);
6a488035 1042
43ef1263 1043 $this->assertEquals("custom string", $check['values'][$check['id']]['custom_' . $ids['custom_field_id']]);
6a488035
TO
1044 $this->customFieldDelete($ids['custom_field_id']);
1045 $this->customGroupDelete($ids['custom_group_id']);
1046 }
1047
43ef1263 1048 /**
66670e4d 1049 * Check that address name, ID is returned if required.
43ef1263 1050 */
66670e4d 1051 public function testGetReturnAddress() {
43ef1263 1052 $contactID = $this->individualCreate();
66670e4d 1053 $result = $this->callAPISuccess('address', 'create', array(
92915c55
TO
1054 'contact_id' => $contactID,
1055 'address_name' => 'My house',
1056 'location_type_id' => 'Home',
1057 'street_address' => '1 my road',
1058 ));
66670e4d 1059 $addressID = $result['id'];
1060
5896d037 1061 $result = $this->callAPISuccessGetSingle('contact', array(
66670e4d 1062 'return' => 'address_name, street_address, address_id',
92915c55
TO
1063 'id' => $contactID,
1064 ));
66670e4d 1065 $this->assertEquals($addressID, $result['address_id']);
43ef1263
EM
1066 $this->assertEquals('1 my road', $result['street_address']);
1067 $this->assertEquals('My house', $result['address_name']);
1068
1069 }
1070
701a69da 1071 /**
1072 * Test group filter syntaxes.
1073 */
00be9182 1074 public function testGetGroupIDFromContact() {
5896d037 1075 $groupId = $this->groupCreate();
5896d037 1076 $params = array(
6a488035
TO
1077 'email' => 'man2@yahoo.com',
1078 'contact_type' => 'Individual',
1079 'location_type_id' => 1,
6a488035
TO
1080 'api.group_contact.create' => array('group_id' => $groupId),
1081 );
1082
4b58ed3b 1083 $this->callAPISuccess('contact', 'create', $params);
6a488035
TO
1084 // testing as integer
1085 $params = array(
d0aa0e47 1086 'filter.group_id' => $groupId,
6a488035
TO
1087 'contact_type' => 'Individual',
1088 );
d0aa0e47 1089 $result = $this->callAPISuccess('contact', 'get', $params);
6a488035
TO
1090 $this->assertEquals(1, $result['count']);
1091 // group 26 doesn't exist, but we can still search contacts in it.
1092 $params = array(
d0aa0e47 1093 'filter.group_id' => 26,
6a488035
TO
1094 'contact_type' => 'Individual',
1095 );
4b58ed3b 1096 $this->callAPISuccess('contact', 'get', $params);
6a488035
TO
1097 // testing as string
1098 $params = array(
d0aa0e47 1099 'filter.group_id' => "$groupId, 26",
6a488035
TO
1100 'contact_type' => 'Individual',
1101 );
d0aa0e47 1102 $result = $this->callAPISuccess('contact', 'get', $params);
6a488035
TO
1103 $this->assertEquals(1, $result['count']);
1104 $params = array(
d0aa0e47 1105 'filter.group_id' => "26,27",
6a488035
TO
1106 'contact_type' => 'Individual',
1107 );
4b58ed3b 1108 $this->callAPISuccess('contact', 'get', $params);
6a488035
TO
1109
1110 // testing as string
6c6e6187 1111 $params = array(
d0aa0e47 1112 'filter.group_id' => array($groupId, 26),
6a488035
TO
1113 'contact_type' => 'Individual',
1114 );
d0aa0e47 1115 $result = $this->callAPISuccess('contact', 'get', $params);
6a488035
TO
1116 $this->assertEquals(1, $result['count']);
1117
1118 //test in conjunction with other criteria
6c6e6187 1119 $params = array(
d0aa0e47 1120 'filter.group_id' => array($groupId, 26),
6a488035
TO
1121 'contact_type' => 'Organization',
1122 );
6c6e6187
TO
1123 $this->callAPISuccess('contact', 'get', $params);
1124 $params = array(
d0aa0e47 1125 'filter.group_id' => array(26, 27),
6a488035
TO
1126 'contact_type' => 'Individual',
1127 );
f6722559 1128 $result = $this->callAPISuccess('contact', 'get', $params);
4b58ed3b 1129 $this->assertEquals(0, $result['count']);
6a488035
TO
1130 }
1131
1132 /**
381fa321 1133 * Verify that attempt to create individual contact with two chained websites succeeds.
6a488035 1134 */
00be9182 1135 public function testCreateIndividualWithContributionDottedSyntax() {
5c49fee0 1136 $description = "This demonstrates the syntax to create 2 chained entities.";
5896d037
TO
1137 $subFile = "ChainTwoWebsites";
1138 $params = array(
6a488035
TO
1139 'first_name' => 'abc3',
1140 'last_name' => 'xyz3',
1141 'contact_type' => 'Individual',
1142 'email' => 'man3@yahoo.com',
6a488035
TO
1143 'api.contribution.create' => array(
1144 'receive_date' => '2010-01-01',
1145 'total_amount' => 100.00,
5896d037 1146 'financial_type_id' => $this->_financialTypeId,
6a488035
TO
1147 'payment_instrument_id' => 1,
1148 'non_deductible_amount' => 10.00,
1149 'fee_amount' => 50.00,
1150 'net_amount' => 90.00,
1151 'trxn_id' => 15345,
1152 'invoice_id' => 67990,
1153 'source' => 'SSF',
1154 'contribution_status_id' => 1,
1155 ),
1156 'api.website.create' => array(
1157 'url' => "http://civicrm.org",
1158 ),
1159 'api.website.create.2' => array(
1160 'url' => "http://chained.org",
1161 ),
1162 );
1163
4b58ed3b 1164 $result = $this->callAPIAndDocument('Contact', 'create', $params, __FUNCTION__, __FILE__, $description, $subFile);
6a488035 1165
f6722559 1166 // checking child function result not covered in callAPIAndDocument
1167 $this->assertAPISuccess($result['values'][$result['id']]['api.website.create']);
fe482240
EM
1168 $this->assertEquals("http://chained.org", $result['values'][$result['id']]['api.website.create.2']['values'][0]['url']);
1169 $this->assertEquals("http://civicrm.org", $result['values'][$result['id']]['api.website.create']['values'][0]['url']);
6a488035
TO
1170
1171 // delete the contact
f6722559 1172 $this->callAPISuccess('contact', 'delete', $result);
6a488035
TO
1173 }
1174
1175 /**
381fa321 1176 * Verify that attempt to create individual contact with chained contribution and website succeeds.
6a488035 1177 */
00be9182 1178 public function testCreateIndividualWithContributionChainedArrays() {
6a488035
TO
1179 $params = array(
1180 'first_name' => 'abc3',
1181 'last_name' => 'xyz3',
1182 'contact_type' => 'Individual',
1183 'email' => 'man3@yahoo.com',
6a488035
TO
1184 'api.contribution.create' => array(
1185 'receive_date' => '2010-01-01',
1186 'total_amount' => 100.00,
5896d037 1187 'financial_type_id' => $this->_financialTypeId,
6a488035
TO
1188 'payment_instrument_id' => 1,
1189 'non_deductible_amount' => 10.00,
1190 'fee_amount' => 50.00,
1191 'net_amount' => 90.00,
1192 'trxn_id' => 12345,
1193 'invoice_id' => 67890,
1194 'source' => 'SSF',
1195 'contribution_status_id' => 1,
1196 ),
1197 'api.website.create' => array(
1198 array(
1199 'url' => "http://civicrm.org",
1200 ),
1201 array(
1202 'url' => "http://chained.org",
1203 'website_type_id' => 2,
1204 ),
1205 ),
1206 );
1207
5c49fee0 1208 $description = "Demonstrates creating two websites as an array.";
5896d037
TO
1209 $subfile = "ChainTwoWebsitesSyntax2";
1210 $result = $this->callAPIAndDocument('Contact', 'create', $params, __FUNCTION__, __FILE__, $description, $subfile);
f6722559 1211
f6722559 1212 // the callAndDocument doesn't check the chained call
fe482240
EM
1213 $this->assertEquals(0, $result['values'][$result['id']]['api.website.create'][0]['is_error']);
1214 $this->assertEquals("http://chained.org", $result['values'][$result['id']]['api.website.create'][1]['values'][0]['url']);
1215 $this->assertEquals("http://civicrm.org", $result['values'][$result['id']]['api.website.create'][0]['values'][0]['url']);
6a488035 1216
f6722559 1217 $this->callAPISuccess('contact', 'delete', $result);
6a488035
TO
1218 }
1219
92d270fd
JV
1220 /**
1221 * Test for direction when chaining relationships.
1222 *
1223 * https://issues.civicrm.org/jira/browse/CRM-16084
1224 */
1225 public function testDirectionChainingRelationshipsCRM16084() {
1226 // Some contact, called Jules.
1227 $create_result_1 = $this->callAPISuccess('contact', 'create', array(
1228 'first_name' => 'Jules',
1229 'last_name' => 'Smos',
1230 'contact_type' => 'Individual',
1231 ));
1232
1233 // Another contact: Jos, child of Jules.
1234 $create_params = array(
1235 'first_name' => 'Jos',
1236 'last_name' => 'Smos',
1237 'contact_type' => 'Individual',
1238 'api.relationship.create' => array(
1239 array(
1240 'contact_id_a' => '$value.id',
1241 'contact_id_b' => $create_result_1['id'],
1242 // child of
1243 'relationship_type_id' => 1,
1244 ),
1245 ),
1246 );
1247 $create_result_2 = $this->callAPISuccess('contact', 'create', $create_params);
1248
1249 // Mia is the child of Jos.
1250 $create_params = array(
1251 'first_name' => 'Mia',
1252 'last_name' => 'Smos',
1253 'contact_type' => 'Individual',
1254 'api.relationship.create' => array(
1255 array(
1256 'contact_id_a' => '$value.id',
1257 'contact_id_b' => $create_result_2['id'],
1258 // child of
1259 'relationship_type_id' => 1,
1260 ),
1261 ),
1262 );
1263 $create_result_3 = $this->callAPISuccess('contact', 'create', $create_params);
1264
1265 // Get Jos and his children.
1266 $get_params = array(
1267 'sequential' => 1,
1268 'id' => $create_result_2['id'],
1269 'api.relationship.get' => array(
1270 'contact_id_b' => '$value.id',
1271 'relationship_type_id' => 1,
1272 ),
1273 );
1274 $get_result = $this->callAPISuccess('contact', 'getsingle', $get_params);
1275
1276 // Clean up first.
1277 $this->callAPISuccess('contact', 'delete', array(
1278 'id' => $create_result_1['id'],
1279 ));
1280 $this->callAPISuccess('contact', 'delete', array(
1281 'id' => $create_result_2['id'],
1282 ));
1283 $this->callAPISuccess('contact', 'delete', array(
1284 'id' => $create_result_2['id'],
1285 ));
1286
1287 // Assert.
1288 $this->assertEquals(1, $get_result['api.relationship.get']['count']);
1289 $this->assertEquals($create_result_3['id'], $get_result['api.relationship.get']['values'][0]['contact_id_a']);
1290 }
1291
6a488035 1292 /**
fe482240 1293 * Verify that attempt to create individual contact with first, and last names and email succeeds.
6a488035 1294 */
00be9182 1295 public function testCreateIndividualWithNameEmail() {
6a488035
TO
1296 $params = array(
1297 'first_name' => 'abc3',
1298 'last_name' => 'xyz3',
1299 'contact_type' => 'Individual',
1300 'email' => 'man3@yahoo.com',
6a488035
TO
1301 );
1302
f6722559 1303 $contact = $this->callAPISuccess('contact', 'create', $params);
6a488035 1304
f6722559 1305 $this->callAPISuccess('contact', 'delete', $contact);
6a488035 1306 }
5896d037 1307
6a488035 1308 /**
eceb18cc 1309 * Verify that attempt to create individual contact with no data fails.
6a488035 1310 */
00be9182 1311 public function testCreateIndividualWithOutNameEmail() {
6a488035
TO
1312 $params = array(
1313 'contact_type' => 'Individual',
6a488035 1314 );
4b58ed3b 1315 $this->callAPIFailure('contact', 'create', $params);
6a488035 1316 }
5896d037 1317
6a488035 1318 /**
fe482240 1319 * Test create individual contact with first &last names, email and location type succeeds.
6a488035 1320 */
00be9182 1321 public function testCreateIndividualWithNameEmailLocationType() {
6a488035
TO
1322 $params = array(
1323 'first_name' => 'abc4',
1324 'last_name' => 'xyz4',
1325 'email' => 'man4@yahoo.com',
1326 'contact_type' => 'Individual',
1327 'location_type_id' => 1,
6a488035 1328 );
f6722559 1329 $result = $this->callAPISuccess('contact', 'create', $params);
6a488035 1330
f6722559 1331 $this->callAPISuccess('contact', 'delete', array('id' => $result['id']));
6a488035
TO
1332 }
1333
1334 /**
fe482240 1335 * Verify that when changing employers the old employer relationship becomes inactive.
6a488035 1336 */
00be9182 1337 public function testCreateIndividualWithEmployer() {
6a488035
TO
1338 $employer = $this->organizationCreate();
1339 $employer2 = $this->organizationCreate();
1340
1341 $params = array(
5896d037
TO
1342 'email' => 'man4@yahoo.com',
1343 'contact_type' => 'Individual',
1344 'employer_id' => $employer,
6a488035
TO
1345 );
1346
f6722559 1347 $result = $this->callAPISuccess('contact', 'create', $params);
1348 $relationships = $this->callAPISuccess('relationship', 'get', array(
6a488035
TO
1349 'contact_id_a' => $result['id'],
1350 'sequential' => 1,
1351 ));
1352
1353 $this->assertEquals($employer, $relationships['values'][0]['contact_id_b']);
1354
1355 // Add more random relationships to make the test more realistic
4b58ed3b
EM
1356 foreach (array('Employee of', 'Volunteer for') as $relationshipType) {
1357 $relTypeId = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_RelationshipType', $relationshipType, 'id', 'name_a_b');
1358 $this->callAPISuccess('relationship', 'create', array(
6a488035
TO
1359 'contact_id_a' => $result['id'],
1360 'contact_id_b' => $this->organizationCreate(),
1361 'is_active' => 1,
1362 'relationship_type_id' => $relTypeId,
1363 ));
6c6e6187 1364 }
6a488035
TO
1365
1366 // Add second employer
1367 $params['employer_id'] = $employer2;
1368 $params['id'] = $result['id'];
f6722559 1369 $result = $this->callAPISuccess('contact', 'create', $params);
6a488035 1370
f6722559 1371 $relationships = $this->callAPISuccess('relationship', 'get', array(
6a488035
TO
1372 'contact_id_a' => $result['id'],
1373 'sequential' => 1,
1374 'is_active' => 0,
1375 ));
1376
1377 $this->assertEquals($employer, $relationships['values'][0]['contact_id_b']);
1378 }
1379
1380 /**
fe482240 1381 * Verify that attempt to create household contact with details succeeds.
6a488035 1382 */
00be9182 1383 public function testCreateHouseholdDetails() {
6a488035
TO
1384 $params = array(
1385 'household_name' => 'abc8\'s House',
1386 'nick_name' => 'x House',
1387 'email' => 'man8@yahoo.com',
1388 'contact_type' => 'Household',
6a488035
TO
1389 );
1390
f6722559 1391 $contact = $this->callAPISuccess('contact', 'create', $params);
1392
f6722559 1393 $this->callAPISuccess('contact', 'delete', $contact);
6a488035 1394 }
5896d037 1395
6a488035 1396 /**
381fa321 1397 * Verify that attempt to create household contact with inadequate details fails.
6a488035 1398 */
00be9182 1399 public function testCreateHouseholdInadequateDetails() {
6a488035
TO
1400 $params = array(
1401 'nick_name' => 'x House',
1402 'email' => 'man8@yahoo.com',
1403 'contact_type' => 'Household',
6a488035 1404 );
4b58ed3b 1405 $this->callAPIFailure('contact', 'create', $params);
6a488035
TO
1406 }
1407
6a488035 1408 /**
381fa321 1409 * Verify successful update of individual contact.
6a488035 1410 */
00be9182 1411 public function testUpdateIndividualWithAll() {
381fa321 1412 // Insert a row in civicrm_contact creating individual contact.
6a488035
TO
1413 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1414 $op->execute($this->_dbconn,
bbfd46a5 1415 $this->createXMLDataSet(
6a488035
TO
1416 dirname(__FILE__) . '/dataset/contact_ind.xml'
1417 )
1418 );
1419
1420 $params = array(
1421 'id' => 23,
1422 'first_name' => 'abcd',
1423 'contact_type' => 'Individual',
1424 'nick_name' => 'This is nickname first',
1425 'do_not_email' => '1',
1426 'do_not_phone' => '1',
1427 'do_not_mail' => '1',
1428 'do_not_trade' => '1',
1429 'legal_identifier' => 'ABC23853ZZ2235',
1430 'external_identifier' => '1928837465',
1431 'image_URL' => 'http://some.url.com/image.jpg',
1432 'home_url' => 'http://www.example.org',
f6722559 1433
1434 );
43ef1263 1435
4b58ed3b 1436 $this->callAPISuccess('Contact', 'Update', $params);
f6722559 1437 $getResult = $this->callAPISuccess('Contact', 'Get', $params);
6a488035
TO
1438 unset($params['contact_id']);
1439 //Todo - neither API v2 or V3 are testing for home_url - not sure if it is being set.
4b58ed3b 1440 //reducing this test partially back to api v2 level to get it through
6a488035
TO
1441 unset($params['home_url']);
1442 foreach ($params as $key => $value) {
4b58ed3b 1443 $this->assertEquals($value, $getResult['values'][23][$key]);
6a488035 1444 }
381fa321 1445 // Check updated civicrm_contact against expected.
bbfd46a5 1446 $expected = $this->createXMLDataSet(
6a488035
TO
1447 dirname(__FILE__) . '/dataset/contact_ind_upd.xml'
1448 );
bbfd46a5 1449 $actual = new PHPUnit_Extensions_Database_DataSet_QueryDataSet(
6a488035
TO
1450 $this->_dbconn
1451 );
1452 $actual->addTable('civicrm_contact');
1453 $expected->matches($actual);
1454 }
1455
1456 /**
eceb18cc 1457 * Verify successful update of organization contact.
6a488035 1458 */
00be9182 1459 public function testUpdateOrganizationWithAll() {
381fa321 1460 // Insert a row in civicrm_contact creating organization contact
6a488035
TO
1461 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1462 $op->execute($this->_dbconn,
bbfd46a5 1463 $this->createXMLDataSet(
6a488035
TO
1464 dirname(__FILE__) . '/dataset/contact_org.xml'
1465 )
1466 );
1467
1468 $params = array(
1469 'id' => 24,
1470 'organization_name' => 'WebAccess India Pvt Ltd',
1471 'legal_name' => 'WebAccess',
1472 'sic_code' => 'ABC12DEF',
1473 'contact_type' => 'Organization',
6a488035
TO
1474 );
1475
4b58ed3b 1476 $this->callAPISuccess('Contact', 'Update', $params);
6a488035 1477
381fa321 1478 // Check updated civicrm_contact against expected.
bbfd46a5 1479 $expected = $this->createXMLDataSet(
6a488035
TO
1480 dirname(__FILE__) . '/dataset/contact_org_upd.xml'
1481 );
bbfd46a5 1482 $actual = new PHPUnit_Extensions_Database_DataSet_QueryDataSet(
6a488035
TO
1483 $this->_dbconn
1484 );
1485 $actual->addTable('civicrm_contact');
1486 $expected->matches($actual);
1487 }
1488
1489 /**
381fa321 1490 * Verify successful update of household contact.
6a488035 1491 */
381fa321 1492 public function testUpdateHouseholdWithAll() {
1493 // Insert a row in civicrm_contact creating household contact
6a488035
TO
1494 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1495 $op->execute($this->_dbconn,
bbfd46a5 1496 $this->createXMLDataSet(
6a488035
TO
1497 dirname(__FILE__) . '/dataset/contact_hld.xml'
1498 )
1499 );
1500
1501 $params = array(
1502 'id' => 25,
1503 'household_name' => 'ABC household',
1504 'nick_name' => 'ABC House',
1505 'contact_type' => 'Household',
6a488035
TO
1506 );
1507
f6722559 1508 $result = $this->callAPISuccess('Contact', 'Update', $params);
6a488035 1509
43ef1263
EM
1510 $expected = array(
1511 'contact_type' => 'Household',
1512 'is_opt_out' => 0,
1513 'sort_name' => 'ABC household',
1514 'display_name' => 'ABC household',
1515 'nick_name' => 'ABC House',
6a488035 1516 );
43ef1263 1517 $this->getAndCheck($expected, $result['id'], 'contact');
6a488035
TO
1518 }
1519
1520 /**
381fa321 1521 * Test civicrm_update() without contact type.
1522 *
1523 * Deliberately exclude contact_type as it should still cope using civicrm_api.
1524 *
1525 * CRM-7645.
6a488035 1526 */
6a488035 1527 public function testUpdateCreateWithID() {
381fa321 1528 // Insert a row in civicrm_contact creating individual contact.
6a488035
TO
1529 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1530 $op->execute($this->_dbconn,
bbfd46a5 1531 $this->createXMLDataSet(
6a488035
TO
1532 dirname(__FILE__) . '/dataset/contact_ind.xml'
1533 )
1534 );
1535
6a488035
TO
1536 $params = array(
1537 'id' => 23,
1538 'first_name' => 'abcd',
1539 'last_name' => 'wxyz',
6a488035 1540 );
4b58ed3b 1541 $this->callAPISuccess('Contact', 'Update', $params);
6a488035
TO
1542 }
1543
1544 /**
381fa321 1545 * Test civicrm_contact_delete() with no contact ID.
6a488035 1546 */
00be9182 1547 public function testContactDeleteNoID() {
6a488035
TO
1548 $params = array(
1549 'foo' => 'bar',
6a488035 1550 );
4b58ed3b 1551 $this->callAPIFailure('contact', 'delete', $params);
6a488035
TO
1552 }
1553
1554 /**
381fa321 1555 * Test civicrm_contact_delete() with error.
6a488035 1556 */
00be9182 1557 public function testContactDeleteError() {
f6722559 1558 $params = array('contact_id' => 999);
4b58ed3b 1559 $this->callAPIFailure('contact', 'delete', $params);
6a488035
TO
1560 }
1561
1562 /**
381fa321 1563 * Test civicrm_contact_delete().
6a488035 1564 */
00be9182 1565 public function testContactDelete() {
f6722559 1566 $contactID = $this->individualCreate();
6a488035 1567 $params = array(
5896d037 1568 'id' => $contactID,
6a488035 1569 );
4b58ed3b 1570 $this->callAPIAndDocument('contact', 'delete', $params, __FUNCTION__, __FILE__);
6a488035
TO
1571 }
1572
1573 /**
381fa321 1574 * Test civicrm_contact_get() return only first name.
6a488035
TO
1575 */
1576 public function testContactGetRetFirst() {
f6722559 1577 $contact = $this->callAPISuccess('contact', 'create', $this->_params);
6a488035
TO
1578 $params = array(
1579 'contact_id' => $contact['id'],
1580 'return_first_name' => TRUE,
1581 'sort' => 'first_name',
6a488035 1582 );
f6722559 1583 $result = $this->callAPISuccess('contact', 'get', $params);
4b58ed3b
EM
1584 $this->assertEquals(1, $result['count']);
1585 $this->assertEquals($contact['id'], $result['id']);
1586 $this->assertEquals('abc1', $result['values'][$contact['id']]['first_name']);
6a488035
TO
1587 }
1588
1589 /**
381fa321 1590 * Test civicrm_contact_get() return only first name & last name.
1591 *
1592 * Use comma separated string return with a space.
6a488035 1593 */
381fa321 1594 public function testContactGetReturnFirstLast() {
f6722559 1595 $contact = $this->callAPISuccess('contact', 'create', $this->_params);
6a488035
TO
1596 $params = array(
1597 'contact_id' => $contact['id'],
1598 'return' => 'first_name, last_name',
6a488035 1599 );
f6722559 1600 $result = $this->callAPISuccess('contact', 'getsingle', $params);
4b58ed3b
EM
1601 $this->assertEquals('abc1', $result['first_name']);
1602 $this->assertEquals('xyz1', $result['last_name']);
6a488035
TO
1603 //check that other defaults not returns
1604 $this->assertArrayNotHasKey('sort_name', $result);
1605 $params = array(
1606 'contact_id' => $contact['id'],
1607 'return' => 'first_name,last_name',
6a488035 1608 );
f6722559 1609 $result = $this->callAPISuccess('contact', 'getsingle', $params);
4b58ed3b
EM
1610 $this->assertEquals('abc1', $result['first_name']);
1611 $this->assertEquals('xyz1', $result['last_name']);
6a488035
TO
1612 //check that other defaults not returns
1613 $this->assertArrayNotHasKey('sort_name', $result);
1614 }
1615
1616 /**
381fa321 1617 * Test civicrm_contact_get() return only first name & last name.
1618 *
d177a2a6 1619 * Use comma separated string return without a space
6a488035 1620 */
381fa321 1621 public function testContactGetReturnFirstLastNoComma() {
f6722559 1622 $contact = $this->callAPISuccess('contact', 'create', $this->_params);
6a488035
TO
1623 $params = array(
1624 'contact_id' => $contact['id'],
1625 'return' => 'first_name,last_name',
6a488035 1626 );
f6722559 1627 $result = $this->callAPISuccess('contact', 'getsingle', $params);
4b58ed3b
EM
1628 $this->assertEquals('abc1', $result['first_name']);
1629 $this->assertEquals('xyz1', $result['last_name']);
6a488035
TO
1630 //check that other defaults not returns
1631 $this->assertArrayNotHasKey('sort_name', $result);
1632 }
1633
1634 /**
381fa321 1635 * Test civicrm_contact_get() with default return properties.
6a488035
TO
1636 */
1637 public function testContactGetRetDefault() {
43ef1263 1638 $contactID = $this->individualCreate();
6a488035 1639 $params = array(
43ef1263 1640 'contact_id' => $contactID,
6a488035 1641 'sort' => 'first_name',
6a488035 1642 );
f6722559 1643 $result = $this->callAPISuccess('contact', 'get', $params);
43ef1263
EM
1644 $this->assertEquals($contactID, $result['values'][$contactID]['contact_id']);
1645 $this->assertEquals('Anthony', $result['values'][$contactID]['first_name']);
6a488035
TO
1646 }
1647
1648 /**
381fa321 1649 * Test civicrm_contact_getquick() with empty name param.
6a488035
TO
1650 */
1651 public function testContactGetQuick() {
fe482240 1652 // Insert a row in civicrm_contact creating individual contact.
6a488035
TO
1653 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1654 $op->execute($this->_dbconn,
bbfd46a5 1655 $this->createXMLDataSet(
6a488035
TO
1656 dirname(__FILE__) . '/dataset/contact_17.xml'
1657 )
1658 );
1659 $op->execute($this->_dbconn,
bbfd46a5 1660 $this->createXMLDataSet(
6a488035
TO
1661 dirname(__FILE__) . '/dataset/email_contact_17.xml'
1662 )
1663 );
1664 $params = array(
1665 'name' => "T",
6a488035
TO
1666 );
1667
1d6020f1 1668 $result = $this->callAPISuccess('contact', 'getquick', $params);
fe482240 1669 $this->assertEquals(17, $result['values'][0]['id']);
6a488035
TO
1670 }
1671
1672 /**
fe482240 1673 * Test civicrm_contact_get) with empty params.
6a488035
TO
1674 */
1675 public function testContactGetEmptyParams() {
4b58ed3b 1676 $this->callAPISuccess('contact', 'get', array());
6a488035
TO
1677 }
1678
1679 /**
fe482240 1680 * Test civicrm_contact_get(,true) with no matches.
6a488035
TO
1681 */
1682 public function testContactGetOldParamsNoMatches() {
fe482240 1683 // Insert a row in civicrm_contact creating contact 17.
6a488035
TO
1684 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1685 $op->execute($this->_dbconn,
bbfd46a5 1686 $this->createXMLDataSet(
6a488035
TO
1687 dirname(__FILE__) . '/dataset/contact_17.xml'
1688 )
1689 );
1690
1691 $params = array(
1692 'first_name' => 'Fred',
6a488035 1693 );
f6722559 1694 $result = $this->callAPISuccess('contact', 'get', $params);
fe482240 1695 $this->assertEquals(0, $result['count']);
6a488035
TO
1696 }
1697
1698 /**
fe482240 1699 * Test civicrm_contact_get(,true) with one match.
6a488035
TO
1700 */
1701 public function testContactGetOldParamsOneMatch() {
fe482240 1702 // Insert a row in civicrm_contact creating contact 17
6a488035
TO
1703 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1704 $op->execute($this->_dbconn,
bbfd46a5 1705 $this->createXMLDataSet(dirname(__FILE__) . '/dataset/contact_17.xml'
6a488035
TO
1706 )
1707 );
1708
1709 $params = array(
1710 'first_name' => 'Test',
6a488035 1711 );
f6722559 1712 $result = $this->callAPISuccess('contact', 'get', $params);
fe482240
EM
1713 $this->assertEquals(17, $result['values'][17]['contact_id']);
1714 $this->assertEquals(17, $result['id']);
6a488035 1715 }
6a488035
TO
1716
1717 /**
fe482240 1718 * Test civicrm_contact_search_count().
6a488035
TO
1719 */
1720 public function testContactGetEmail() {
1721 $params = array(
1722 'email' => 'man2@yahoo.com',
1723 'contact_type' => 'Individual',
1724 'location_type_id' => 1,
6a488035
TO
1725 );
1726
f6722559 1727 $contact = $this->callAPISuccess('contact', 'create', $params);
1728
6a488035
TO
1729 $params = array(
1730 'email' => 'man2@yahoo.com',
6a488035 1731 );
f6722559 1732 $result = $this->callAPIAndDocument('contact', 'get', $params, __FUNCTION__, __FILE__);
c8747697 1733 $this->assertEquals('man2@yahoo.com', $result['values'][$result['id']]['email']);
6a488035 1734
f6722559 1735 $this->callAPISuccess('contact', 'delete', $contact);
6a488035
TO
1736 }
1737
37f7ae88 1738 /**
1739 * Ensure consistent return format for option group fields.
1740 */
1741 public function testSetPreferredCommunicationNull() {
1742 $contact = $this->callAPISuccess('contact', 'create', array_merge($this->_params, array(
1743 'preferred_communication_method' => array('Phone', 'SMS'),
1744 )));
1745 $preferredCommunicationMethod = $this->callAPISuccessGetValue('Contact', array(
1746 'id' => $contact['id'],
1747 'return' => 'preferred_communication_method',
1748 ));
1749 $this->assertNotEmpty($preferredCommunicationMethod);
1750 $contact = $this->callAPISuccess('contact', 'create', array_merge($this->_params, array(
1751 'preferred_communication_method' => 'null',
1752 'id' => $contact['id'],
1753 )));
1754 $preferredCommunicationMethod = $this->callAPISuccessGetValue('Contact', array(
1755 'id' => $contact['id'],
1756 'return' => 'preferred_communication_method',
1757 ));
1758 $this->assertEmpty($preferredCommunicationMethod);
1759 }
1760
86ab13b7 1761 /**
1762 * Ensure consistent return format for option group fields.
1763 */
1764 public function testPseudoFields() {
1765 $params = array(
1766 'preferred_communication_method' => array('Phone', 'SMS'),
1767 'preferred_language' => 'en_US',
1768 'gender_id' => 'Female',
1769 'prefix_id' => 'Mrs.',
1770 'suffix_id' => 'II',
1771 'communication_style_id' => 'Formal',
1772 );
1773
1774 $contact = $this->callAPISuccess('contact', 'create', array_merge($this->_params, $params));
1775
1776 $result = $this->callAPISuccess('contact', 'getsingle', array('id' => $contact['id']));
1777 $this->assertEquals('Both', $result['preferred_mail_format']);
1778
1779 $this->assertEquals('en_US', $result['preferred_language']);
1780 $this->assertEquals(1, $result['communication_style_id']);
1781 $this->assertEquals(1, $result['gender_id']);
1782 $this->assertEquals('Female', $result['gender']);
1783 $this->assertEquals('Mrs.', $result['individual_prefix']);
1784 $this->assertEquals(1, $result['prefix_id']);
1785 $this->assertEquals('II', $result['individual_suffix']);
1786 $this->assertEquals(CRM_Core_PseudoConstant::getKey("CRM_Contact_BAO_Contact", 'suffix_id', 'II'), $result['suffix_id']);
1787 $this->callAPISuccess('contact', 'delete', $contact);
1788 $this->assertEquals(array(
1789 CRM_Core_PseudoConstant::getKey("CRM_Contact_BAO_Contact", 'preferred_communication_method', 'Phone'),
1790 CRM_Core_PseudoConstant::getKey("CRM_Contact_BAO_Contact", 'preferred_communication_method', 'SMS'),
1791 ), $result['preferred_communication_method']);
1792 }
1793
1794
b1f09bea 1795 /**
fe482240
EM
1796 * Test birth date parameters.
1797 *
1798 * These include value, array & birth_date_high, birth_date_low
1799 * && deceased.
b1f09bea 1800 */
4b58ed3b 1801 public function testContactGetBirthDate() {
b1f09bea
E
1802 $contact1 = $this->callAPISuccess('contact', 'create', array_merge($this->_params, array('birth_date' => 'first day of next month - 2 years')));
1803 $contact2 = $this->callAPISuccess('contact', 'create', array_merge($this->_params, array('birth_date' => 'first day of next month - 5 years')));
1804 $contact3 = $this->callAPISuccess('contact', 'create', array_merge($this->_params, array('birth_date' => 'first day of next month -20 years')));
1805
1806 $result = $this->callAPISuccess('contact', 'get', array());
1807 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -2 years')), $result['values'][$contact1['id']]['birth_date']);
1808 $result = $this->callAPISuccess('contact', 'get', array('birth_date' => 'first day of next month -5 years'));
1809 $this->assertEquals(1, $result['count']);
1810 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -5 years')), $result['values'][$contact2['id']]['birth_date']);
1811 $result = $this->callAPISuccess('contact', 'get', array('birth_date_high' => date('Y-m-d', strtotime('-6 years'))));
1812 $this->assertEquals(1, $result['count']);
1813 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -20 years')), $result['values'][$contact3['id']]['birth_date']);
5896d037 1814 $result = $this->callAPISuccess('contact', 'get', array(
92915c55
TO
1815 'birth_date_low' => date('Y-m-d', strtotime('-6 years')),
1816 'birth_date_high' => date('Y-m-d', strtotime('- 3 years')),
1817 ));
b1f09bea
E
1818 $this->assertEquals(1, $result['count']);
1819 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -5 years')), $result['values'][$contact2['id']]['birth_date']);
5896d037 1820 $result = $this->callAPISuccess('contact', 'get', array(
92915c55
TO
1821 'birth_date_low' => '-6 years',
1822 'birth_date_high' => '- 3 years',
1823 ));
9f60788a
EM
1824 $this->assertEquals(1, $result['count']);
1825 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -5 years')), $result['values'][$contact2['id']]['birth_date']);
b1f09bea
E
1826 }
1827
d0bfb983 1828 /**
1829 * Test Address parameters
1830 *
1831 * This include state_province, state_province_name, country
1832 */
1833 public function testContactGetWithAddressFields() {
1834 $individuals = array(
1835 array(
1836 'first_name' => 'abc1',
1837 'contact_type' => 'Individual',
1838 'last_name' => 'xyz1',
1839 'api.address.create' => array(
1840 'country' => 'United States',
1841 'state_province_id' => 'Michigan',
1842 'location_type_id' => 1,
1843 ),
1844 ),
1845 array(
1846 'first_name' => 'abc2',
1847 'contact_type' => 'Individual',
1848 'last_name' => 'xyz2',
1849 'api.address.create' => array(
1850 'country' => 'United States',
1851 'state_province_id' => 'Alabama',
1852 'location_type_id' => 1,
1853 ),
1854 ),
1855 );
1856 foreach ($individuals as $params) {
1857 $contact = $this->callAPISuccess('contact', 'create', $params);
1858 }
1859
1860 // Check whether Contact get API return successfully with below Address params.
1861 $fieldsToTest = array(
1862 'state_province_name' => 'Michigan',
1863 'state_province' => 'Michigan',
1864 'country' => 'United States',
1865 'state_province_name' => array('IN' => array('Michigan', 'Alabama')),
1866 'state_province' => array('IN' => array('Michigan', 'Alabama')),
1867 );
1868 foreach ($fieldsToTest as $field => $value) {
1869 $getParams = array(
1870 'id' => $contact['id'],
1871 $field => $value,
1872 );
41a74135 1873 $result = $this->callAPISuccess('Contact', 'get', $getParams);
1874 $this->assertEquals(1, $result['count']);
d0bfb983 1875 }
1876 }
1877
b1f09bea 1878 /**
fe482240
EM
1879 * Test Deceased date parameters.
1880 *
1881 * These include value, array & Deceased_date_high, Deceased date_low
d177a2a6 1882 * && deceased.
b1f09bea 1883 */
4b58ed3b 1884 public function testContactGetDeceasedDate() {
b1f09bea
E
1885 $contact1 = $this->callAPISuccess('contact', 'create', array_merge($this->_params, array('deceased_date' => 'first day of next month - 2 years')));
1886 $contact2 = $this->callAPISuccess('contact', 'create', array_merge($this->_params, array('deceased_date' => 'first day of next month - 5 years')));
1887 $contact3 = $this->callAPISuccess('contact', 'create', array_merge($this->_params, array('deceased_date' => 'first day of next month -20 years')));
1888
1889 $result = $this->callAPISuccess('contact', 'get', array());
1890 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -2 years')), $result['values'][$contact1['id']]['deceased_date']);
1891 $result = $this->callAPISuccess('contact', 'get', array('deceased_date' => 'first day of next month -5 years'));
1892 $this->assertEquals(1, $result['count']);
1893 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -5 years')), $result['values'][$contact2['id']]['deceased_date']);
1894 $result = $this->callAPISuccess('contact', 'get', array('deceased_date_high' => date('Y-m-d', strtotime('-6 years'))));
1895 $this->assertEquals(1, $result['count']);
1896 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -20 years')), $result['values'][$contact3['id']]['deceased_date']);
5896d037 1897 $result = $this->callAPISuccess('contact', 'get', array(
92915c55
TO
1898 'deceased_date_low' => '-6 years',
1899 'deceased_date_high' => date('Y-m-d', strtotime('- 3 years')),
1900 ));
b1f09bea
E
1901 $this->assertEquals(1, $result['count']);
1902 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -5 years')), $result['values'][$contact2['id']]['deceased_date']);
1903 }
1904
e635f9d4 1905 /**
fe482240 1906 * Test for Contact.get id=@user:username.
e635f9d4 1907 */
00be9182 1908 public function testContactGetByUsername() {
fe482240 1909 // Setup - create contact with a uf-match.
e635f9d4
TO
1910 $cid = $this->individualCreate(array(
1911 'contact_type' => 'Individual',
1912 'first_name' => 'testGetByUsername',
1913 'last_name' => 'testGetByUsername',
1914 ));
1915
1916 $ufMatchParams = array(
1917 'domain_id' => CRM_Core_Config::domainID(),
1918 'uf_id' => 99,
1919 'uf_name' => 'the-email-matching-key-is-not-really-the-username',
1920 'contact_id' => $cid,
1921 );
1922 $ufMatch = CRM_Core_BAO_UFMatch::create($ufMatchParams);
1923 $this->assertTrue(is_numeric($ufMatch->id));
1924
1925 // setup - mock the calls to CRM_Utils_System_*::getUfId
1926 $userSystem = $this->getMock('CRM_Utils_System_UnitTests', array('getUfId'));
1927 $userSystem->expects($this->once())
1928 ->method('getUfId')
1929 ->with($this->equalTo('exampleUser'))
1930 ->will($this->returnValue(99));
1931 CRM_Core_Config::singleton()->userSystem = $userSystem;
1932
1933 // perform a lookup
1934 $result = $this->callAPISuccess('Contact', 'get', array(
e635f9d4
TO
1935 'id' => '@user:exampleUser',
1936 ));
1937 $this->assertEquals('testGetByUsername', $result['values'][$cid]['first_name']);
1938 }
1939
265cc07d 1940 /**
eceb18cc 1941 * Test to check return works OK.
265cc07d 1942 */
00be9182 1943 public function testContactGetReturnValues() {
701a69da 1944 $extraParams = array(
1945 'nick_name' => 'Bob',
1946 'phone' => '456',
1947 'email' => 'e@mail.com',
1948 );
265cc07d 1949 $contactID = $this->individualCreate($extraParams);
1950 //actually it turns out the above doesn't create a phone
6c6e6187 1951 $this->callAPISuccess('phone', 'create', array('contact_id' => $contactID, 'phone' => '456'));
265cc07d 1952 $result = $this->callAPISuccess('contact', 'getsingle', array('id' => $contactID));
1953 foreach ($extraParams as $key => $value) {
1954 $this->assertEquals($result[$key], $value);
1955 }
1956 //now we check they are still returned with 'return' key
5896d037 1957 $result = $this->callAPISuccess('contact', 'getsingle', array(
92915c55
TO
1958 'id' => $contactID,
1959 'return' => array_keys($extraParams),
1960 ));
265cc07d 1961 foreach ($extraParams as $key => $value) {
1962 $this->assertEquals($result[$key], $value);
1963 }
1964 }
1965
701a69da 1966 /**
1967 * Test creating multiple phones using chaining.
1968 *
1969 * @throws \Exception
1970 */
00be9182 1971 public function testCRM13252MultipleChainedPhones() {
265cc07d 1972 $contactID = $this->householdCreate();
1973 $this->callAPISuccessGetCount('phone', array('contact_id' => $contactID), 0);
1974 $params = array(
5896d037
TO
1975 'contact_id' => $contactID,
1976 'household_name' => 'Household 1',
1977 'contact_type' => 'Household',
1978 'api.phone.create' => array(
265cc07d 1979 0 => array(
1980 'phone' => '111-111-1111',
1981 'location_type_id' => 1,
1982 'phone_type_id' => 1,
1983 ),
1984 1 => array(
1985 'phone' => '222-222-2222',
1986 'location_type_id' => 1,
1987 'phone_type_id' => 2,
21dfd5f5
TO
1988 ),
1989 ),
265cc07d 1990 );
4b58ed3b 1991 $this->callAPISuccess('contact', 'create', $params);
265cc07d 1992 $this->callAPISuccessGetCount('phone', array('contact_id' => $contactID), 2);
1993
1994 }
5896d037 1995
e635f9d4 1996 /**
fe482240 1997 * Test for Contact.get id=@user:username (with an invalid username).
e635f9d4 1998 */
00be9182 1999 public function testContactGetByUnknownUsername() {
e635f9d4
TO
2000 // setup - mock the calls to CRM_Utils_System_*::getUfId
2001 $userSystem = $this->getMock('CRM_Utils_System_UnitTests', array('getUfId'));
2002 $userSystem->expects($this->once())
2003 ->method('getUfId')
2004 ->with($this->equalTo('exampleUser'))
2005 ->will($this->returnValue(NULL));
2006 CRM_Core_Config::singleton()->userSystem = $userSystem;
2007
2008 // perform a lookup
2009 $result = $this->callAPIFailure('Contact', 'get', array(
e635f9d4
TO
2010 'id' => '@user:exampleUser',
2011 ));
2012 $this->assertRegExp('/cannot be resolved to a contact ID/', $result['error_message']);
2013 }
2014
6a488035 2015 /**
701a69da 2016 * Verify attempt to create individual with chained arrays and sequential.
48bb2598
JV
2017 */
2018 public function testGetIndividualWithChainedArraysAndSequential() {
2019 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__, __FILE__);
2020 $params['custom_' . $ids['custom_field_id']] = "custom string";
2021
84b51197 2022 $moreIDs = $this->CustomGroupMultipleCreateWithFields();
48bb2598
JV
2023 $params = array(
2024 'sequential' => 1,
2025 'first_name' => 'abc3',
2026 'last_name' => 'xyz3',
2027 'contact_type' => 'Individual',
2028 'email' => 'man3@yahoo.com',
2029 'api.website.create' => array(
2030 array(
2031 'url' => "http://civicrm.org",
2032 ),
2033 array(
2034 'url' => "https://civicrm.org",
2035 ),
2036 ),
2037 );
2038
2039 $result = $this->callAPISuccess('Contact', 'create', $params);
2040
48bb2598
JV
2041 // delete the contact and custom groups
2042 $this->callAPISuccess('contact', 'delete', array('id' => $result['id']));
2043 $this->customGroupDelete($ids['custom_group_id']);
84b51197 2044 $this->customGroupDelete($moreIDs['custom_group_id']);
48bb2598
JV
2045
2046 $this->assertEquals($result['id'], $result['values'][0]['id']);
2047 $this->assertArrayKeyExists('api.website.create', $result['values'][0]);
2048 }
2049
2050 /**
701a69da 2051 * Verify attempt to create individual with chained arrays.
6a488035 2052 */
00be9182 2053 public function testGetIndividualWithChainedArrays() {
6a488035
TO
2054 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__, __FILE__);
2055 $params['custom_' . $ids['custom_field_id']] = "custom string";
2056
381fa321 2057 $moreIDs = $this->CustomGroupMultipleCreateWithFields();
5c49fee0 2058 $description = "This demonstrates the usage of chained api functions.\nIn this case no notes or custom fields have been created.";
5896d037
TO
2059 $subfile = "APIChainedArray";
2060 $params = array(
6a488035
TO
2061 'first_name' => 'abc3',
2062 'last_name' => 'xyz3',
2063 'contact_type' => 'Individual',
2064 'email' => 'man3@yahoo.com',
6a488035
TO
2065 'api.contribution.create' => array(
2066 'receive_date' => '2010-01-01',
2067 'total_amount' => 100.00,
2068 'financial_type_id' => 1,
2069 'payment_instrument_id' => 1,
2070 'non_deductible_amount' => 10.00,
2071 'fee_amount' => 50.00,
2072 'net_amount' => 90.00,
2073 'trxn_id' => 12345,
2074 'invoice_id' => 67890,
2075 'source' => 'SSF',
2076 'contribution_status_id' => 1,
2077 ),
2078 'api.contribution.create.1' => array(
2079 'receive_date' => '2011-01-01',
2080 'total_amount' => 120.00,
6c6e6187 2081 'financial_type_id' => $this->_financialTypeId = 1,
6a488035
TO
2082 'payment_instrument_id' => 1,
2083 'non_deductible_amount' => 10.00,
2084 'fee_amount' => 50.00,
2085 'net_amount' => 90.00,
2086 'trxn_id' => 12335,
2087 'invoice_id' => 67830,
2088 'source' => 'SSF',
2089 'contribution_status_id' => 1,
2090 ),
2091 'api.website.create' => array(
2092 array(
2093 'url' => "http://civicrm.org",
2094 ),
2095 ),
2096 );
2097
f6722559 2098 $result = $this->callAPISuccess('Contact', 'create', $params);
6a488035 2099 $params = array(
f6722559 2100 'id' => $result['id'],
6a488035
TO
2101 'api.website.get' => array(),
2102 'api.Contribution.get' => array(
2103 'total_amount' => '120.00',
5896d037
TO
2104 ),
2105 'api.CustomValue.get' => 1,
6a488035
TO
2106 'api.Note.get' => 1,
2107 );
f6722559 2108 $result = $this->callAPIAndDocument('Contact', 'Get', $params, __FUNCTION__, __FILE__, $description, $subfile);
6a488035 2109 // delete the contact
f6722559 2110 $this->callAPISuccess('contact', 'delete', $result);
6a488035 2111 $this->customGroupDelete($ids['custom_group_id']);
381fa321 2112 $this->customGroupDelete($moreIDs['custom_group_id']);
4b58ed3b
EM
2113 $this->assertEquals(0, $result['values'][$result['id']]['api.website.get']['is_error']);
2114 $this->assertEquals("http://civicrm.org", $result['values'][$result['id']]['api.website.get']['values'][0]['url']);
6a488035
TO
2115 }
2116
a77b0380 2117 /**
701a69da 2118 * Verify attempt to create individual with chained arrays and sequential.
a77b0380
JV
2119 *
2120 * See https://issues.civicrm.org/jira/browse/CRM-15815
2121 */
2122 public function testCreateIndividualWithChainedArrayAndSequential() {
2123 $params = array(
2124 'sequential' => 1,
2125 'first_name' => 'abc5',
2126 'last_name' => 'xyz5',
2127 'contact_type' => 'Individual',
2128 'email' => 'woman5@yahoo.com',
2129 'api.phone.create' => array(
2130 array('phone' => '03-231 07 95'),
2131 array('phone' => '03-232 51 62'),
2132 ),
2133 'api.website.create' => array(
2134 'url' => 'http://civicrm.org',
2135 ),
2136 );
2137 $result = $this->callAPISuccess('Contact', 'create', $params);
2138
2139 // I could try to parse the result to see whether the two phone numbers
2140 // and the website are there, but I am not sure about the correct format.
2141 // So I will just fetch it again before checking.
2142 // See also http://forum.civicrm.org/index.php/topic,35393.0.html
2143 $params = array(
2144 'sequential' => 1,
2145 'id' => $result['id'],
2146 'api.website.get' => array(),
2147 'api.phone.get' => array(),
2148 );
2149 $result = $this->callAPISuccess('Contact', 'get', $params);
2150
2151 // delete the contact
2152 $this->callAPISuccess('contact', 'delete', $result);
2153
2154 $this->assertEquals(2, $result['values'][0]['api.phone.get']['count']);
2155 $this->assertEquals(1, $result['values'][0]['api.website.get']['count']);
2156 }
2157
701a69da 2158 /**
2159 * Test retrieving an individual with chained array syntax.
2160 */
00be9182 2161 public function testGetIndividualWithChainedArraysFormats() {
5c49fee0 2162 $description = "This demonstrates the usage of chained api functions.\nIn this case no notes or custom fields have been created.";
6a488035
TO
2163 $subfile = "APIChainedArrayFormats";
2164 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__, __FILE__);
2165 $params['custom_' . $ids['custom_field_id']] = "custom string";
2166
381fa321 2167 $moreIDs = $this->CustomGroupMultipleCreateWithFields();
6a488035
TO
2168 $params = array(
2169 'first_name' => 'abc3',
2170 'last_name' => 'xyz3',
2171 'contact_type' => 'Individual',
2172 'email' => 'man3@yahoo.com',
6a488035
TO
2173 'api.contribution.create' => array(
2174 'receive_date' => '2010-01-01',
2175 'total_amount' => 100.00,
f6722559 2176 'financial_type_id' => $this->_financialTypeId,
6a488035
TO
2177 'payment_instrument_id' => 1,
2178 'non_deductible_amount' => 10.00,
2179 'fee_amount' => 50.00,
2180 'net_amount' => 90.00,
2181 'source' => 'SSF',
2182 'contribution_status_id' => 1,
2183 ),
2184 'api.contribution.create.1' => array(
2185 'receive_date' => '2011-01-01',
2186 'total_amount' => 120.00,
f6722559 2187 'financial_type_id' => $this->_financialTypeId,
6a488035
TO
2188 'payment_instrument_id' => 1,
2189 'non_deductible_amount' => 10.00,
2190 'fee_amount' => 50.00,
2191 'net_amount' => 90.00,
2192 'source' => 'SSF',
2193 'contribution_status_id' => 1,
2194 ),
2195 'api.website.create' => array(
2196 array(
2197 'url' => "http://civicrm.org",
2198 ),
2199 ),
2200 );
2201
f6722559 2202 $result = $this->callAPISuccess('Contact', 'create', $params);
6a488035 2203 $params = array(
f6722559 2204 'id' => $result['id'],
6a488035
TO
2205 'api.website.getValue' => array('return' => 'url'),
2206 'api.Contribution.getCount' => array(),
2207 'api.CustomValue.get' => 1,
2208 'api.Note.get' => 1,
2209 'api.Membership.getCount' => array(),
2210 );
f6722559 2211 $result = $this->callAPIAndDocument('Contact', 'Get', $params, __FUNCTION__, __FILE__, $description, $subfile);
4b58ed3b
EM
2212 $this->assertEquals(2, $result['values'][$result['id']]['api.Contribution.getCount']);
2213 $this->assertEquals(0, $result['values'][$result['id']]['api.Note.get']['is_error']);
2214 $this->assertEquals("http://civicrm.org", $result['values'][$result['id']]['api.website.getValue']);
6a488035 2215
f6722559 2216 $this->callAPISuccess('contact', 'delete', $result);
6a488035 2217 $this->customGroupDelete($ids['custom_group_id']);
381fa321 2218 $this->customGroupDelete($moreIDs['custom_group_id']);
6a488035
TO
2219 }
2220
381fa321 2221 /**
2222 * Test complex chaining.
2223 */
00be9182 2224 public function testGetIndividualWithChainedArraysAndMultipleCustom() {
6a488035
TO
2225 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__, __FILE__);
2226 $params['custom_' . $ids['custom_field_id']] = "custom string";
381fa321 2227 $moreIDs = $this->CustomGroupMultipleCreateWithFields();
2228 $andMoreIDs = $this->CustomGroupMultipleCreateWithFields(array(
92915c55
TO
2229 'title' => "another group",
2230 'name' => 'another name',
2231 ));
5c49fee0 2232 $description = "This demonstrates the usage of chained api functions with multiple custom fields.";
6a488035
TO
2233 $subfile = "APIChainedArrayMultipleCustom";
2234 $params = array(
2235 'first_name' => 'abc3',
2236 'last_name' => 'xyz3',
2237 'contact_type' => 'Individual',
2238 'email' => 'man3@yahoo.com',
6a488035
TO
2239 'api.contribution.create' => array(
2240 'receive_date' => '2010-01-01',
2241 'total_amount' => 100.00,
5896d037 2242 'financial_type_id' => 1,
6a488035
TO
2243 'payment_instrument_id' => 1,
2244 'non_deductible_amount' => 10.00,
2245 'fee_amount' => 50.00,
2246 'net_amount' => 90.00,
2247 'trxn_id' => 12345,
2248 'invoice_id' => 67890,
2249 'source' => 'SSF',
2250 'contribution_status_id' => 1,
2251 ),
2252 'api.contribution.create.1' => array(
2253 'receive_date' => '2011-01-01',
2254 'total_amount' => 120.00,
5896d037 2255 'financial_type_id' => 1,
6a488035
TO
2256 'payment_instrument_id' => 1,
2257 'non_deductible_amount' => 10.00,
2258 'fee_amount' => 50.00,
2259 'net_amount' => 90.00,
2260 'trxn_id' => 12335,
2261 'invoice_id' => 67830,
2262 'source' => 'SSF',
2263 'contribution_status_id' => 1,
2264 ),
2265 'api.website.create' => array(
2266 array(
2267 'url' => "http://civicrm.org",
2268 ),
2269 ),
2270 'custom_' . $ids['custom_field_id'] => "value 1",
381fa321 2271 'custom_' . $moreIDs['custom_field_id'][0] => "value 2",
2272 'custom_' . $moreIDs['custom_field_id'][1] => "warm beer",
2273 'custom_' . $andMoreIDs['custom_field_id'][1] => "vegemite",
6a488035
TO
2274 );
2275
f6722559 2276 $result = $this->callAPISuccess('Contact', 'create', $params);
2277 $result = $this->callAPISuccess('Contact', 'create', array(
6c6e6187 2278 'contact_type' => 'Individual',
5896d037
TO
2279 'id' => $result['id'],
2280 'custom_' .
381fa321 2281 $moreIDs['custom_field_id'][0] => "value 3",
5896d037
TO
2282 'custom_' .
2283 $ids['custom_field_id'] => "value 4",
2284 ));
6a488035
TO
2285
2286 $params = array(
f6722559 2287 'id' => $result['id'],
6a488035
TO
2288 'api.website.getValue' => array('return' => 'url'),
2289 'api.Contribution.getCount' => array(),
2290 'api.CustomValue.get' => 1,
2291 );
f6722559 2292 $result = $this->callAPIAndDocument('Contact', 'Get', $params, __FUNCTION__, __FILE__, $description, $subfile);
2293
6a488035 2294 $this->customGroupDelete($ids['custom_group_id']);
381fa321 2295 $this->customGroupDelete($moreIDs['custom_group_id']);
2296 $this->customGroupDelete($andMoreIDs['custom_group_id']);
4b58ed3b
EM
2297 $this->assertEquals(0, $result['values'][$result['id']]['api.CustomValue.get']['is_error']);
2298 $this->assertEquals('http://civicrm.org', $result['values'][$result['id']]['api.website.getValue']);
6a488035 2299 }
5896d037 2300
d424ffde 2301 /**
381fa321 2302 * Test checks usage of $values to pick & choose inputs.
6a488035 2303 */
00be9182 2304 public function testChainingValuesCreate() {
5c49fee0
CW
2305 $description = "This demonstrates the usage of chained api functions. Specifically it has one 'parent function' &
2306 2 child functions - one receives values from the parent (Contact) and the other child (Tag).";
6a488035
TO
2307 $subfile = "APIChainedArrayValuesFromSiblingFunction";
2308 $params = array(
6c6e6187 2309 'display_name' => 'batman',
5896d037 2310 'contact_type' => 'Individual',
701a69da 2311 'api.tag.create' => array(
2312 'name' => '$value.id',
2313 'description' => '$value.display_name',
2314 'format.only_id' => 1,
2315 ),
6a488035
TO
2316 'api.entity_tag.create' => array('tag_id' => '$value.api.tag.create'),
2317 );
f6722559 2318 $result = $this->callAPIAndDocument('Contact', 'Create', $params, __FUNCTION__, __FILE__, $description, $subfile);
6a488035 2319 $this->assertEquals(0, $result['values'][$result['id']]['api.entity_tag.create']['is_error']);
f6722559 2320
6a488035
TO
2321 $tablesToTruncate = array(
2322 'civicrm_contact',
2323 'civicrm_activity',
2324 'civicrm_entity_tag',
2325 'civicrm_tag',
2326 );
2327 $this->quickCleanup($tablesToTruncate, TRUE);
2328 }
2329
d424ffde 2330 /**
fe482240 2331 * Test TrueFalse format - I couldn't come up with an easy way to get an error on Get.
6a488035 2332 */
00be9182 2333 public function testContactGetFormatIsSuccessTrue() {
6a488035
TO
2334 $this->createContactFromXML();
2335 $description = "This demonstrates use of the 'format.is_success' param.
2336 This param causes only the success or otherwise of the function to be returned as BOOLEAN";
2337 $subfile = "FormatIsSuccess_True";
5896d037
TO
2338 $params = array('id' => 17, 'format.is_success' => 1);
2339 $result = $this->callAPIAndDocument('Contact', 'Get', $params, __FUNCTION__, __FILE__, $description, $subfile);
6a488035 2340 $this->assertEquals(1, $result);
f6722559 2341 $this->callAPISuccess('Contact', 'Delete', $params);
6a488035 2342 }
5896d037 2343
d424ffde 2344 /**
fe482240 2345 * Test TrueFalse format.
6a488035 2346 */
00be9182 2347 public function testContactCreateFormatIsSuccessFalse() {
6a488035
TO
2348
2349 $description = "This demonstrates use of the 'format.is_success' param.
2350 This param causes only the success or otherwise of the function to be returned as BOOLEAN";
2351 $subfile = "FormatIsSuccess_Fail";
5896d037
TO
2352 $params = array('id' => 500, 'format.is_success' => 1);
2353 $result = $this->callAPIAndDocument('Contact', 'Create', $params, __FUNCTION__, __FILE__, $description, $subfile);
6a488035
TO
2354 $this->assertEquals(0, $result);
2355 }
5896d037 2356
d424ffde 2357 /**
fe482240 2358 * Test Single Entity format.
6a488035 2359 */
fe482240 2360 public function testContactGetSingleEntityArray() {
6a488035
TO
2361 $this->createContactFromXML();
2362 $description = "This demonstrates use of the 'format.single_entity_array' param.
5c49fee0
CW
2363 This param causes the only contact to be returned as an array without the other levels.
2364 It will be ignored if there is not exactly 1 result";
6a488035 2365 $subfile = "GetSingleContact";
5896d037
TO
2366 $params = array('id' => 17);
2367 $result = $this->callAPIAndDocument('Contact', 'GetSingle', $params, __FUNCTION__, __FILE__, $description, $subfile);
4b58ed3b 2368 $this->assertEquals('Test Contact', $result['display_name']);
f6722559 2369 $this->callAPISuccess('Contact', 'Delete', $params);
6a488035
TO
2370 }
2371
d424ffde 2372 /**
381fa321 2373 * Test Single Entity format.
6a488035 2374 */
fe482240 2375 public function testContactGetFormatCountOnly() {
6a488035 2376 $this->createContactFromXML();
5c49fee0
CW
2377 $description = "This demonstrates use of the 'getCount' action.
2378 This param causes the count of the only function to be returned as an integer.";
5896d037 2379 $params = array('id' => 17);
381fa321 2380 $result = $this->callAPIAndDocument('Contact', 'GetCount', $params, __FUNCTION__, __FILE__, $description,
84b51197 2381 'GetCountContact');
4b58ed3b 2382 $this->assertEquals('1', $result);
f6722559 2383 $this->callAPISuccess('Contact', 'Delete', $params);
6a488035 2384 }
5896d037 2385
d424ffde 2386 /**
381fa321 2387 * Test id only format.
408b79bf 2388 */
fe482240 2389 public function testContactGetFormatIDOnly() {
6a488035 2390 $this->createContactFromXML();
5c49fee0
CW
2391 $description = "This demonstrates use of the 'format.id_only' param.
2392 This param causes the id of the only entity to be returned as an integer.
2393 It will be ignored if there is not exactly 1 result";
6a488035 2394 $subfile = "FormatOnlyID";
5896d037
TO
2395 $params = array('id' => 17, 'format.only_id' => 1);
2396 $result = $this->callAPIAndDocument('Contact', 'Get', $params, __FUNCTION__, __FILE__, $description, $subfile);
4b58ed3b 2397 $this->assertEquals('17', $result);
f6722559 2398 $this->callAPISuccess('Contact', 'Delete', $params);
6a488035
TO
2399 }
2400
d424ffde 2401 /**
381fa321 2402 * Test id only format.
408b79bf 2403 */
00be9182 2404 public function testContactGetFormatSingleValue() {
6a488035
TO
2405 $this->createContactFromXML();
2406 $description = "This demonstrates use of the 'format.single_value' param.
5c49fee0
CW
2407 This param causes only a single value of the only entity to be returned as an string.
2408 It will be ignored if there is not exactly 1 result";
4b58ed3b 2409 $subFile = "FormatSingleValue";
5896d037 2410 $params = array('id' => 17, 'return' => 'display_name');
a828d7b8 2411 $result = $this->callAPIAndDocument('Contact', 'getvalue', $params, __FUNCTION__, __FILE__, $description, $subFile);
4b58ed3b 2412 $this->assertEquals('Test Contact', $result);
f6722559 2413 $this->callAPISuccess('Contact', 'Delete', $params);
6a488035
TO
2414 }
2415
b2130237 2416 /**
381fa321 2417 * Test that permissions are respected when creating contacts.
b2130237 2418 */
00be9182 2419 public function testContactCreationPermissions() {
6a488035 2420 $params = array(
6c6e6187 2421 'contact_type' => 'Individual',
5896d037 2422 'first_name' => 'Foo',
6a488035
TO
2423 'last_name' => 'Bear',
2424 'check_permissions' => TRUE,
6a488035
TO
2425 );
2426 $config = CRM_Core_Config::singleton();
2427 $config->userPermissionClass->permissions = array('access CiviCRM');
d0e1eff2 2428 $result = $this->callAPIFailure('contact', 'create', $params);
1644b908 2429 $this->assertEquals('API permission check failed for Contact/create call; insufficient permission: require access CiviCRM and add contacts', $result['error_message'], 'lacking permissions should not be enough to create a contact');
6a488035
TO
2430
2431 $config->userPermissionClass->permissions = array('access CiviCRM', 'add contacts', 'import contacts');
701a69da 2432 $this->callAPISuccess('contact', 'create', $params);
6a488035
TO
2433 }
2434
fa6448fa
EM
2435 /**
2436 * Test that delete with skip undelete respects permissions.
2437 */
2438 public function testContactDeletePermissions() {
2439 $contactID = $this->individualCreate();
2440 CRM_Core_Config::singleton()->userPermissionClass->permissions = array('access CiviCRM');
2441 $this->callAPIFailure('Contact', 'delete', array(
2442 'id' => $contactID,
2443 'check_permissions' => 1,
2444 'skip_undelete' => 1,
2445 ));
2446 $this->callAPISuccess('Contact', 'delete', array(
2447 'id' => $contactID,
2448 'check_permissions' => 0,
2449 'skip_undelete' => 1,
2450 ));
2451 }
2452
381fa321 2453 /**
2454 * Test update with check permissions set.
2455 */
00be9182 2456 public function testContactUpdatePermissions() {
5896d037
TO
2457 $params = array(
2458 'contact_type' => 'Individual',
2459 'first_name' => 'Foo',
2460 'last_name' => 'Bear',
21dfd5f5 2461 'check_permissions' => TRUE,
5896d037 2462 );
f6722559 2463 $result = $this->callAPISuccess('contact', 'create', $params);
6a488035 2464 $config = CRM_Core_Config::singleton();
5896d037
TO
2465 $params = array(
2466 'id' => $result['id'],
2467 'contact_type' => 'Individual',
2468 'last_name' => 'Bar',
21dfd5f5 2469 'check_permissions' => TRUE,
5896d037 2470 );
6a488035
TO
2471
2472 $config->userPermissionClass->permissions = array('access CiviCRM');
d0e1eff2 2473 $result = $this->callAPIFailure('contact', 'update', $params);
0a61b6e2 2474 $this->assertEquals('Permission denied to modify contact record', $result['error_message']);
6a488035 2475
5896d037
TO
2476 $config->userPermissionClass->permissions = array(
2477 'access CiviCRM',
2478 'add contacts',
2479 'view all contacts',
2480 'edit all contacts',
21dfd5f5 2481 'import contacts',
5896d037 2482 );
701a69da 2483 $this->callAPISuccess('contact', 'update', $params);
6a488035
TO
2484 }
2485
381fa321 2486 /**
2487 * Set up helper to create a contact.
2488 */
00be9182 2489 public function createContactFromXML() {
381fa321 2490 // Insert a row in civicrm_contact creating contact 17.
6a488035
TO
2491 $op = new PHPUnit_Extensions_Database_Operation_Insert();
2492 $op->execute($this->_dbconn,
bbfd46a5 2493 $this->createXMLDataSet(
6a488035
TO
2494 dirname(__FILE__) . '/dataset/contact_17.xml'
2495 )
2496 );
2497 }
2498
381fa321 2499 /**
2500 * Test contact proximity api.
2501 */
00be9182 2502 public function testContactProximity() {
6a488035
TO
2503 // first create a contact with a SF location with a specific
2504 // geocode
2505 $contactID = $this->organizationCreate();
2506
2507 // now create the address
2508 $params = array(
2509 'street_address' => '123 Main Street',
2510 'city' => 'San Francisco',
2511 'is_primary' => 1,
2512 'country_id' => 1228,
2513 'state_province_id' => 1004,
2514 'geo_code_1' => '37.79',
2515 'geo_code_2' => '-122.40',
2516 'location_type_id' => 1,
2517 'contact_id' => $contactID,
6a488035
TO
2518 );
2519
f6722559 2520 $result = $this->callAPISuccess('address', 'create', $params);
ba4a1892 2521 $this->assertEquals(1, $result['count']);
6a488035
TO
2522
2523 // now do a proximity search with a close enough geocode and hope to match
2524 // that specific contact only!
2525 $proxParams = array(
2526 'latitude' => 37.7,
2527 'longitude' => -122.3,
2528 'unit' => 'mile',
2529 'distance' => 10,
6a488035 2530 );
f6722559 2531 $result = $this->callAPISuccess('contact', 'proximity', $proxParams);
ba4a1892 2532 $this->assertEquals(1, $result['count']);
6a488035 2533 }
60ec9f43
E
2534
2535 /**
381fa321 2536 * Test that Ajax API permission is sufficient to access getquick api.
2537 *
1d6020f1 2538 * (note that getquick api is required for autocomplete & has ACL permissions applied)
60ec9f43 2539 */
fe482240 2540 public function testGetquickPermissionCRM13744() {
60ec9f43 2541 CRM_Core_Config::singleton()->userPermissionClass->permissions = array('access CiviEvent');
4b58ed3b 2542 $this->callAPIFailure('contact', 'getquick', array('name' => 'b', 'check_permissions' => TRUE));
60ec9f43 2543 CRM_Core_Config::singleton()->userPermissionClass->permissions = array('access CiviCRM');
4b58ed3b 2544 $this->callAPISuccess('contact', 'getquick', array('name' => 'b', 'check_permissions' => TRUE));
60ec9f43 2545 CRM_Core_Config::singleton()->userPermissionClass->permissions = array('access AJAX API');
4b58ed3b 2546 $this->callAPISuccess('contact', 'getquick', array('name' => 'b', 'check_permissions' => TRUE));
60ec9f43 2547 }
9c8096cb 2548
08f4ab8d 2549 /**
2550 * Test that getquick returns contacts with an exact first name match first.
2baa1e00 2551 *
2552 * The search string 'b' & 'bob' both return ordered by sort_name if includeOrderByClause
2553 * is true (default) but if it is false then matches are returned in ID order.
613643e0 2554 *
2555 * @dataProvider getSearchSortOptions
08f4ab8d 2556 */
613643e0 2557 public function testGetQuickExactFirst($searchParameters, $settings, $firstContact, $secondContact = NULL) {
08f4ab8d 2558 $this->getQuickSearchSampleData();
613643e0 2559 $this->callAPISuccess('Setting', 'create', $settings);
2560 $result = $this->callAPISuccess('contact', 'getquick', $searchParameters);
2561 $this->assertEquals($firstContact, $result['values'][0]['sort_name']);
2562 $this->assertEquals($secondContact, $result['values'][1]['sort_name']);
2563 $this->callAPISuccess('Setting', 'create', array('includeWildCardInName' => TRUE, 'includeOrderByClause' => TRUE));
2564 }
2565
2566 public function getSearchSortOptions() {
2567 $firstAlphabeticalContactBySortName = 'A Bobby, Bobby';
2568 $secondAlphabeticalContactBySortName = 'Aadvark, Bob';
2569 $secondAlphabeticalContactWithEmailBySortName = 'Bob, Bob';
2570 $firstAlphabeticalContactFirstNameBob = 'Aadvark, Bob';
2571 $secondAlphabeticalContactFirstNameBob = 'Bob, Bob';
2572 $firstByIDContactFirstNameBob = 'Bob, Bob';
2573 $secondByIDContactFirstNameBob = 'K Bobby, Bob';
2574 $firstContactByID = 'Bob, Bob';
2575 $secondContactByID = 'E Bobby, Bobby';
2576 $bobLikeEmail = 'A Bobby, Bobby';
2577
2578 return array(
2579 'empty_search_basic' => array(
2580 'search_parameters' => array('name' => '%'),
2581 'settings' => array('includeWildCardInName' => TRUE, 'includeOrderByClause' => TRUE),
2582 'first_contact' => $firstAlphabeticalContactBySortName,
2583 'second_contact' => $secondAlphabeticalContactBySortName,
2584 ),
2585 'empty_search_basic_no_wildcard' => array(
2586 'search_parameters' => array('name' => '%'),
2587 'settings' => array('includeWildCardInName' => FALSE, 'includeOrderByClause' => TRUE),
2588 'first_contact' => $firstAlphabeticalContactBySortName,
2589 'second_contact' => $secondAlphabeticalContactBySortName,
2590 ),
2591 'single_letter_search_basic' => array(
2592 'search_parameters' => array('name' => 'b'),
2593 'settings' => array('includeWildCardInName' => TRUE, 'includeOrderByClause' => TRUE),
2594 'first_contact' => $firstAlphabeticalContactBySortName,
2595 'second_contact' => $secondAlphabeticalContactBySortName,
2596 ),
2597 'bob_search_basic' => array(
2598 'search_parameters' => array('name' => 'bob'),
2599 'settings' => array('includeWildCardInName' => TRUE, 'includeOrderByClause' => TRUE),
2600 'first_contact' => $firstAlphabeticalContactBySortName,
2601 'second_contact' => $secondAlphabeticalContactBySortName,
2602 ),
2603 'bob_search_no_orderby' => array(
2604 'search_parameters' => array('name' => 'bob'),
2605 'settings' => array('includeWildCardInName' => TRUE, 'includeOrderByClause' => FALSE),
2606 'first_contact' => $firstContactByID,
2607 'second_contact' => $secondContactByID,
2608 ),
2609 'bob_search_no_wildcard' => array(
2610 'search_parameters' => array('name' => 'bob'),
2611 'settings' => array('includeWildCardInName' => FALSE, 'includeOrderByClause' => TRUE),
2612 'second_contact' => $bobLikeEmail,
2613 'first_contact' => $secondAlphabeticalContactFirstNameBob,
2614 ),
2615 // This should be the same as just no wildcard as if we had an exactMatch while searching by
2616 // sort name it would rise to the top CRM-19547
2617 'bob_search_no_wildcard_no_orderby' => array(
2618 'search_parameters' => array('name' => 'bob'),
2619 'settings' => array('includeWildCardInName' => FALSE, 'includeOrderByClause' => TRUE),
2620 'second_contact' => $bobLikeEmail,
2621 'first_contact' => $secondAlphabeticalContactFirstNameBob,
2622 ),
2623 'first_name_search_basic' => array(
2624 'search_parameters' => array('name' => 'bob', 'field_name' => 'first_name'),
2625 'settings' => array('includeWildCardInName' => TRUE, 'includeOrderByClause' => TRUE),
2626 'first_contact' => $firstAlphabeticalContactFirstNameBob,
2627 'second_contact' => $secondAlphabeticalContactFirstNameBob,
2628 ),
2629 'first_name_search_no_wildcard' => array(
2630 'search_parameters' => array('name' => 'bob', 'field_name' => 'first_name'),
2631 'settings' => array('includeWildCardInName' => FALSE, 'includeOrderByClause' => TRUE),
2632 'first_contact' => $firstAlphabeticalContactFirstNameBob,
2633 'second_contact' => $secondAlphabeticalContactFirstNameBob,
2634 ),
2635 'first_name_search_no_orderby' => array(
2636 'search_parameters' => array('name' => 'bob', 'field_name' => 'first_name'),
2637 'settings' => array('includeWildCardInName' => TRUE, 'includeOrderByClause' => FALSE),
2638 'first_contact' => $firstByIDContactFirstNameBob,
2639 'second_contact' => $secondByIDContactFirstNameBob,
2640 ),
2641 'email_search_basic' => array(
2642 'search_parameters' => array('name' => 'bob', 'field_name' => 'email', 'table_name' => 'eml'),
2643 'settings' => array('includeWildCardInName' => FALSE, 'includeOrderByClause' => TRUE),
2644 'first_contact' => $firstAlphabeticalContactBySortName,
2645 'second_contact' => $secondAlphabeticalContactWithEmailBySortName,
2646 ),
2647 );
2baa1e00 2648 }
2649
e9e27a80 2650 /**
2651 * Test that getquick returns contacts with an exact first name match first.
2652 */
2653 public function testGetQuickEmail() {
2654 $this->getQuickSearchSampleData();
1ca22999 2655 $loggedInContactID = $this->createLoggedInUser();
e9e27a80 2656 $result = $this->callAPISuccess('contact', 'getquick', array(
2657 'name' => 'c',
2658 ));
2659 $expectedData = array(
613643e0 2660 'A Bobby, Bobby :: bob@bobby.com',
e9e27a80 2661 'Bob, Bob :: bob@bob.com',
2662 'C Bobby, Bobby',
e9e27a80 2663 'H Bobby, Bobby :: bob@h.com',
1ca22999 2664 'Second Domain',
2665 $this->callAPISuccessGetValue('Contact', array('id' => $loggedInContactID, 'return' => 'last_name')) . ', Logged In :: anthony_anderson@civicrm.org',
e9e27a80 2666 );
1ca22999 2667 $this->assertEquals(6, $result['count']);
e9e27a80 2668 foreach ($expectedData as $index => $value) {
2669 $this->assertEquals($value, $result['values'][$index]['data']);
2670 }
7f6f3df1 2671 $result = $this->callAPISuccess('contact', 'getquick', array(
2672 'name' => 'h.',
2673 ));
2674 $expectedData = array(
2675 'H Bobby, Bobby :: bob@h.com',
2676 );
2677 foreach ($expectedData as $index => $value) {
2678 $this->assertEquals($value, $result['values'][$index]['data']);
2679 }
2680 $this->callAPISuccess('Setting', 'create', array('includeWildCardInName' => FALSE));
2681 $result = $this->callAPISuccess('contact', 'getquick', array(
2682 'name' => 'h.',
2683 ));
2684 $this->callAPISuccess('Setting', 'create', array('includeWildCardInName' => TRUE));
2685 $this->assertEquals(0, $result['count']);
e9e27a80 2686 }
2687
c37a2d66 2688 /**
2689 * Test that getquick returns contacts with an exact first name match first.
2690 */
2691 public function testGetQuickEmailACL() {
2692 $this->getQuickSearchSampleData();
1ca22999 2693 $loggedInContactID = $this->createLoggedInUser();
c37a2d66 2694 CRM_Core_Config::singleton()->userPermissionClass->permissions = array();
2695 $result = $this->callAPISuccess('contact', 'getquick', array(
2696 'name' => 'c',
2697 ));
2698 $this->assertEquals(0, $result['count']);
2699
2700 $this->hookClass->setHook('civicrm_aclWhereClause', array($this, 'aclWhereNoBobH'));
1ca22999 2701 CRM_Contact_BAO_Contact_Permission::cache($loggedInContactID, CRM_Core_Permission::VIEW, TRUE);
c37a2d66 2702 $result = $this->callAPISuccess('contact', 'getquick', array(
2703 'name' => 'c',
2704 ));
1ca22999 2705
2706 // Without the acl it would be 6 like the previous email getquick test.
2707 $this->assertEquals(5, $result['count']);
c37a2d66 2708 $expectedData = array(
613643e0 2709 'A Bobby, Bobby :: bob@bobby.com',
c37a2d66 2710 'Bob, Bob :: bob@bob.com',
2711 'C Bobby, Bobby',
1ca22999 2712 'Second Domain',
2713 $this->callAPISuccessGetValue('Contact', array('id' => $loggedInContactID, 'return' => 'last_name')) . ', Logged In :: anthony_anderson@civicrm.org',
c37a2d66 2714 );
2715 foreach ($expectedData as $index => $value) {
2716 $this->assertEquals($value, $result['values'][$index]['data']);
2717 }
2718 }
2719
2baa1e00 2720 /**
2721 * Test that getquick returns contacts with an exact first name match first.
2722 */
2723 public function testGetQuickExternalID() {
2724 $this->getQuickSearchSampleData();
2725 $result = $this->callAPISuccess('contact', 'getquick', array(
2726 'name' => 'b',
2727 'field_name' => 'external_identifier',
2728 'table_name' => 'cc',
2729 ));
2730 $this->assertEquals(0, $result['count']);
2731 $result = $this->callAPISuccess('contact', 'getquick', array(
2732 'name' => 'abc',
2733 'field_name' => 'external_identifier',
2734 'table_name' => 'cc',
2735 ));
2736 $this->assertEquals(1, $result['count']);
2737 $this->assertEquals('Bob, Bob', $result['values'][0]['sort_name']);
2738 }
2739
2740 /**
2741 * Test that getquick returns contacts with an exact first name match first.
2742 */
2743 public function testGetQuickID() {
1ca22999 2744 $max = CRM_Core_DAO::singleValueQuery("SELECT max(id) FROM civicrm_contact");
2baa1e00 2745 $this->getQuickSearchSampleData();
2746 $result = $this->callAPISuccess('contact', 'getquick', array(
1ca22999 2747 'name' => $max + 2,
2baa1e00 2748 'field_name' => 'id',
2749 'table_name' => 'cc',
2750 ));
2751 $this->assertEquals(1, $result['count']);
613643e0 2752 $this->assertEquals('E Bobby, Bobby', $result['values'][0]['sort_name']);
2baa1e00 2753 $result = $this->callAPISuccess('contact', 'getquick', array(
1ca22999 2754 'name' => $max + 2,
2baa1e00 2755 'field_name' => 'contact_id',
2756 'table_name' => 'cc',
2757 ));
2758 $this->assertEquals(1, $result['count']);
613643e0 2759 $this->assertEquals('E Bobby, Bobby', $result['values'][0]['sort_name']);
2baa1e00 2760 }
2761
2762 /**
2763 * Test that getquick returns contacts with an exact first name match first.
ef3fd279 2764 *
2765 * Depending on the setting the sort name sort might click in next or not - test!
2baa1e00 2766 */
2767 public function testGetQuickFirstName() {
2768 $this->getQuickSearchSampleData();
ef3fd279 2769 $this->callAPISuccess('Setting', 'create', array('includeOrderByClause' => TRUE));
2baa1e00 2770 $result = $this->callAPISuccess('contact', 'getquick', array(
2771 'name' => 'Bob',
2772 'field_name' => 'first_name',
2773 'table_name' => 'cc',
2774 ));
e9e27a80 2775 $expected = array(
613643e0 2776 'Aadvark, Bob',
e9e27a80 2777 'Bob, Bob',
2778 'K Bobby, Bob',
2779 'A Bobby, Bobby',
2780 );
2781
2782 foreach ($expected as $index => $value) {
2783 $this->assertEquals($value, $result['values'][$index]['sort_name']);
2784 }
08f4ab8d 2785 $this->callAPISuccess('Setting', 'create', array('includeOrderByClause' => FALSE));
2786 $result = $this->callAPISuccess('contact', 'getquick', array('name' => 'bob'));
2787 $this->assertEquals('Bob, Bob', $result['values'][0]['sort_name']);
613643e0 2788 $this->assertEquals('E Bobby, Bobby', $result['values'][1]['sort_name']);
08f4ab8d 2789 }
2790
1b9c2802 2791 /**
2792 * Test that getquick applies ACLs.
2793 */
2794 public function testGetQuickFirstNameACLs() {
2795 $this->getQuickSearchSampleData();
2796 $userID = $this->createLoggedInUser();
613643e0 2797 $this->callAPISuccess('Setting', 'create', array('includeOrderByClause' => TRUE, 'search_autocomplete_count' => 15));
1b9c2802 2798 CRM_Core_Config::singleton()->userPermissionClass->permissions = array();
2799 $result = $this->callAPISuccess('contact', 'getquick', array(
2800 'name' => 'Bob',
2801 'field_name' => 'first_name',
2802 'table_name' => 'cc',
2803 ));
2804 $this->assertEquals(0, $result['count']);
2805
2806 $this->hookClass->setHook('civicrm_aclWhereClause', array($this, 'aclWhereNoBobH'));
2807 CRM_Contact_BAO_Contact_Permission::cache($userID, CRM_Core_Permission::VIEW, TRUE);
2808 $result = $this->callAPISuccess('contact', 'getquick', array(
2809 'name' => 'Bob',
2810 'field_name' => 'first_name',
2811 'table_name' => 'cc',
2812 ));
613643e0 2813 $this->assertEquals('K Bobby, Bob', $result['values'][2]['sort_name']);
1b9c2802 2814 // Without the ACL 9 would be bob@h.com.
613643e0 2815 $this->assertEquals('I Bobby, Bobby', $result['values'][10]['sort_name']);
1b9c2802 2816 }
2817
2818 /**
2819 * Full results returned.
2820 * @implements CRM_Utils_Hook::aclWhereClause
2821 *
2822 * @param string $type
2823 * @param array $tables
2824 * @param array $whereTables
2825 * @param int $contactID
2826 * @param string $where
2827 */
2828 public function aclWhereNoBobH($type, &$tables, &$whereTables, &$contactID, &$where) {
c37a2d66 2829 $where = " (email <> 'bob@h.com' OR email IS NULL) ";
1b9c2802 2830 $whereTables['civicrm_email'] = "LEFT JOIN civicrm_email e ON contact_a.id = e.contact_id";
2831 }
2832
e9e27a80 2833 /**
2834 * Test that getquick returns contacts with an exact last name match first.
2835 */
2836 public function testGetQuickLastName() {
2837 $this->getQuickSearchSampleData();
2838 $this->callAPISuccess('Setting', 'create', array('includeOrderByClause' => TRUE));
2839 $result = $this->callAPISuccess('contact', 'getquick', array(
2840 'name' => 'Bob',
2841 'field_name' => 'last_name',
2842 'table_name' => 'cc',
2843 ));
2844 $expected = array(
2845 'Bob, Bob',
2846 'A Bobby, Bobby',
36575b09 2847 'B Bobby, Bobby',
e9e27a80 2848 );
2849
2850 foreach ($expected as $index => $value) {
2851 $this->assertEquals($value, $result['values'][$index]['sort_name']);
2852 }
2853 $this->callAPISuccess('Setting', 'create', array('includeOrderByClause' => FALSE));
2854 $result = $this->callAPISuccess('contact', 'getquick', array('name' => 'bob'));
2855 $this->assertEquals('Bob, Bob :: bob@bob.com', $result['values'][0]['data']);
2856 }
2857
2858 /**
2859 * Test that getquick returns contacts by city.
2860 */
2861 public function testGetQuickCity() {
2862 $this->getQuickSearchSampleData();
2863 $result = $this->callAPISuccess('contact', 'getquick', array(
2864 'name' => 'o',
2865 'field_name' => 'city',
2866 'table_name' => 'sts',
2867 ));
2868 $this->assertEquals('B Bobby, Bobby :: Toronto', $result['values'][0]['data']);
2869 $result = $this->callAPISuccess('contact', 'getquick', array(
2870 'name' => 'n',
2871 'field_name' => 'city',
2872 'table_name' => 'sts',
2873 ));
2874 $this->assertEquals('B Bobby, Bobby :: Toronto', $result['values'][0]['data']);
2875 $this->assertEquals('C Bobby, Bobby :: Whanganui', $result['values'][1]['data']);
2876 }
2877
08f4ab8d 2878 /**
2879 * Set up some sample data for testing quicksearch.
2880 */
2881 public function getQuickSearchSampleData() {
2882 $contacts = array(
e9e27a80 2883 array('first_name' => 'Bob', 'last_name' => 'Bob', 'external_identifier' => 'abc', 'email' => 'bob@bob.com'),
613643e0 2884 array('first_name' => 'Bobby', 'last_name' => 'E Bobby', 'external_identifier' => 'abcd'),
36575b09 2885 array(
2886 'first_name' => 'Bobby',
2887 'last_name' => 'B Bobby',
2888 'external_identifier' => 'bcd',
2889 'api.address.create' => array(
2890 'street_address' => 'Sesame Street',
2891 'city' => 'Toronto',
2892 'location_type_id' => 1,
2893 ),
2894 ),
2895 array(
2896 'first_name' => 'Bobby',
2897 'last_name' => 'C Bobby',
2898 'external_identifier' => 'bcde',
2899 'api.address.create' => array(
2900 'street_address' => 'Te huarahi',
2901 'city' => 'Whanganui',
2902 'location_type_id' => 1,
2903 ),
2904 ),
2baa1e00 2905 array('first_name' => 'Bobby', 'last_name' => 'D Bobby', 'external_identifier' => 'efg'),
613643e0 2906 array('first_name' => 'Bobby', 'last_name' => 'A Bobby', 'external_identifier' => 'hij', 'email' => 'bob@bobby.com'),
2baa1e00 2907 array('first_name' => 'Bobby', 'last_name' => 'F Bobby', 'external_identifier' => 'klm'),
2908 array('first_name' => 'Bobby', 'last_name' => 'G Bobby', 'external_identifier' => 'nop'),
e9e27a80 2909 array('first_name' => 'Bobby', 'last_name' => 'H Bobby', 'external_identifier' => 'qrs', 'email' => 'bob@h.com'),
2baa1e00 2910 array('first_name' => 'Bobby', 'last_name' => 'I Bobby'),
2911 array('first_name' => 'Bobby', 'last_name' => 'J Bobby'),
2912 array('first_name' => 'Bob', 'last_name' => 'K Bobby', 'external_identifier' => 'bcdef'),
613643e0 2913 array('first_name' => 'Bob', 'last_name' => 'Aadvark'),
08f4ab8d 2914 );
2915 foreach ($contacts as $type => $contact) {
2916 $contact['contact_type'] = 'Individual';
2917 $this->callAPISuccess('Contact', 'create', $contact);
2918 }
2919 }
2920
b2130237 2921 /**
381fa321 2922 * Test get ref api - gets a list of references to an entity.
b2130237 2923 */
00be9182 2924 public function testGetReferenceCounts() {
9c8096cb
TO
2925 $result = $this->callAPISuccess('Contact', 'create', array(
2926 'first_name' => 'Testily',
2927 'last_name' => 'McHaste',
2928 'contact_type' => 'Individual',
2929 'api.Address.replace' => array(
2930 'values' => array(),
2931 ),
2932 'api.Email.replace' => array(
2933 'values' => array(
2934 array(
2935 'email' => 'spam@dev.null',
2936 'is_primary' => 0,
2937 'location_type_id' => 1,
21dfd5f5 2938 ),
9c8096cb
TO
2939 ),
2940 ),
2941 'api.Phone.replace' => array(
2942 'values' => array(
2943 array(
2944 'phone' => '234-567-0001',
2945 'is_primary' => 1,
2946 'location_type_id' => 1,
2947 ),
2948 array(
2949 'phone' => '234-567-0002',
2950 'is_primary' => 0,
2951 'location_type_id' => 1,
2952 ),
2953 ),
2954 ),
2955 ));
2956
2957 //$dao = new CRM_Contact_BAO_Contact();
2958 //$dao->id = $result['id'];
2959 //$this->assertTrue((bool) $dao->find(TRUE));
2960 //
2961 //$refCounts = $dao->getReferenceCounts();
2962 //$this->assertTrue(is_array($refCounts));
2963 //$refCountsIdx = CRM_Utils_Array::index(array('name'), $refCounts);
2964
2965 $refCounts = $this->callAPISuccess('Contact', 'getrefcount', array(
21dfd5f5 2966 'id' => $result['id'],
9c8096cb
TO
2967 ));
2968 $refCountsIdx = CRM_Utils_Array::index(array('name'), $refCounts['values']);
2969
2970 $this->assertEquals(1, $refCountsIdx['sql:civicrm_email:contact_id']['count']);
2971 $this->assertEquals('civicrm_email', $refCountsIdx['sql:civicrm_email:contact_id']['table']);
2972 $this->assertEquals(2, $refCountsIdx['sql:civicrm_phone:contact_id']['count']);
2973 $this->assertEquals('civicrm_phone', $refCountsIdx['sql:civicrm_phone:contact_id']['table']);
2974 $this->assertTrue(!isset($refCountsIdx['sql:civicrm_address:contact_id']));
2975 }
2976
701a69da 2977 /**
2978 * Test the use of sql operators.
2979 */
00be9182 2980 public function testSQLOperatorsOnContactAPI() {
a75c13cc
EM
2981 $this->individualCreate();
2982 $this->organizationCreate();
2983 $this->householdCreate();
2984 $contacts = $this->callAPISuccess('contact', 'get', array('legal_name' => array('IS NOT NULL' => TRUE)));
2985 $this->assertEquals($contacts['count'], CRM_Core_DAO::singleValueQuery('select count(*) FROM civicrm_contact WHERE legal_name IS NOT NULL'));
2986 $contacts = $this->callAPISuccess('contact', 'get', array('legal_name' => array('IS NULL' => TRUE)));
2987 $this->assertEquals($contacts['count'], CRM_Core_DAO::singleValueQuery('select count(*) FROM civicrm_contact WHERE legal_name IS NULL'));
2988 }
9bee5ea2 2989
9bee5ea2 2990 /**
fe482240 2991 * CRM-14743 - test api respects search operators.
9bee5ea2 2992 */
00be9182 2993 public function testGetModifiedDateByOperators() {
9bee5ea2
EM
2994 $preExistingContactCount = CRM_Core_DAO::singleValueQuery('select count(*) FROM civicrm_contact');
2995 $contact1 = $this->individualCreate();
2996 $sql = "UPDATE civicrm_contact SET created_date = '2012-01-01', modified_date = '2013-01-01' WHERE id = " . $contact1;
2997 CRM_Core_DAO::executeQuery($sql);
2998 $contact2 = $this->individualCreate();
2999 $sql = "UPDATE civicrm_contact SET created_date = '2012-02-01', modified_date = '2013-02-01' WHERE id = " . $contact2;
3000 CRM_Core_DAO::executeQuery($sql);
3001 $contact3 = $this->householdCreate();
3002 $sql = "UPDATE civicrm_contact SET created_date = '2012-03-01', modified_date = '2013-03-01' WHERE id = " . $contact3;
3003 CRM_Core_DAO::executeQuery($sql);
3004 $contacts = $this->callAPISuccess('contact', 'get', array('modified_date' => array('<' => '2014-01-01')));
3005 $this->assertEquals($contacts['count'], 3);
3006 $contacts = $this->callAPISuccess('contact', 'get', array('modified_date' => array('>' => '2014-01-01')));
3007 $this->assertEquals($contacts['count'], $preExistingContactCount);
3008 }
2134e310 3009
2134e310 3010 /**
fe482240 3011 * CRM-14743 - test api respects search operators.
2134e310 3012 */
00be9182 3013 public function testGetCreatedDateByOperators() {
2134e310
EM
3014 $preExistingContactCount = CRM_Core_DAO::singleValueQuery('select count(*) FROM civicrm_contact');
3015 $contact1 = $this->individualCreate();
3016 $sql = "UPDATE civicrm_contact SET created_date = '2012-01-01' WHERE id = " . $contact1;
3017 CRM_Core_DAO::executeQuery($sql);
3018 $contact2 = $this->individualCreate();
3019 $sql = "UPDATE civicrm_contact SET created_date = '2012-02-01' WHERE id = " . $contact2;
3020 CRM_Core_DAO::executeQuery($sql);
3021 $contact3 = $this->householdCreate();
3022 $sql = "UPDATE civicrm_contact SET created_date = '2012-03-01' WHERE id = " . $contact3;
3023 CRM_Core_DAO::executeQuery($sql);
3024 $contacts = $this->callAPISuccess('contact', 'get', array('created_date' => array('<' => '2014-01-01')));
3025 $this->assertEquals($contacts['count'], 3);
3026 $contacts = $this->callAPISuccess('contact', 'get', array('created_date' => array('>' => '2014-01-01')));
3027 $this->assertEquals($contacts['count'], $preExistingContactCount);
3028 }
e5fccefb
EM
3029
3030 /**
fe482240 3031 * CRM-14263 check that API is not affected by search profile related bug.
e5fccefb 3032 */
5896d037 3033 public function testReturnCityProfile() {
e5fccefb
EM
3034 $contactID = $this->individualCreate();
3035 CRM_Core_Config::singleton()->defaultSearchProfileID = 1;
5896d037 3036 $this->callAPISuccess('address', 'create', array(
92915c55
TO
3037 'contact_id' => $contactID,
3038 'city' => 'Cool City',
3039 'location_type_id' => 1,
3040 ));
e5fccefb
EM
3041 $result = $this->callAPISuccess('contact', 'get', array('city' => 'Cool City', 'return' => 'contact_type'));
3042 $this->assertEquals(1, $result['count']);
3043 }
eaa112a5 3044
eaa112a5 3045 /**
701a69da 3046 * CRM-15443 - ensure getlist api does not return deleted contacts.
eaa112a5 3047 */
00be9182 3048 public function testGetlistExcludeConditions() {
eaa112a5 3049 $name = md5(time());
45fcf8b7 3050 $contact = $this->individualCreate(array('last_name' => $name));
381fa321 3051 $this->individualCreate(array('last_name' => $name, 'is_deceased' => 1));
3052 $this->individualCreate(array('last_name' => $name, 'is_deleted' => 1));
3053 // We should get all but the deleted contact.
eaa112a5 3054 $result = $this->callAPISuccess('contact', 'getlist', array('input' => $name));
ba4a1892 3055 $this->assertEquals(2, $result['count']);
381fa321 3056 // Force-exclude the deceased contact.
5896d037 3057 $result = $this->callAPISuccess('contact', 'getlist', array(
92915c55
TO
3058 'input' => $name,
3059 'params' => array('is_deceased' => 0),
3060 ));
ba4a1892
TM
3061 $this->assertEquals(1, $result['count']);
3062 $this->assertEquals($contact, $result['values'][0]['id']);
eaa112a5 3063 }
92776611
CW
3064
3065 /**
fe482240 3066 * Test contact getactions.
92776611 3067 */
00be9182 3068 public function testGetActions() {
92776611
CW
3069 $description = "Getting the available actions for an entity.";
3070 $result = $this->callAPIAndDocument($this->_entity, 'getactions', array(), __FUNCTION__, __FILE__, $description);
3071 $expected = array(
3072 'create',
3073 'delete',
3074 'get',
3075 'getactions',
3076 'getcount',
3077 'getfields',
3078 'getlist',
3079 'getoptions',
3080 'getquick',
3081 'getrefcount',
3082 'getsingle',
3083 'getvalue',
3084 'merge',
3085 'proximity',
3086 'replace',
3087 'setvalue',
3088 'update',
3089 );
3090 $deprecated = array(
3091 'update',
3092 'getquick',
3093 );
3094 foreach ($expected as $action) {
3095 $this->assertTrue(in_array($action, $result['values']), "Expected action $action");
3096 }
3097 foreach ($deprecated as $action) {
3098 $this->assertArrayKeyExists($action, $result['deprecated']);
3099 }
3100 }
96025800 3101
ffe87781 3102 /**
3103 * Test the duplicate check function.
3104 */
3105 public function testDuplicateCheck() {
fedc3428 3106 $harry = array(
ffe87781 3107 'first_name' => 'Harry',
3108 'last_name' => 'Potter',
3109 'email' => 'harry@hogwarts.edu',
3110 'contact_type' => 'Individual',
fedc3428 3111 );
3112 $this->callAPISuccess('Contact', 'create', $harry);
ffe87781 3113 $result = $this->callAPISuccess('Contact', 'duplicatecheck', array(
fedc3428 3114 'match' => $harry,
ffe87781 3115 ));
3116
3117 $this->assertEquals(1, $result['count']);
3118 $result = $this->callAPISuccess('Contact', 'duplicatecheck', array(
3119 'match' => array(
3120 'first_name' => 'Harry',
3121 'last_name' => 'Potter',
3122 'email' => 'no5@privet.drive',
3123 'contact_type' => 'Individual',
3124 ),
3125 ));
3126 $this->assertEquals(0, $result['count']);
fedc3428 3127 $this->callAPIFailure('Contact', 'create', array_merge($harry, array('dupe_check' => 1)));
ffe87781 3128 }
3129
a2dd33d3 3130 /**
3131 * Test the duplicate check function.
3132 */
3133 public function testDuplicateCheckRuleNotReserved() {
3134 $harry = array(
3135 'first_name' => 'Harry',
3136 'last_name' => 'Potter',
3137 'email' => 'harry@hogwarts.edu',
3138 'contact_type' => 'Individual',
3139 );
3140 $defaultRule = $this->callAPISuccess('RuleGroup', 'getsingle', array('used' => 'Unsupervised', 'is_reserved' => 1));
3141 $this->callAPISuccess('RuleGroup', 'create', array('id' => $defaultRule['id'], 'is_reserved' => 0));
3142 $this->callAPISuccess('Contact', 'create', $harry);
3143 $result = $this->callAPISuccess('Contact', 'duplicatecheck', array(
3144 'match' => $harry,
3145 ));
3146
3147 $this->assertEquals(1, $result['count']);
3148 $this->callAPISuccess('RuleGroup', 'create', array('id' => $defaultRule['id'], 'is_reserved' => 1));
3149 }
3150
3151 /**
3152 * Test variants on retrieving contact by type.
3153 */
46b3417a
CW
3154 public function testGetByContactType() {
3155 $individual = $this->callAPISuccess('Contact', 'create', array(
3156 'email' => 'individual@test.com',
3157 'contact_type' => 'Individual',
3158 ));
3159 $household = $this->callAPISuccess('Contact', 'create', array(
3160 'household_name' => 'household@test.com',
3161 'contact_type' => 'Household',
3162 ));
3163 $organization = $this->callAPISuccess('Contact', 'create', array(
3164 'organization_name' => 'organization@test.com',
3165 'contact_type' => 'Organization',
3166 ));
3167 // Test with id - getsingle will throw an exception if not found
3168 $this->callAPISuccess('Contact', 'getsingle', array(
3169 'id' => $individual['id'],
3170 'contact_type' => 'Individual',
3171 ));
3172 $this->callAPISuccess('Contact', 'getsingle', array(
3173 'id' => $individual['id'],
3174 'contact_type' => array('IN' => array('Individual')),
3175 'return' => 'id',
3176 ));
3177 $this->callAPISuccess('Contact', 'getsingle', array(
3178 'id' => $organization['id'],
3179 'contact_type' => array('IN' => array('Individual', 'Organization')),
3180 ));
3181 // Test as array
3182 $result = $this->callAPISuccess('Contact', 'get', array(
3183 'contact_type' => array('IN' => array('Individual', 'Organization')),
3184 'options' => array('limit' => 0),
3185 'return' => 'id',
3186 ));
3187 $this->assertContains($organization['id'], array_keys($result['values']));
3188 $this->assertContains($individual['id'], array_keys($result['values']));
3189 $this->assertNotContains($household['id'], array_keys($result['values']));
3190 // Test as string
3191 $result = $this->callAPISuccess('Contact', 'get', array(
3192 'contact_type' => 'Household',
3193 'options' => array('limit' => 0),
3194 'return' => 'id',
3195 ));
3196 $this->assertNotContains($organization['id'], array_keys($result['values']));
3197 $this->assertNotContains($individual['id'], array_keys($result['values']));
3198 $this->assertContains($household['id'], array_keys($result['values']));
3199 }
3200
12d73bba 3201 /**
3202 * Test merging 2 contacts.
5ea06a7b 3203 *
3204 * Someone kindly bequethed us the legacy of mixed up use of main_id & other_id
3205 * in the params for contact.merge api.
3206 *
3207 * This test protects that legacy.
12d73bba 3208 */
5ea06a7b 3209 public function testMergeBizzareOldParams() {
3210 $this->createLoggedInUser();
12d73bba 3211 $otherContact = $this->callAPISuccess('contact', 'create', $this->_params);
3212 $mainContact = $this->callAPISuccess('contact', 'create', $this->_params);
5ea06a7b 3213 $this->callAPISuccess('contact', 'merge', array(
3214 'main_id' => $mainContact['id'],
3215 'other_id' => $otherContact['id'],
3216 ));
12d73bba 3217 $contacts = $this->callAPISuccess('contact', 'get', $this->_params);
3218 $this->assertEquals($otherContact['id'], $contacts['id']);
5ea06a7b 3219 }
3220
3221 /**
3222 * Test merging 2 contacts.
3223 */
3224 public function testMerge() {
3225 $this->createLoggedInUser();
3226 $otherContact = $this->callAPISuccess('contact', 'create', $this->_params);
3227 $retainedContact = $this->callAPISuccess('contact', 'create', $this->_params);
3228 $this->callAPISuccess('contact', 'merge', array(
3229 'to_keep_id' => $retainedContact['id'],
3230 'to_remove_id' => $otherContact['id'],
3231 'auto_flip' => FALSE,
3232 ));
3233
3234 $contacts = $this->callAPISuccess('contact', 'get', $this->_params);
3235 $this->assertEquals($retainedContact['id'], $contacts['id']);
3236 $activity = $this->callAPISuccess('Activity', 'getsingle', array(
3237 'target_contact_id' => $retainedContact['id'],
3238 'activity_type_id' => 'Contact Merged',
3239 ));
3240 $this->assertEquals(date('Y-m-d'), date('Y-m-d', strtotime($activity['activity_date_time'])));
f00283b5 3241 $activity2 = $this->callAPISuccess('Activity', 'getsingle', array(
3242 'target_contact_id' => $otherContact['id'],
3243 'activity_type_id' => 'Contact Deleted by Merge',
3244 ));
3245 $this->assertEquals($activity['id'], $activity2['parent_id']);
3246 $this->assertEquals('Normal', civicrm_api3('option_value', 'getvalue', array(
3247 'value' => $activity['priority_id'],
3248 'return' => 'label',
3249 'option_group_id' => 'priority',
3250 )));
12d73bba 3251
3252 }
3253
4d834a99 3254 /**
3255 * Test merging 2 contacts with delete to trash off.
3256 *
3257 * We are checking that there is no error due to attempting to add an activity for the
3258 * deleted contact.
3259 *
3260 * CRM-18307
3261 */
3262 public function testMergeNoTrash() {
3263 $this->createLoggedInUser();
3264 $this->callAPISuccess('Setting', 'create', array('contact_undelete' => FALSE));
3265 $otherContact = $this->callAPISuccess('contact', 'create', $this->_params);
3266 $retainedContact = $this->callAPISuccess('contact', 'create', $this->_params);
3267 $this->callAPISuccess('contact', 'merge', array(
3268 'to_keep_id' => $retainedContact['id'],
3269 'to_remove_id' => $otherContact['id'],
3270 'auto_flip' => FALSE,
3271 ));
3272 $this->callAPISuccess('Setting', 'create', array('contact_undelete' => TRUE));
3273 }
3274
00ed3e04
CB
3275 /**
3276 * Ensure format with return=group shows comma-separated group IDs.
3277 *
3278 * CRM-19426
3279 */
3280 public function testContactGetReturnGroup() {
3281 // Set up a contact, asser that they were created.
3282 $contact_params = array(
3283 'contact_type' => 'Individual',
3284 'first_name' => 'Test',
3285 'last_name' => 'Groupmember',
3286 'email' => 'test@example.org',
3287 );
3288 $create_contact = $this->callApiSuccess('Contact', 'create', $contact_params);
3289 $this->assertEquals(0, $create_contact['is_error']);
3290 $this->assertInternalType('int', $create_contact['id']);
3291
3292 $created_contact_id = $create_contact['id'];
3293
3294 // Set up multiple groups, add the contact to the groups.
3295 $test_groups = array('Test group A', 'Test group B');
3296 foreach ($test_groups as $title) {
3297 // Use this contact as group owner, since we know they exist.
3298 $group_params = array(
3299 'title' => $title,
3300 'created_id' => $created_contact_id,
3301 );
3302 $create_group = $this->callApiSuccess('Group', 'create', $group_params);
3303 $this->assertEquals(0, $create_group['is_error']);
3304 $this->assertInternalType('int', $create_group['id']);
3305
3306 $created_group_ids[] = $create_group['id'];
3307
3308 // Add contact to the new group.
3309 $group_contact_params = array(
3310 'contact_id' => $created_contact_id,
3311 'group_id' => $create_group['id'],
3312 );
3313 $create_group_contact = $this->callApiSuccess('GroupContact', 'create', $group_contact_params);
3314 $this->assertEquals(0, $create_group_contact['is_error']);
3315 $this->assertInternalType('int', $create_group_contact['added']);
3316 }
3317
3318 // Use the Contact,get API to retrieve the contact
3319 $contact_get_params = array(
3320 'id' => $created_contact_id,
3321 'return' => 'group',
3322 );
3323 $contact_get = $this->callApiSuccess('Contact', 'get', $contact_get_params);
3324 $this->assertInternalType('array', $contact_get['values'][$created_contact_id]);
3325 $this->assertInternalType('string', $contact_get['values'][$created_contact_id]['groups']);
3326
3327 // Ensure they are shown as being in each created group.
3328 $contact_group_ids = explode(',', $contact_get['values'][$created_contact_id]['groups']);
3329 foreach ($created_group_ids as $created_group_id) {
3330 $this->assertContains($created_group_id, $contact_group_ids);
3331 }
3332 }
3333
309f98a9
SL
3334 /**
3335 * CRM-20144 Verify that passing title of group works as well as id
0c66b30c
SL
3336 * Tests the following formats
3337 * contact.get group='title1'
3338 * contact.get group=id1
309f98a9
SL
3339 */
3340 public function testContactGetWithGroupTitle() {
3341 // Set up a contact, asser that they were created.
3342 $contact_params = array(
3343 'contact_type' => 'Individual',
3344 'first_name' => 'Test2',
3345 'last_name' => 'Groupmember',
3346 'email' => 'test@example.org',
3347 );
3348 $create_contact = $this->callApiSuccess('Contact', 'create', $contact_params);
3349 $created_contact_id = $create_contact['id'];
3350 // Set up multiple groups, add the contact to the groups.
3351 $test_groups = array('Test group C', 'Test group D');
3352 foreach ($test_groups as $title) {
3353 $group_params = array(
3354 'title' => $title,
3355 'created_id' => $created_contact_id,
3356 );
3357 $create_group = $this->callApiSuccess('Group', 'create', $group_params);
3358 $created_group_id = $create_group['id'];
3359
3360 // Add contact to the new group.
3361 $group_contact_params = array(
3362 'contact_id' => $created_contact_id,
3363 'group_id' => $create_group['id'],
3364 );
6d054a8e 3365 $this->callApiSuccess('GroupContact', 'create', $group_contact_params);
309f98a9
SL
3366 $contact_get = $this->callAPISuccess('contact', 'get', array('group' => $title, 'return' => 'group'));
3367 $this->assertEquals(1, $contact_get['count']);
3368 $this->assertEquals($created_contact_id, $contact_get['id']);
3369 $contact_groups = explode(',', $contact_get['values'][$created_contact_id]['groups']);
3370 $this->assertContains((string) $create_group['id'], $contact_groups);
3371 $contact_get2 = $this->callAPISuccess('contact', 'get', array('group' => $created_group_id, 'return' => 'group'));
3372 $this->assertEquals($created_contact_id, $contact_get2['id']);
3373 $contact_groups2 = explode(',', $contact_get2['values'][$created_contact_id]['groups']);
3374 $this->assertContains((string) $create_group['id'], $contact_groups2);
3375 $this->callAPISuccess('group', 'delete', array('id' => $created_group_id));
3376 }
3377 $this->callAPISuccess('contact', 'delete', array('id' => $created_contact_id, 'skip_undelete' => TRUE));
3378 }
3379
0c66b30c
SL
3380 /**
3381 * CRM-20144 Verify that passing title of group works as well as id
3382 * Tests the following formats
3383 * contact.get group=array('title1', title1)
3384 * contact.get group=array('IN' => array('title1', 'title2)
3385 */
3386 public function testContactGetWithGroupTitleMultipleGroups() {
d0aa0e47
SL
3387 $description = "Get all from group and display contacts.";
3388 $subFile = "GroupFilterUsingContactAPI";
0c66b30c
SL
3389 // Set up a contact, asser that they were created.
3390 $contact_params = array(
3391 'contact_type' => 'Individual',
3392 'first_name' => 'Test2',
3393 'last_name' => 'Groupmember',
3394 'email' => 'test@example.org',
3395 );
3396 $create_contact = $this->callApiSuccess('Contact', 'create', $contact_params);
3397 $created_contact_id = $create_contact['id'];
3398 $createdGroupsTitles = $createdGroupsIds = array();
3399 // Set up multiple groups, add the contact to the groups.
3400 $test_groups = array('Test group C', 'Test group D');
3401 foreach ($test_groups as $title) {
3402 $group_params = array(
3403 'title' => $title,
3404 'created_id' => $created_contact_id,
3405 );
3406 $create_group = $this->callApiSuccess('Group', 'create', $group_params);
3407 $created_group_id = $create_group['id'];
3408 $createdGroupsIds[] = $create_group['id'];
3409 $createdGroupTitles[] = $title;
3410 // Add contact to the new group.
3411 $group_contact_params = array(
3412 'contact_id' => $created_contact_id,
3413 'group_id' => $create_group['id'],
3414 );
3415 $create_group_contact = $this->callApiSuccess('GroupContact', 'create', $group_contact_params);
3416 }
3417 $contact_get = $this->callAPISuccess('contact', 'get', array('group' => $createdGroupTitles, 'return' => 'group'));
3418 $this->assertEquals(1, $contact_get['count']);
3419 $this->assertEquals($created_contact_id, $contact_get['id']);
3420 $contact_groups = explode(',', $contact_get['values'][$created_contact_id]['groups']);
3421 foreach ($createdGroupsIds as $id) {
3422 $this->assertContains((string) $id, $contact_groups);
3423 }
d0aa0e47 3424 $contact_get2 = $this->callAPIAndDocument('contact', 'get', array('group' => array('IN' => $createdGroupTitles)), __FUNCTION__, __FILE__, $description, $subFile);
0c66b30c
SL
3425 $contact_get2 = $this->callAPISuccess('contact', 'get', array('group' => array('IN' => $createdGroupTitles), 'return' => 'group'));
3426 $this->assertEquals($created_contact_id, $contact_get2['id']);
3427 $contact_groups2 = explode(',', $contact_get2['values'][$created_contact_id]['groups']);
3428 foreach ($createdGroupsIds as $id) {
3429 $this->assertContains((string) $id, $contact_groups2);
3430 }
3431 foreach ($createdGroupsIds as $id) {
3432 $this->callAPISuccess('group', 'delete', array('id' => $id));
3433 }
3434 $this->callAPISuccess('contact', 'delete', array('id' => $created_contact_id, 'skip_undelete' => TRUE));
3435 }
3436
b6b28d93
SL
3437 /**
3438 * CRM-20144 Verify that passing title of group works as well as id
3439 * Tests the following formats
3440 * contact.get group=array('title1' => 1)
3441 * contact.get group=array('titke1' => 1, 'title2' => 1)
3442 * contact.get group=array('id1' => 1)
3443 * contact.get group=array('id1' => 1, id2 => 1)
3444 */
3445 public function testContactGetWithGroupTitleMultipleGroupsLegacyFormat() {
3446 // Set up a contact, asser that they were created.
3447 $contact_params = array(
3448 'contact_type' => 'Individual',
3449 'first_name' => 'Test2',
3450 'last_name' => 'Groupmember',
3451 'email' => 'test@example.org',
3452 );
3453 $create_contact = $this->callApiSuccess('Contact', 'create', $contact_params);
3454 $created_contact_id = $create_contact['id'];
3455 $createdGroupsTitles = $createdGroupsIds = array();
3456 // Set up multiple groups, add the contact to the groups.
3457 $test_groups = array('Test group C', 'Test group D');
3458 foreach ($test_groups as $title) {
3459 $group_params = array(
3460 'title' => $title,
3461 'created_id' => $created_contact_id,
3462 );
3463 $create_group = $this->callApiSuccess('Group', 'create', $group_params);
3464 $created_group_id = $create_group['id'];
3465 $createdGroupsIds[] = $create_group['id'];
3466 $createdGroupTitles[] = $title;
3467 // Add contact to the new group.
3468 $group_contact_params = array(
3469 'contact_id' => $created_contact_id,
3470 'group_id' => $create_group['id'],
3471 );
3472 $create_group_contact = $this->callApiSuccess('GroupContact', 'create', $group_contact_params);
3473 }
3474 $contact_get = $this->callAPISuccess('contact', 'get', array('group' => array($createdGroupTitles[0] => 1), 'return' => 'group'));
3475 $this->assertEquals(1, $contact_get['count']);
3476 $this->assertEquals($created_contact_id, $contact_get['id']);
3477 $contact_groups = explode(',', $contact_get['values'][$created_contact_id]['groups']);
3478 foreach ($createdGroupsIds as $id) {
3479 $this->assertContains((string) $id, $contact_groups);
3480 }
3481 $contact_get2 = $this->callAPISuccess('contact', 'get', array('group' => array($createdGroupTitles[0] => 1, $createdGroupTitles[1] => 1), 'return' => 'group'));
3482 $this->assertEquals(1, $contact_get2['count']);
3483 $this->assertEquals($created_contact_id, $contact_get2['id']);
62b8c91c 3484 $contact_groups2 = explode(',', $contact_get2['values'][$created_contact_id]['groups']);
b6b28d93 3485 foreach ($createdGroupsIds as $id) {
62b8c91c 3486 $this->assertContains((string) $id, $contact_groups2);
b6b28d93
SL
3487 }
3488 $contact_get3 = $this->callAPISuccess('contact', 'get', array('group' => array($createdGroupsIds[0] => 1), 'return' => 'group'));
3489 $this->assertEquals($created_contact_id, $contact_get3['id']);
3490 $contact_groups3 = explode(',', $contact_get3['values'][$created_contact_id]['groups']);
3491 foreach ($createdGroupsIds as $id) {
62b8c91c 3492 $this->assertContains((string) $id, $contact_groups3);
b6b28d93
SL
3493 }
3494 $contact_get4 = $this->callAPISuccess('contact', 'get', array('group' => array($createdGroupsIds[0] => 1, $createdGroupsIds[1] => 1), 'return' => 'group'));
3495 $this->assertEquals($created_contact_id, $contact_get4['id']);
62b8c91c 3496 $contact_groups4 = explode(',', $contact_get4['values'][$created_contact_id]['groups']);
b6b28d93 3497 foreach ($createdGroupsIds as $id) {
62b8c91c 3498 $this->assertContains((string) $id, $contact_groups4);
b6b28d93
SL
3499 }
3500 foreach ($createdGroupsIds as $id) {
3501 $this->callAPISuccess('group', 'delete', array('id' => $id));
3502 }
3503 $this->callAPISuccess('contact', 'delete', array('id' => $created_contact_id, 'skip_undelete' => TRUE));
3504 }
3505
83d02301
SL
3506 public function testLoggedInUserAPISupportToken() {
3507 $description = "Get contact id of the current logged in user";
3508 $subFile = "ContactIDOfLoggedInUserContactAPI";
3509 $cid = $this->createLoggedInUser();
3510 $contact = $this->callAPIAndDocument('contact', 'get', array('id' => 'user_contact_id'), __FUNCTION__, __FILE__, $description, $subFile);
3511 $this->assertEquals($cid, $contact['id']);
3512 }
3513
ec52a65a 3514 /**
3515 * @param $groupID
3516 * @param $contact
3517 */
3518 protected function putGroupContactCacheInClearableState($groupID, $contact) {
bb2d2335 3519 // We need to force the situation where there is invalid data in the cache and it
ec52a65a 3520 // is due to be cleared.
3521 CRM_Core_DAO::executeQuery("
3522 INSERT INTO civicrm_group_contact_cache (group_id, contact_id)
3523 VALUES ({$groupID}, {$contact['id']})
3524 ");
3525 CRM_Core_DAO::executeQuery("UPDATE civicrm_group SET cache_date = '2017-01-01'");
3526 // Reset so it does not skip.
3527 Civi::$statics['CRM_Contact_BAO_GroupContactCache']['is_refresh_init'] = FALSE;
3528 }
3529
6a488035 3530}