4 * File for the TestContact class.
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
11 * GNU Affero General Public License version 3
12 * @version $Id: ContactTest.php 31254 2010-12-15 10:09:29Z eileen $
15 * This file is part of CiviCRM
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.
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.
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/>.
33 * Test APIv3 civicrm_contact* functions
35 * @package CiviCRM_APIv3
36 * @subpackage API_Contact
39 class api_v3_ContactTest
extends CiviUnitTestCase
{
40 public $DBResetRequired = FALSE;
41 protected $_apiversion;
45 protected $_contactID;
46 protected $_financialTypeId = 1;
49 * Test setup for every test.
51 * Connect to the database, truncate the tables that will be used
52 * and redirect stdin to a temporary file
54 public function setUp() {
55 // Connect to the database.
57 $this->_apiversion
= 3;
58 $this->_entity
= 'contact';
59 $this->_params
= array(
60 'first_name' => 'abc1',
61 'contact_type' => 'Individual',
62 'last_name' => 'xyz1',
67 * Restore the DB for the next test.
71 public function tearDown() {
72 $this->callAPISuccess('Setting', 'create', array('includeOrderByClause' => TRUE));
73 // truncate a few tables
74 $tablesToTruncate = array(
76 'civicrm_contribution',
79 'civicrm_relationship',
83 'civicrm_acl_contact_cache',
84 'civicrm_activity_contact',
87 'civicrm_group_contact',
88 'civicrm_saved_search',
89 'civicrm_group_contact_cache',
92 $this->quickCleanup($tablesToTruncate, TRUE);
97 * Test civicrm_contact_create.
99 * Verify that attempt to create individual contact with only
100 * first and last names succeeds
102 public function testAddCreateIndividual() {
103 $oldCount = CRM_Core_DAO
::singleValueQuery('select count(*) from civicrm_contact');
105 'first_name' => 'abc1',
106 'contact_type' => 'Individual',
107 'last_name' => 'xyz1',
110 $contact = $this->callAPISuccess('contact', 'create', $params);
111 $this->assertTrue(is_numeric($contact['id']));
112 $this->assertTrue($contact['id'] > 0);
113 $newCount = CRM_Core_DAO
::singleValueQuery('select count(*) from civicrm_contact');
114 $this->assertEquals($oldCount +
1, $newCount);
116 $this->assertDBState('CRM_Contact_DAO_Contact',
123 * Test that it is possible to prevent cache clearing via option.
125 * Cache clearing is bypassed if 'options' => array('do_not_reset_cache' => 1 is used.
127 public function testCreateIndividualNoCacheClear() {
129 $contact = $this->callAPISuccess('contact', 'create', $this->_params
);
130 $groupID = $this->groupCreate();
132 $this->putGroupContactCacheInClearableState($groupID, $contact);
134 $this->callAPISuccess('contact', 'create', array('id' => $contact['id']));
135 $this->assertEquals(0, CRM_Core_DAO
::singleValueQuery("SELECT count(*) FROM civicrm_group_contact_cache"));
137 // Rinse & repeat, but with the option.
138 $this->putGroupContactCacheInClearableState($groupID, $contact);
139 CRM_Core_Config
::setPermitCacheFlushMode(FALSE);
140 $this->callAPISuccess('contact', 'create', array('id' => $contact['id']));
141 $this->assertEquals(1, CRM_Core_DAO
::singleValueQuery("SELECT count(*) FROM civicrm_group_contact_cache"));
142 CRM_Core_Config
::setPermitCacheFlushMode(TRUE);
146 * Test for international string acceptance (CRM-10210).
147 * Requires the databsase to be in utf8.
149 * @dataProvider getInternationalStrings
151 * @param string $string
152 * String to be tested.
154 * Bool to see if we should check charset.
158 public function testInternationalStrings($string) {
159 $this->callAPISuccess('Contact', 'create', array_merge(
161 array('first_name' => $string)
164 $result = $this->callAPISuccessGetSingle('Contact', array('first_name' => $string));
165 $this->assertEquals($string, $result['first_name']);
167 $organizationParams = array(
168 'organization_name' => $string,
169 'contact_type' => 'Organization',
172 $this->callAPISuccess('Contact', 'create', $organizationParams);
173 $result = $this->callAPISuccessGetSingle('Contact', $organizationParams);
174 $this->assertEquals($string, $result['organization_name']);
178 * Get international string data for testing against api calls.
180 public function getInternationalStrings() {
181 $invocations = array();
182 $invocations[] = array('Scarabée');
183 $invocations[] = array('Iñtërnâtiônàlizætiøn');
184 $invocations[] = array('これは日本語のテキストです。読めますか');
185 $invocations[] = array('देखें हिन्दी कैसी नजर आती है। अरे वाह ये तो नजर आती है।');
190 * Test civicrm_contact_create.
192 * Verify that preferred language can be set.
194 public function testAddCreateIndividualWithPreferredLanguage() {
196 'first_name' => 'abc1',
197 'contact_type' => 'Individual',
198 'last_name' => 'xyz1',
199 'preferred_language' => 'es_ES',
202 $contact = $this->callAPISuccess('contact', 'create', $params);
203 $this->getAndCheck($params, $contact['id'], 'Contact');
207 * Test civicrm_contact_create with sub-types.
209 * Verify that sub-types are created successfully and not deleted by subsequent updates.
211 public function testIndividualSubType() {
213 'first_name' => 'test abc',
214 'contact_type' => 'Individual',
215 'last_name' => 'test xyz',
216 'contact_sub_type' => array('Student', 'Staff'),
218 $contact = $this->callAPISuccess('contact', 'create', $params);
219 $cid = $contact['id'];
223 'middle_name' => 'foo',
225 $this->callAPISuccess('contact', 'create', $params);
226 unset($params['middle_name']);
228 $contact = $this->callAPISuccess('contact', 'get', $params);
230 $this->assertEquals(array('Student', 'Staff'), $contact['values'][$cid]['contact_sub_type']);
234 * Verify that we can retreive contacts of different sub types
236 public function testGetMultipleContactSubTypes() {
238 // This test presumes that there are no parents or students in the dataset
241 $student = $this->callAPISuccess('contact', 'create', array(
242 'email' => 'student@example.com',
243 'contact_type' => 'Individual',
244 'contact_sub_type' => 'Student',
248 $parent = $this->callAPISuccess('contact', 'create', array(
249 'email' => 'parent@example.com',
250 'contact_type' => 'Individual',
251 'contact_sub_type' => 'Parent',
255 $this->callAPISuccess('contact', 'create', array(
256 'email' => 'parent@example.com',
257 'contact_type' => 'Individual',
260 // get all students and parents
261 $getParams = array('contact_sub_type' => array('IN' => array('Parent', 'Student')));
262 $result = civicrm_api3('contact', 'get', $getParams);
264 // check that we retrieved the student and the parent
265 $this->assertArrayHasKey($student['id'], $result['values']);
266 $this->assertArrayHasKey($parent['id'], $result['values']);
267 $this->assertEquals(2, $result['count']);
272 * Verify that attempt to create contact with empty params fails.
274 public function testCreateEmptyContact() {
275 $this->callAPIFailure('contact', 'create', array());
279 * Verify that attempt to create contact with bad contact type fails.
281 public function testCreateBadTypeContact() {
283 'email' => 'man1@yahoo.com',
284 'contact_type' => 'Does not Exist',
286 $this->callAPIFailure('contact', 'create', $params, "'Does not Exist' is not a valid option for field contact_type");
290 * Verify that attempt to create individual contact without required fields fails.
292 public function testCreateBadRequiredFieldsIndividual() {
294 'middle_name' => 'This field is not required',
295 'contact_type' => 'Individual',
297 $this->callAPIFailure('contact', 'create', $params);
301 * Verify that attempt to create household contact without required fields fails.
303 public function testCreateBadRequiredFieldsHousehold() {
305 'middle_name' => 'This field is not required',
306 'contact_type' => 'Household',
308 $this->callAPIFailure('contact', 'create', $params);
312 * Test required field check.
314 * Verify that attempt to create organization contact without required fields fails.
316 public function testCreateBadRequiredFieldsOrganization() {
318 'middle_name' => 'This field is not required',
319 'contact_type' => 'Organization',
322 $this->callAPIFailure('contact', 'create', $params);
326 * Verify that attempt to create individual contact with only an email succeeds.
328 public function testCreateEmailIndividual() {
329 $primaryEmail = 'man3@yahoo.com';
330 $notPrimaryEmail = 'man4@yahoo.com';
332 'email' => $primaryEmail,
333 'contact_type' => 'Individual',
334 'location_type_id' => 1,
337 $contact1 = $this->callAPISuccess('contact', 'create', $params);
339 $this->assertEquals(3, $contact1['id']);
340 $email1 = $this->callAPISuccess('email', 'get', array('contact_id' => $contact1['id']));
341 $this->assertEquals(1, $email1['count']);
342 $this->assertEquals($primaryEmail, $email1['values'][$email1['id']]['email']);
344 $email2 = $this->callAPISuccess('email', 'create', array('contact_id' => $contact1['id'], 'is_primary' => 0, 'email' => $notPrimaryEmail));
346 // Case 1: Check with criteria primary 'email' => array('IS NOT NULL' => 1)
347 $result = $this->callAPISuccess('contact', 'get', array('email' => array('IS NOT NULL' => 1)));
348 $primaryEmailContactIds = array_keys($result['values']);
349 $this->assertEquals($primaryEmail, $email1['values'][$email1['id']]['email']);
351 // Case 2: Check with criteria primary 'email' => array('<>' => '')
352 $result = $this->callAPISuccess('contact', 'get', array('email' => array('<>' => '')));
353 $primaryEmailContactIds = array_keys($result['values']);
354 $this->assertEquals($primaryEmail, $email1['values'][$email1['id']]['email']);
356 // Case 3: Check with email_id='primary email id'
357 $result = $this->callAPISuccess('contact', 'get', array('email_id' => $email1['id']));
358 $this->assertEquals(1, $result['count']);
359 $this->assertEquals($contact1['id'], $result['id']);
361 $this->callAPISuccess('contact', 'delete', $contact1);
365 * Test creating individual by name.
367 * Verify create individual contact with only first and last names succeeds.
369 public function testCreateNameIndividual() {
371 'first_name' => 'abc1',
372 'contact_type' => 'Individual',
373 'last_name' => 'xyz1',
376 $this->callAPISuccess('contact', 'create', $params);
380 * Test creating individual by display_name.
382 * Display name & sort name should be set.
384 public function testCreateDisplayNameIndividual() {
386 'display_name' => 'abc1',
387 'contact_type' => 'Individual',
390 $contact = $this->callAPISuccess('contact', 'create', $params);
391 $params['sort_name'] = 'abc1';
392 $this->getAndCheck($params, $contact['id'], 'contact');
396 * Test that name searches are case insensitive.
398 public function testGetNameVariantsCaseInsensitive() {
399 $this->callAPISuccess('contact', 'create', [
400 'display_name' => 'Abc1',
401 'contact_type' => 'Individual',
403 $this->callAPISuccessGetSingle('Contact', ['display_name' => 'aBc1']);
404 $this->callAPISuccessGetSingle('Contact', ['sort_name' => 'aBc1']);
405 Civi
::settings()->set('includeNickNameInName', TRUE);
406 $this->callAPISuccessGetSingle('Contact', ['display_name' => 'aBc1']);
407 $this->callAPISuccessGetSingle('Contact', ['sort_name' => 'aBc1']);
408 Civi
::settings()->set('includeNickNameInName', FALSE);
412 * Test old keys still work.
414 * Verify that attempt to create individual contact with
415 * first and last names and old key values works
417 public function testCreateNameIndividualOldKeys() {
419 'individual_prefix' => 'Dr.',
420 'first_name' => 'abc1',
421 'contact_type' => 'Individual',
422 'last_name' => 'xyz1',
423 'individual_suffix' => 'Jr.',
426 $contact = $this->callAPISuccess('contact', 'create', $params);
427 $result = $this->callAPISuccess('contact', 'getsingle', array('id' => $contact['id']));
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']);
437 * Test preferred keys work.
439 * Verify that attempt to create individual contact with
440 * first and last names and old key values works
442 public function testCreateNameIndividualRecommendedKeys2() {
444 'prefix_id' => 'Dr.',
445 'first_name' => 'abc1',
446 'contact_type' => 'Individual',
447 'last_name' => 'xyz1',
448 'suffix_id' => 'Jr.',
449 'gender_id' => 'Male',
452 $contact = $this->callAPISuccess('contact', 'create', $params);
453 $result = $this->callAPISuccess('contact', 'getsingle', array('id' => $contact['id']));
455 $this->assertArrayKeyExists('prefix_id', $result);
456 $this->assertArrayKeyExists('suffix_id', $result);
457 $this->assertArrayKeyExists('gender_id', $result);
458 $this->assertEquals(4, $result['prefix_id']);
459 $this->assertEquals(1, $result['suffix_id']);
463 * Test household name is sufficient for create.
465 * Verify that attempt to create household contact with only
466 * household name succeeds
468 public function testCreateNameHousehold() {
470 'household_name' => 'The abc Household',
471 'contact_type' => 'Household',
473 $this->callAPISuccess('contact', 'create', $params);
477 * Test organization name is sufficient for create.
479 * Verify that attempt to create organization contact with only
480 * organization name succeeds.
482 public function testCreateNameOrganization() {
484 'organization_name' => 'The abc Organization',
485 'contact_type' => 'Organization',
487 $this->callAPISuccess('contact', 'create', $params);
491 * Verify that attempt to create organization contact without organization name fails.
493 public function testCreateNoNameOrganization() {
495 'first_name' => 'The abc Organization',
496 'contact_type' => 'Organization',
498 $this->callAPIFailure('contact', 'create', $params);
502 * Check that permissions on API key are restricted (CRM-18112).
504 public function testCreateApiKey() {
505 $config = CRM_Core_Config
::singleton();
506 $contactId = $this->individualCreate(array(
511 // Allow edit -- because permissions aren't being checked
512 $config->userPermissionClass
->permissions
= array();
513 $result = $this->callAPISuccess('Contact', 'create', array(
515 'api_key' => 'original',
517 $this->assertEquals('original', $result['values'][$contactId]['api_key']);
519 // Allow edit -- because we have adequate permission
520 $config->userPermissionClass
->permissions
= array('access CiviCRM', 'edit all contacts', 'edit api keys');
521 $result = $this->callAPISuccess('Contact', 'create', array(
522 'check_permissions' => 1,
524 'api_key' => 'abcd1234',
526 $this->assertEquals('abcd1234', $result['values'][$contactId]['api_key']);
528 // Disallow edit -- because we don't have permission
529 $config->userPermissionClass
->permissions
= array('access CiviCRM', 'edit all contacts');
530 $result = $this->callAPIFailure('Contact', 'create', array(
531 'check_permissions' => 1,
533 'api_key' => 'defg4321',
535 $this->assertRegExp(';Permission denied to modify api key;', $result['error_message']);
537 // Return everything -- because permissions are not being checked
538 $config->userPermissionClass
->permissions
= array();
539 $result = $this->callAPISuccess('Contact', 'create', array(
541 'first_name' => 'A2',
543 $this->assertEquals('A2', $result['values'][$contactId]['first_name']);
544 $this->assertEquals('B', $result['values'][$contactId]['last_name']);
545 $this->assertEquals('abcd1234', $result['values'][$contactId]['api_key']);
547 // Return everything -- because we have adequate permission
548 $config->userPermissionClass
->permissions
= array('access CiviCRM', 'edit all contacts', 'edit api keys');
549 $result = $this->callAPISuccess('Contact', 'create', array(
550 'check_permissions' => 1,
552 'first_name' => 'A3',
554 $this->assertEquals('A3', $result['values'][$contactId]['first_name']);
555 $this->assertEquals('B', $result['values'][$contactId]['last_name']);
556 $this->assertEquals('abcd1234', $result['values'][$contactId]['api_key']);
558 // Restricted return -- because we don't have permission
559 $config->userPermissionClass
->permissions
= array('access CiviCRM', 'edit all contacts');
560 $result = $this->callAPISuccess('Contact', 'create', array(
561 'check_permissions' => 1,
563 'first_name' => 'A4',
565 $this->assertEquals('A4', $result['values'][$contactId]['first_name']);
566 $this->assertEquals('B', $result['values'][$contactId]['last_name']);
567 $this->assertTrue(empty($result['values'][$contactId]['api_key']));
571 * Check with complete array + custom field.
573 * Note that the test is written on purpose without any
574 * variables specific to participant so it can be replicated into other entities
575 * and / or moved to the automated test suite
577 public function testCreateWithCustom() {
578 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__
, __FILE__
);
580 $params = $this->_params
;
581 $params['custom_' . $ids['custom_field_id']] = "custom string";
582 $description = "This demonstrates setting a custom field through the API.";
583 $result = $this->callAPIAndDocument($this->_entity
, 'create', $params, __FUNCTION__
, __FILE__
, $description);
585 $check = $this->callAPISuccess($this->_entity
, 'get', array(
586 'return.custom_' . $ids['custom_field_id'] => 1,
587 'id' => $result['id'],
589 $this->assertEquals("custom string", $check['values'][$check['id']]['custom_' . $ids['custom_field_id']]);
591 $this->customFieldDelete($ids['custom_field_id']);
592 $this->customGroupDelete($ids['custom_group_id']);
596 * CRM-12773 - expectation is that civicrm quietly ignores fields without values.
598 public function testCreateWithNULLCustomCRM12773() {
599 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__
, __FILE__
);
600 $params = $this->_params
;
601 $params['custom_' . $ids['custom_field_id']] = NULL;
602 $this->callAPISuccess('contact', 'create', $params);
603 $this->customFieldDelete($ids['custom_field_id']);
604 $this->customGroupDelete($ids['custom_group_id']);
608 * CRM-14232 test preferred language set to site default if not passed.
610 public function testCreatePreferredLanguageUnset() {
611 $this->callAPISuccess('Contact', 'create', array(
612 'first_name' => 'Snoop',
613 'last_name' => 'Dog',
614 'contact_type' => 'Individual')
616 $result = $this->callAPISuccessGetSingle('Contact', array('last_name' => 'Dog'));
617 $this->assertEquals('en_US', $result['preferred_language']);
621 * CRM-14232 test preferred language returns setting if not passed.
623 public function testCreatePreferredLanguageSet() {
624 $this->callAPISuccess('Setting', 'create', array('contact_default_language' => 'fr_FR'));
625 $this->callAPISuccess('Contact', 'create', array(
626 'first_name' => 'Snoop',
627 'last_name' => 'Dog',
628 'contact_type' => 'Individual',
630 $result = $this->callAPISuccessGetSingle('Contact', array('last_name' => 'Dog'));
631 $this->assertEquals('fr_FR', $result['preferred_language']);
635 * CRM-14232 test preferred language returns setting if not passed where setting is NULL.
637 public function testCreatePreferredLanguageNull() {
638 $this->callAPISuccess('Setting', 'create', array('contact_default_language' => 'null'));
639 $this->callAPISuccess('Contact', 'create', array(
640 'first_name' => 'Snoop',
641 'last_name' => 'Dog',
642 'contact_type' => 'Individual',
645 $result = $this->callAPISuccessGetSingle('Contact', array('last_name' => 'Dog'));
646 $this->assertEquals(NULL, $result['preferred_language']);
650 * CRM-14232 test preferred language returns setting if not passed where setting is NULL.
652 public function testCreatePreferredLanguagePassed() {
653 $this->callAPISuccess('Setting', 'create', array('contact_default_language' => 'null'));
654 $this->callAPISuccess('Contact', 'create', array(
655 'first_name' => 'Snoop',
656 'last_name' => 'Dog',
657 'contact_type' => 'Individual',
658 'preferred_language' => 'en_AU',
660 $result = $this->callAPISuccessGetSingle('Contact', array('last_name' => 'Dog'));
661 $this->assertEquals('en_AU', $result['preferred_language']);
665 * CRM-15792 - create/update datetime field for contact.
667 public function testCreateContactCustomFldDateTime() {
668 $customGroup = $this->customGroupCreate(array('extends' => 'Individual', 'title' => 'datetime_test_group'));
669 $dateTime = CRM_Utils_Date
::currentDBDate();
670 //check date custom field is saved along with time when time_format is set
672 'first_name' => 'abc3',
673 'last_name' => 'xyz3',
674 'contact_type' => 'Individual',
675 'email' => 'man3@yahoo.com',
676 'api.CustomField.create' => array(
677 'custom_group_id' => $customGroup['id'],
678 'name' => 'test_datetime',
679 'label' => 'Demo Date',
680 'html_type' => 'Select Date',
681 'data_type' => 'Date',
685 'is_searchable' => 0,
690 $result = $this->callAPISuccess('Contact', 'create', $params);
691 $customFldId = $result['values'][$result['id']]['api.CustomField.create']['id'];
692 $this->assertNotNull($result['id']);
693 $this->assertNotNull($customFldId);
696 'id' => $result['id'],
697 "custom_{$customFldId}" => $dateTime,
698 'api.CustomValue.get' => 1,
701 $result = $this->callAPISuccess('Contact', 'create', $params);
702 $this->assertNotNull($result['id']);
703 $customFldDate = date("YmdHis", strtotime($result['values'][$result['id']]['api.CustomValue.get']['values'][0]['latest']));
704 $this->assertNotNull($customFldDate);
705 $this->assertEquals($dateTime, $customFldDate);
706 $customValueId = $result['values'][$result['id']]['api.CustomValue.get']['values'][0]['id'];
707 $dateTime = date('Ymd');
708 //date custom field should not contain time part when time_format is null
710 'id' => $result['id'],
711 'api.CustomField.create' => array(
712 'id' => $customFldId,
713 'html_type' => 'Select Date',
714 'data_type' => 'Date',
717 'api.CustomValue.create' => array(
718 'id' => $customValueId,
719 'entity_id' => $result['id'],
720 "custom_{$customFldId}" => $dateTime,
722 'api.CustomValue.get' => 1,
724 $result = $this->callAPISuccess('Contact', 'create', $params);
725 $this->assertNotNull($result['id']);
726 $customFldDate = date("Ymd", strtotime($result['values'][$result['id']]['api.CustomValue.get']['values'][0]['latest']));
727 $customFldTime = date("His", strtotime($result['values'][$result['id']]['api.CustomValue.get']['values'][0]['latest']));
728 $this->assertNotNull($customFldDate);
729 $this->assertEquals($dateTime, $customFldDate);
730 $this->assertEquals(000000, $customFldTime);
731 $this->callAPISuccess('Contact', 'create', $params);
736 * Test creating a current employer through API.
738 public function testContactCreateCurrentEmployer() {
739 // Here we will just do the get for set-up purposes.
740 $count = $this->callAPISuccess('contact', 'getcount', array(
741 'organization_name' => 'new employer org',
742 'contact_type' => 'Organization',
744 $this->assertEquals(0, $count);
745 $employerResult = $this->callAPISuccess('contact', 'create', array_merge($this->_params
, array(
746 'current_employer' => 'new employer org',
749 // do it again as an update to check it doesn't cause an error
750 $employerResult = $this->callAPISuccess('contact', 'create', array_merge($this->_params
, array(
751 'current_employer' => 'new employer org',
752 'id' => $employerResult['id'],
756 $this->callAPISuccess('contact', 'getcount', array(
757 'organization_name' => 'new employer org',
758 'contact_type' => 'Organization',
762 $result = $this->callAPISuccess('contact', 'getsingle', array(
763 'id' => $employerResult['id'],
766 $this->assertEquals('new employer org', $result['current_employer']);
771 * Test creating a current employer through API.
773 * Check it will re-activate a de-activated employer
775 public function testContactCreateDuplicateCurrentEmployerEnables() {
776 // Set up - create employer relationship.
777 $employerResult = $this->callAPISuccess('contact', 'create', array_merge($this->_params
, array(
778 'current_employer' => 'new employer org',
781 $relationship = $this->callAPISuccess('relationship', 'get', array(
782 'contact_id_a' => $employerResult['id'],
785 //disable & check it is disabled
786 $this->callAPISuccess('relationship', 'create', array('id' => $relationship['id'], 'is_active' => 0));
787 $this->callAPISuccess('relationship', 'getvalue', array(
788 'id' => $relationship['id'],
789 'return' => 'is_active',
792 // Re-set the current employer - thus enabling the relationship.
793 $this->callAPISuccess('contact', 'create', array_merge($this->_params
, array(
794 'current_employer' => 'new employer org',
795 'id' => $employerResult['id'],
798 //check is_active is now 1
799 $relationship = $this->callAPISuccess('relationship', 'getsingle', array(
800 'return' => 'is_active',
802 $this->assertEquals(1, $relationship['is_active']);
806 * Check deceased contacts are not retrieved.
808 * Note at time of writing the default is to return default. This should possibly be changed & test added.
810 public function testGetDeceasedRetrieved() {
811 $this->callAPISuccess($this->_entity
, 'create', $this->_params
);
812 $c2 = $this->callAPISuccess($this->_entity
, 'create', array(
813 'first_name' => 'bb',
814 'last_name' => 'ccc',
815 'contact_type' => 'Individual',
818 $result = $this->callAPISuccess($this->_entity
, 'get', array('is_deceased' => 0));
819 $this->assertFalse(array_key_exists($c2['id'], $result['values']));
823 * Test that sort works - old syntax.
825 public function testGetSort() {
826 $c1 = $this->callAPISuccess($this->_entity
, 'create', $this->_params
);
827 $c2 = $this->callAPISuccess($this->_entity
, 'create', array(
828 'first_name' => 'bb',
829 'last_name' => 'ccc',
830 'contact_type' => 'Individual',
832 $result = $this->callAPISuccess($this->_entity
, 'get', array(
833 'sort' => 'first_name ASC',
834 'return.first_name' => 1,
837 'contact_type' => 'Individual',
840 $this->assertEquals('abc1', $result['values'][0]['first_name']);
841 $result = $this->callAPISuccess($this->_entity
, 'get', array(
842 'sort' => 'first_name DESC',
843 'return.first_name' => 1,
847 $this->assertEquals('bb', $result['values'][0]['first_name']);
849 $this->callAPISuccess($this->_entity
, 'delete', array('id' => $c1['id']));
850 $this->callAPISuccess($this->_entity
, 'delete', array('id' => $c2['id']));
854 * Test that we can retrieve contacts using array syntax.
856 * I.e 'id' => array('IN' => array('3,4')).
858 public function testGetINIDArray() {
859 $c1 = $this->callAPISuccess($this->_entity
, 'create', $this->_params
);
860 $c2 = $this->callAPISuccess($this->_entity
, 'create', array(
861 'first_name' => 'bb',
862 'last_name' => 'ccc',
863 'contact_type' => 'Individual',
865 $c3 = $this->callAPISuccess($this->_entity
, 'create', array(
866 'first_name' => 'hh',
868 'contact_type' => 'Individual',
870 $result = $this->callAPISuccess($this->_entity
, 'get', array('id' => array('IN' => array($c1['id'], $c3['id']))));
871 $this->assertEquals(2, $result['count']);
872 $this->assertEquals(array($c1['id'], $c3['id']), array_keys($result['values']));
873 $this->callAPISuccess($this->_entity
, 'delete', array('id' => $c1['id']));
874 $this->callAPISuccess($this->_entity
, 'delete', array('id' => $c2['id']));
875 $this->callAPISuccess($this->_entity
, 'delete', array('id' => $c3['id']));
879 * Test variants on deleted behaviour.
881 public function testGetDeleted() {
882 $params = $this->_params
;
883 $contact1 = $this->callAPISuccess('contact', 'create', $params);
884 $params['is_deleted'] = 1;
885 $params['last_name'] = 'bcd';
886 $contact2 = $this->callAPISuccess('contact', 'create', $params);
887 $countActive = $this->callAPISuccess('contact', 'getcount', array(
888 'showAll' => 'active',
889 'contact_type' => 'Individual',
891 $countAll = $this->callAPISuccess('contact', 'getcount', array('showAll' => 'all', 'contact_type' => 'Individual'));
892 $countTrash = $this->callAPISuccess('contact', 'getcount', array('showAll' => 'trash', 'contact_type' => 'Individual'));
893 $countDefault = $this->callAPISuccess('contact', 'getcount', array('contact_type' => 'Individual'));
894 $countDeleted = $this->callAPISuccess('contact', 'getcount', array(
895 'contact_type' => 'Individual',
896 'contact_is_deleted' => 1,
898 $countNotDeleted = $this->callAPISuccess('contact', 'getcount', array(
899 'contact_is_deleted' => 0,
900 'contact_type' => 'Individual',
902 $this->callAPISuccess('contact', 'delete', array('id' => $contact1['id']));
903 $this->callAPISuccess('contact', 'delete', array('id' => $contact2['id']));
904 $this->assertEquals(1, $countNotDeleted, 'contact_is_deleted => 0 is respected');
905 $this->assertEquals(1, $countActive);
906 $this->assertEquals(1, $countTrash);
907 $this->assertEquals(2, $countAll);
908 $this->assertEquals(1, $countDeleted);
909 $this->assertEquals(1, $countDefault, 'Only active by default in line');
913 * Test that sort works - new syntax.
915 public function testGetSortNewSyntax() {
916 $c1 = $this->callAPISuccess($this->_entity
, 'create', $this->_params
);
917 $c2 = $this->callAPISuccess($this->_entity
, 'create', array(
918 'first_name' => 'bb',
919 'last_name' => 'ccc',
920 'contact_type' => 'Individual',
922 $result = $this->callAPISuccess($this->_entity
, 'getvalue', array(
923 'return' => 'first_name',
924 'contact_type' => 'Individual',
927 'sort' => 'first_name',
930 $this->assertEquals('abc1', $result);
932 $result = $this->callAPISuccess($this->_entity
, 'getvalue', array(
933 'return' => 'first_name',
934 'contact_type' => 'Individual',
937 'sort' => 'first_name DESC',
940 $this->assertEquals('bb', $result);
942 $this->callAPISuccess($this->_entity
, 'delete', array('id' => $c1['id']));
943 $this->callAPISuccess($this->_entity
, 'delete', array('id' => $c2['id']));
947 * Test sort and limit for chained relationship get.
949 * https://issues.civicrm.org/jira/browse/CRM-15983
951 public function testSortLimitChainedRelationshipGetCRM15983() {
953 $create_result_1 = $this->callAPISuccess('contact', 'create', array(
954 'first_name' => 'Jules',
955 'last_name' => 'Smos',
956 'contact_type' => 'Individual',
959 // Create another contact with two relationships.
960 $create_params = array(
961 'first_name' => 'Jos',
962 'last_name' => 'Smos',
963 'contact_type' => 'Individual',
964 'api.relationship.create' => array(
966 'contact_id_a' => '$value.id',
967 'contact_id_b' => $create_result_1['id'],
969 'relationship_type_id' => 2,
970 'start_date' => '2005-01-12',
971 'end_date' => '2006-01-11',
972 'description' => 'old',
975 'contact_id_a' => '$value.id',
976 'contact_id_b' => $create_result_1['id'],
977 // spouse of (was married twice :))
978 'relationship_type_id' => 2,
979 'start_date' => '2006-07-01',
980 'end_date' => '2010-07-01',
981 'description' => 'new',
985 $create_result = $this->callAPISuccess('contact', 'create', $create_params);
987 // Try to retrieve the contact and the most recent relationship.
990 'id' => $create_result['id'],
991 'api.relationship.get' => array(
992 'contact_id_a' => '$value.id',
995 'sort' => 'start_date DESC',
998 $get_result = $this->callAPISuccess('contact', 'getsingle', $get_params);
1001 $this->callAPISuccess('contact', 'delete', array(
1002 'id' => $create_result['id'],
1006 $this->assertEquals(1, $get_result['api.relationship.get']['count']);
1007 $this->assertEquals('new', $get_result['api.relationship.get']['values'][0]['description']);
1011 * Test apostrophe works in get & create.
1013 public function testGetApostropheCRM10857() {
1014 $params = array_merge($this->_params
, array('last_name' => "O'Connor"));
1015 $this->callAPISuccess($this->_entity
, 'create', $params);
1016 $result = $this->callAPISuccess($this->_entity
, 'getsingle', array(
1017 'last_name' => "O'Connor",
1020 $this->assertEquals("O'Connor", $result['last_name'], 'in line' . __LINE__
);
1024 * Test retrieval by addressee id.
1026 public function testGetByAddresseeID() {
1027 $individual1ID = $this->individualCreate([
1028 'skip_greeting_processing' => 1,
1029 'addressee_id' => 'null',
1030 'email_greeting_id' => 'null',
1031 'postal_greeting_id' => 'null'
1033 $individual2ID = $this->individualCreate();
1035 $this->assertEquals($individual1ID,
1036 $this->callAPISuccessGetValue('Contact', ['contact_type' => 'Individual', 'addressee_id' => ['IS NULL' => 1], 'return' => 'id'])
1038 $this->assertEquals($individual1ID,
1039 $this->callAPISuccessGetValue('Contact', ['contact_type' => 'Individual', 'email_greeting_id' => ['IS NULL' => 1], 'return' => 'id'])
1041 $this->assertEquals($individual1ID,
1042 $this->callAPISuccessGetValue('Contact', ['contact_type' => 'Individual', 'postal_greeting_id' => ['IS NULL' => 1], 'return' => 'id'])
1045 $this->assertEquals($individual2ID,
1046 $this->callAPISuccessGetValue('Contact', ['contact_type' => 'Individual', 'addressee_id' => ['NOT NULL' => 1], 'return' => 'id'])
1051 * Check with complete array + custom field.
1053 * Note that the test is written on purpose without any
1054 * variables specific to participant so it can be replicated into other entities
1055 * and / or moved to the automated test suite
1057 public function testGetWithCustom() {
1058 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__
, __FILE__
);
1060 $params = $this->_params
;
1061 $params['custom_' . $ids['custom_field_id']] = "custom string";
1062 $description = "This demonstrates setting a custom field through the API.";
1063 $subfile = "CustomFieldGet";
1064 $result = $this->callAPISuccess($this->_entity
, 'create', $params);
1066 $check = $this->callAPIAndDocument($this->_entity
, 'get', array(
1067 'return.custom_' . $ids['custom_field_id'] => 1,
1068 'id' => $result['id'],
1069 ), __FUNCTION__
, __FILE__
, $description, $subfile);
1071 $this->assertEquals("custom string", $check['values'][$check['id']]['custom_' . $ids['custom_field_id']]);
1072 $fields = ($this->callAPISuccess('contact', 'getfields', $params));
1073 $this->assertTrue(is_array($fields['values']['custom_' . $ids['custom_field_id']]));
1074 $this->customFieldDelete($ids['custom_field_id']);
1075 $this->customGroupDelete($ids['custom_group_id']);
1079 * Check with complete array + custom field.
1081 * Note that the test is written on purpose without any
1082 * variables specific to participant so it can be replicated into other entities
1083 * and / or moved to the automated test suite
1085 public function testGetWithCustomReturnSyntax() {
1086 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__
, __FILE__
);
1088 $params = $this->_params
;
1089 $params['custom_' . $ids['custom_field_id']] = "custom string";
1090 $description = "This demonstrates setting a custom field through the API.";
1091 $subfile = "CustomFieldGetReturnSyntaxVariation";
1092 $result = $this->callAPISuccess($this->_entity
, 'create', $params);
1093 $params = array('return' => 'custom_' . $ids['custom_field_id'], 'id' => $result['id']);
1094 $check = $this->callAPIAndDocument($this->_entity
, 'get', $params, __FUNCTION__
, __FILE__
, $description, $subfile);
1096 $this->assertEquals("custom string", $check['values'][$check['id']]['custom_' . $ids['custom_field_id']]);
1097 $this->customFieldDelete($ids['custom_field_id']);
1098 $this->customGroupDelete($ids['custom_group_id']);
1102 * Check that address name, ID is returned if required.
1104 public function testGetReturnAddress() {
1105 $contactID = $this->individualCreate();
1106 $result = $this->callAPISuccess('address', 'create', array(
1107 'contact_id' => $contactID,
1108 'address_name' => 'My house',
1109 'location_type_id' => 'Home',
1110 'street_address' => '1 my road',
1112 $addressID = $result['id'];
1114 $result = $this->callAPISuccessGetSingle('contact', array(
1115 'return' => 'address_name, street_address, address_id',
1118 $this->assertEquals($addressID, $result['address_id']);
1119 $this->assertEquals('1 my road', $result['street_address']);
1120 $this->assertEquals('My house', $result['address_name']);
1125 * Test group filter syntaxes.
1127 public function testGetGroupIDFromContact() {
1128 $groupId = $this->groupCreate();
1130 'email' => 'man2@yahoo.com',
1131 'contact_type' => 'Individual',
1132 'location_type_id' => 1,
1133 'api.group_contact.create' => array('group_id' => $groupId),
1136 $this->callAPISuccess('contact', 'create', $params);
1137 // testing as integer
1139 'filter.group_id' => $groupId,
1140 'contact_type' => 'Individual',
1142 $result = $this->callAPISuccess('contact', 'get', $params);
1143 $this->assertEquals(1, $result['count']);
1144 // group 26 doesn't exist, but we can still search contacts in it.
1146 'filter.group_id' => 26,
1147 'contact_type' => 'Individual',
1149 $this->callAPISuccess('contact', 'get', $params);
1150 // testing as string
1152 'filter.group_id' => "$groupId, 26",
1153 'contact_type' => 'Individual',
1155 $result = $this->callAPISuccess('contact', 'get', $params);
1156 $this->assertEquals(1, $result['count']);
1158 'filter.group_id' => "26,27",
1159 'contact_type' => 'Individual',
1161 $this->callAPISuccess('contact', 'get', $params);
1163 // testing as string
1165 'filter.group_id' => array($groupId, 26),
1166 'contact_type' => 'Individual',
1168 $result = $this->callAPISuccess('contact', 'get', $params);
1169 $this->assertEquals(1, $result['count']);
1171 //test in conjunction with other criteria
1173 'filter.group_id' => array($groupId, 26),
1174 'contact_type' => 'Organization',
1176 $this->callAPISuccess('contact', 'get', $params);
1178 'filter.group_id' => array(26, 27),
1179 'contact_type' => 'Individual',
1181 $result = $this->callAPISuccess('contact', 'get', $params);
1182 $this->assertEquals(0, $result['count']);
1186 * Verify that attempt to create individual contact with two chained websites succeeds.
1188 public function testCreateIndividualWithContributionDottedSyntax() {
1189 $description = "This demonstrates the syntax to create 2 chained entities.";
1190 $subFile = "ChainTwoWebsites";
1192 'first_name' => 'abc3',
1193 'last_name' => 'xyz3',
1194 'contact_type' => 'Individual',
1195 'email' => 'man3@yahoo.com',
1196 'api.contribution.create' => array(
1197 'receive_date' => '2010-01-01',
1198 'total_amount' => 100.00,
1199 'financial_type_id' => $this->_financialTypeId
,
1200 'payment_instrument_id' => 1,
1201 'non_deductible_amount' => 10.00,
1202 'fee_amount' => 50.00,
1203 'net_amount' => 90.00,
1205 'invoice_id' => 67990,
1207 'contribution_status_id' => 1,
1208 'skipCleanMoney' => 1,
1210 'api.website.create' => array(
1211 'url' => "http://civicrm.org",
1213 'api.website.create.2' => array(
1214 'url' => "http://chained.org",
1218 $result = $this->callAPIAndDocument('Contact', 'create', $params, __FUNCTION__
, __FILE__
, $description, $subFile);
1220 // checking child function result not covered in callAPIAndDocument
1221 $this->assertAPISuccess($result['values'][$result['id']]['api.website.create']);
1222 $this->assertEquals("http://chained.org", $result['values'][$result['id']]['api.website.create.2']['values'][0]['url']);
1223 $this->assertEquals("http://civicrm.org", $result['values'][$result['id']]['api.website.create']['values'][0]['url']);
1225 // delete the contact
1226 $this->callAPISuccess('contact', 'delete', $result);
1230 * Verify that attempt to create individual contact with chained contribution and website succeeds.
1232 public function testCreateIndividualWithContributionChainedArrays() {
1234 'first_name' => 'abc3',
1235 'last_name' => 'xyz3',
1236 'contact_type' => 'Individual',
1237 'email' => 'man3@yahoo.com',
1238 'api.contribution.create' => array(
1239 'receive_date' => '2010-01-01',
1240 'total_amount' => 100.00,
1241 'financial_type_id' => $this->_financialTypeId
,
1242 'payment_instrument_id' => 1,
1243 'non_deductible_amount' => 10.00,
1244 'fee_amount' => 50.00,
1245 'net_amount' => 90.00,
1247 'invoice_id' => 67890,
1249 'contribution_status_id' => 1,
1250 'skipCleanMoney' => 1,
1252 'api.website.create' => array(
1254 'url' => "http://civicrm.org",
1257 'url' => "http://chained.org",
1258 'website_type_id' => 2,
1263 $description = "Demonstrates creating two websites as an array.";
1264 $subfile = "ChainTwoWebsitesSyntax2";
1265 $result = $this->callAPIAndDocument('Contact', 'create', $params, __FUNCTION__
, __FILE__
, $description, $subfile);
1267 // the callAndDocument doesn't check the chained call
1268 $this->assertEquals(0, $result['values'][$result['id']]['api.website.create'][0]['is_error']);
1269 $this->assertEquals("http://chained.org", $result['values'][$result['id']]['api.website.create'][1]['values'][0]['url']);
1270 $this->assertEquals("http://civicrm.org", $result['values'][$result['id']]['api.website.create'][0]['values'][0]['url']);
1272 $this->callAPISuccess('contact', 'delete', $result);
1276 * Test for direction when chaining relationships.
1278 * https://issues.civicrm.org/jira/browse/CRM-16084
1280 public function testDirectionChainingRelationshipsCRM16084() {
1281 // Some contact, called Jules.
1282 $create_result_1 = $this->callAPISuccess('contact', 'create', array(
1283 'first_name' => 'Jules',
1284 'last_name' => 'Smos',
1285 'contact_type' => 'Individual',
1288 // Another contact: Jos, child of Jules.
1289 $create_params = array(
1290 'first_name' => 'Jos',
1291 'last_name' => 'Smos',
1292 'contact_type' => 'Individual',
1293 'api.relationship.create' => array(
1295 'contact_id_a' => '$value.id',
1296 'contact_id_b' => $create_result_1['id'],
1298 'relationship_type_id' => 1,
1302 $create_result_2 = $this->callAPISuccess('contact', 'create', $create_params);
1304 // Mia is the child of Jos.
1305 $create_params = array(
1306 'first_name' => 'Mia',
1307 'last_name' => 'Smos',
1308 'contact_type' => 'Individual',
1309 'api.relationship.create' => array(
1311 'contact_id_a' => '$value.id',
1312 'contact_id_b' => $create_result_2['id'],
1314 'relationship_type_id' => 1,
1318 $create_result_3 = $this->callAPISuccess('contact', 'create', $create_params);
1320 // Get Jos and his children.
1321 $get_params = array(
1323 'id' => $create_result_2['id'],
1324 'api.relationship.get' => array(
1325 'contact_id_b' => '$value.id',
1326 'relationship_type_id' => 1,
1329 $get_result = $this->callAPISuccess('contact', 'getsingle', $get_params);
1332 $this->callAPISuccess('contact', 'delete', array(
1333 'id' => $create_result_1['id'],
1335 $this->callAPISuccess('contact', 'delete', array(
1336 'id' => $create_result_2['id'],
1338 $this->callAPISuccess('contact', 'delete', array(
1339 'id' => $create_result_2['id'],
1343 $this->assertEquals(1, $get_result['api.relationship.get']['count']);
1344 $this->assertEquals($create_result_3['id'], $get_result['api.relationship.get']['values'][0]['contact_id_a']);
1348 * Verify that attempt to create individual contact with first, and last names and email succeeds.
1350 public function testCreateIndividualWithNameEmail() {
1352 'first_name' => 'abc3',
1353 'last_name' => 'xyz3',
1354 'contact_type' => 'Individual',
1355 'email' => 'man3@yahoo.com',
1358 $contact = $this->callAPISuccess('contact', 'create', $params);
1360 $this->callAPISuccess('contact', 'delete', $contact);
1364 * Verify that attempt to create individual contact with no data fails.
1366 public function testCreateIndividualWithOutNameEmail() {
1368 'contact_type' => 'Individual',
1370 $this->callAPIFailure('contact', 'create', $params);
1374 * Test create individual contact with first &last names, email and location type succeeds.
1376 public function testCreateIndividualWithNameEmailLocationType() {
1378 'first_name' => 'abc4',
1379 'last_name' => 'xyz4',
1380 'email' => 'man4@yahoo.com',
1381 'contact_type' => 'Individual',
1382 'location_type_id' => 1,
1384 $result = $this->callAPISuccess('contact', 'create', $params);
1386 $this->callAPISuccess('contact', 'delete', array('id' => $result['id']));
1390 * Verify that when changing employers the old employer relationship becomes inactive.
1392 public function testCreateIndividualWithEmployer() {
1393 $employer = $this->organizationCreate();
1394 $employer2 = $this->organizationCreate();
1397 'email' => 'man4@yahoo.com',
1398 'contact_type' => 'Individual',
1399 'employer_id' => $employer,
1402 $result = $this->callAPISuccess('contact', 'create', $params);
1403 $relationships = $this->callAPISuccess('relationship', 'get', array(
1404 'contact_id_a' => $result['id'],
1408 $this->assertEquals($employer, $relationships['values'][0]['contact_id_b']);
1410 // Add more random relationships to make the test more realistic
1411 foreach (array('Employee of', 'Volunteer for') as $relationshipType) {
1412 $relTypeId = CRM_Core_DAO
::getFieldValue('CRM_Contact_DAO_RelationshipType', $relationshipType, 'id', 'name_a_b');
1413 $this->callAPISuccess('relationship', 'create', array(
1414 'contact_id_a' => $result['id'],
1415 'contact_id_b' => $this->organizationCreate(),
1417 'relationship_type_id' => $relTypeId,
1421 // Add second employer
1422 $params['employer_id'] = $employer2;
1423 $params['id'] = $result['id'];
1424 $result = $this->callAPISuccess('contact', 'create', $params);
1426 $relationships = $this->callAPISuccess('relationship', 'get', array(
1427 'contact_id_a' => $result['id'],
1432 $this->assertEquals($employer, $relationships['values'][0]['contact_id_b']);
1436 * Verify that attempt to create household contact with details succeeds.
1438 public function testCreateHouseholdDetails() {
1440 'household_name' => 'abc8\'s House',
1441 'nick_name' => 'x House',
1442 'email' => 'man8@yahoo.com',
1443 'contact_type' => 'Household',
1446 $contact = $this->callAPISuccess('contact', 'create', $params);
1448 $this->callAPISuccess('contact', 'delete', $contact);
1452 * Verify that attempt to create household contact with inadequate details fails.
1454 public function testCreateHouseholdInadequateDetails() {
1456 'nick_name' => 'x House',
1457 'email' => 'man8@yahoo.com',
1458 'contact_type' => 'Household',
1460 $this->callAPIFailure('contact', 'create', $params);
1464 * Verify successful update of individual contact.
1466 public function testUpdateIndividualWithAll() {
1467 // Insert a row in civicrm_contact creating individual contact.
1468 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1469 $op->execute($this->_dbconn
,
1470 $this->createXMLDataSet(
1471 dirname(__FILE__
) . '/dataset/contact_ind.xml'
1477 'first_name' => 'abcd',
1478 'contact_type' => 'Individual',
1479 'nick_name' => 'This is nickname first',
1480 'do_not_email' => '1',
1481 'do_not_phone' => '1',
1482 'do_not_mail' => '1',
1483 'do_not_trade' => '1',
1484 'legal_identifier' => 'ABC23853ZZ2235',
1485 'external_identifier' => '1928837465',
1486 'image_URL' => 'http://some.url.com/image.jpg',
1487 'home_url' => 'http://www.example.org',
1491 $this->callAPISuccess('Contact', 'Update', $params);
1492 $getResult = $this->callAPISuccess('Contact', 'Get', $params);
1493 unset($params['contact_id']);
1494 //Todo - neither API v2 or V3 are testing for home_url - not sure if it is being set.
1495 //reducing this test partially back to api v2 level to get it through
1496 unset($params['home_url']);
1497 foreach ($params as $key => $value) {
1498 $this->assertEquals($value, $getResult['values'][23][$key]);
1500 // Check updated civicrm_contact against expected.
1501 $expected = $this->createXMLDataSet(
1502 dirname(__FILE__
) . '/dataset/contact_ind_upd.xml'
1504 $actual = new PHPUnit_Extensions_Database_DataSet_QueryDataSet(
1507 $actual->addTable('civicrm_contact');
1508 $expected->matches($actual);
1512 * Verify successful update of organization contact.
1514 public function testUpdateOrganizationWithAll() {
1515 // Insert a row in civicrm_contact creating organization contact
1516 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1517 $op->execute($this->_dbconn
,
1518 $this->createXMLDataSet(
1519 dirname(__FILE__
) . '/dataset/contact_org.xml'
1525 'organization_name' => 'WebAccess India Pvt Ltd',
1526 'legal_name' => 'WebAccess',
1527 'sic_code' => 'ABC12DEF',
1528 'contact_type' => 'Organization',
1531 $this->callAPISuccess('Contact', 'Update', $params);
1533 // Check updated civicrm_contact against expected.
1534 $expected = $this->createXMLDataSet(
1535 dirname(__FILE__
) . '/dataset/contact_org_upd.xml'
1537 $actual = new PHPUnit_Extensions_Database_DataSet_QueryDataSet(
1540 $actual->addTable('civicrm_contact');
1541 $expected->matches($actual);
1545 * Test merging 2 organizations.
1547 * CRM-20421: This test make sure that inherited memberships are deleted upon merging organization.
1549 public function testMergeOrganizations() {
1550 $organizationID1 = $this->organizationCreate(array(), 0);
1551 $organizationID2 = $this->organizationCreate(array(), 1);
1552 $contact = $this->callAPISuccess('contact', 'create', array_merge($this->_params
, array(
1553 'employer_id' => $organizationID1,
1556 $contact = $contact["values"][$contact["id"]];
1558 $membershipType = $this->createEmployerOfMembership();
1559 $membershipParams = array(
1560 'membership_type_id' => $membershipType["id"],
1561 'contact_id' => $organizationID1,
1562 'start_date' => "01/01/2015",
1563 'join_date' => "01/01/2010",
1564 'end_date' => "12/31/2015",
1566 $ownermembershipid = $this->contactMembershipCreate($membershipParams);
1568 $contactmembership = $this->callAPISuccess("membership", "getsingle", array(
1569 "contact_id" => $contact["id"],
1572 $this->assertEquals($ownermembershipid, $contactmembership["owner_membership_id"], "Contact membership must be inherited from Organization");
1574 CRM_Dedupe_Merger
::moveAllBelongings($organizationID2, $organizationID1, array(
1575 "move_rel_table_memberships" => "0",
1576 "move_rel_table_relationships" => "1",
1577 "main_details" => array(
1578 "contact_id" => $organizationID2,
1579 "contact_type" => "Organization",
1581 "other_details" => array(
1582 "contact_id" => $organizationID1,
1583 "contact_type" => "Organization",
1587 $contactmembership = $this->callAPISuccess("membership", "get", array(
1588 "contact_id" => $contact["id"],
1591 $this->assertEquals(0, $contactmembership["count"], "Contact membership must be deleted after merging organization without memberships.");
1594 private function createEmployerOfMembership() {
1596 'domain_id' => CRM_Core_Config
::domainID(),
1597 'name' => 'Organization Membership',
1598 'description' => NULL,
1599 'member_of_contact_id' => 1,
1600 'financial_type_id' => 1,
1601 'minimum_fee' => 10,
1602 'duration_unit' => 'year',
1603 'duration_interval' => 1,
1604 'period_type' => 'rolling',
1605 'relationship_type_id' => 5,
1606 'relationship_direction' => 'b_a',
1607 'visibility' => 'Public',
1610 $membershipType = $this->callAPISuccess('membership_type', 'create', $params);
1611 return $membershipType["values"][$membershipType["id"]];
1615 * Verify successful update of household contact.
1617 public function testUpdateHouseholdWithAll() {
1618 // Insert a row in civicrm_contact creating household contact
1619 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1620 $op->execute($this->_dbconn
,
1621 $this->createXMLDataSet(
1622 dirname(__FILE__
) . '/dataset/contact_hld.xml'
1628 'household_name' => 'ABC household',
1629 'nick_name' => 'ABC House',
1630 'contact_type' => 'Household',
1633 $result = $this->callAPISuccess('Contact', 'Update', $params);
1636 'contact_type' => 'Household',
1638 'sort_name' => 'ABC household',
1639 'display_name' => 'ABC household',
1640 'nick_name' => 'ABC House',
1642 $this->getAndCheck($expected, $result['id'], 'contact');
1646 * Test civicrm_update() without contact type.
1648 * Deliberately exclude contact_type as it should still cope using civicrm_api.
1652 public function testUpdateCreateWithID() {
1653 // Insert a row in civicrm_contact creating individual contact.
1654 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1655 $op->execute($this->_dbconn
,
1656 $this->createXMLDataSet(
1657 dirname(__FILE__
) . '/dataset/contact_ind.xml'
1663 'first_name' => 'abcd',
1664 'last_name' => 'wxyz',
1666 $this->callAPISuccess('Contact', 'Update', $params);
1670 * Test civicrm_contact_delete() with no contact ID.
1672 public function testContactDeleteNoID() {
1676 $this->callAPIFailure('contact', 'delete', $params);
1680 * Test civicrm_contact_delete() with error.
1682 public function testContactDeleteError() {
1683 $params = array('contact_id' => 999);
1684 $this->callAPIFailure('contact', 'delete', $params);
1688 * Test civicrm_contact_delete().
1690 public function testContactDelete() {
1691 $contactID = $this->individualCreate();
1695 $this->callAPIAndDocument('contact', 'delete', $params, __FUNCTION__
, __FILE__
);
1699 * Test civicrm_contact_get() return only first name.
1701 public function testContactGetRetFirst() {
1702 $contact = $this->callAPISuccess('contact', 'create', $this->_params
);
1704 'contact_id' => $contact['id'],
1705 'return_first_name' => TRUE,
1706 'sort' => 'first_name',
1708 $result = $this->callAPISuccess('contact', 'get', $params);
1709 $this->assertEquals(1, $result['count']);
1710 $this->assertEquals($contact['id'], $result['id']);
1711 $this->assertEquals('abc1', $result['values'][$contact['id']]['first_name']);
1715 * Test civicrm_contact_get() return only first name & last name.
1717 * Use comma separated string return with a space.
1719 public function testContactGetReturnFirstLast() {
1720 $contact = $this->callAPISuccess('contact', 'create', $this->_params
);
1722 'contact_id' => $contact['id'],
1723 'return' => 'first_name, last_name',
1725 $result = $this->callAPISuccess('contact', 'getsingle', $params);
1726 $this->assertEquals('abc1', $result['first_name']);
1727 $this->assertEquals('xyz1', $result['last_name']);
1728 //check that other defaults not returns
1729 $this->assertArrayNotHasKey('sort_name', $result);
1731 'contact_id' => $contact['id'],
1732 'return' => 'first_name,last_name',
1734 $result = $this->callAPISuccess('contact', 'getsingle', $params);
1735 $this->assertEquals('abc1', $result['first_name']);
1736 $this->assertEquals('xyz1', $result['last_name']);
1737 //check that other defaults not returns
1738 $this->assertArrayNotHasKey('sort_name', $result);
1742 * Test civicrm_contact_get() return only first name & last name.
1744 * Use comma separated string return without a space
1746 public function testContactGetReturnFirstLastNoComma() {
1747 $contact = $this->callAPISuccess('contact', 'create', $this->_params
);
1749 'contact_id' => $contact['id'],
1750 'return' => 'first_name,last_name',
1752 $result = $this->callAPISuccess('contact', 'getsingle', $params);
1753 $this->assertEquals('abc1', $result['first_name']);
1754 $this->assertEquals('xyz1', $result['last_name']);
1755 //check that other defaults not returns
1756 $this->assertArrayNotHasKey('sort_name', $result);
1760 * Test civicrm_contact_get() with default return properties.
1762 public function testContactGetRetDefault() {
1763 $contactID = $this->individualCreate();
1765 'contact_id' => $contactID,
1766 'sort' => 'first_name',
1768 $result = $this->callAPISuccess('contact', 'get', $params);
1769 $this->assertEquals($contactID, $result['values'][$contactID]['contact_id']);
1770 $this->assertEquals('Anthony', $result['values'][$contactID]['first_name']);
1774 * Test civicrm_contact_getquick() with empty name param.
1776 public function testContactGetQuick() {
1777 // Insert a row in civicrm_contact creating individual contact.
1778 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1779 $op->execute($this->_dbconn
,
1780 $this->createXMLDataSet(
1781 dirname(__FILE__
) . '/dataset/contact_17.xml'
1784 $op->execute($this->_dbconn
,
1785 $this->createXMLDataSet(
1786 dirname(__FILE__
) . '/dataset/email_contact_17.xml'
1793 $result = $this->callAPISuccess('contact', 'getquick', $params);
1794 $this->assertEquals(17, $result['values'][0]['id']);
1796 'name' => "TestContact@example.com",
1797 'field_name' => 'sort_name',
1799 $result = $this->callAPISuccess('contact', 'getquick', $params);
1800 $this->assertEquals(17, $result['values'][0]['id']);
1804 * Test civicrm_contact_get) with empty params.
1806 public function testContactGetEmptyParams() {
1807 $this->callAPISuccess('contact', 'get', array());
1811 * Test civicrm_contact_get(,true) with no matches.
1813 public function testContactGetOldParamsNoMatches() {
1814 // Insert a row in civicrm_contact creating contact 17.
1815 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1816 $op->execute($this->_dbconn
,
1817 $this->createXMLDataSet(
1818 dirname(__FILE__
) . '/dataset/contact_17.xml'
1823 'first_name' => 'Fred',
1825 $result = $this->callAPISuccess('contact', 'get', $params);
1826 $this->assertEquals(0, $result['count']);
1830 * Test civicrm_contact_get(,true) with one match.
1832 public function testContactGetOldParamsOneMatch() {
1833 // Insert a row in civicrm_contact creating contact 17
1834 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1835 $op->execute($this->_dbconn
,
1836 $this->createXMLDataSet(dirname(__FILE__
) . '/dataset/contact_17.xml'
1841 'first_name' => 'Test',
1843 $result = $this->callAPISuccess('contact', 'get', $params);
1844 $this->assertEquals(17, $result['values'][17]['contact_id']);
1845 $this->assertEquals(17, $result['id']);
1849 * Test civicrm_contact_search_count().
1851 public function testContactGetEmail() {
1853 'email' => 'man2@yahoo.com',
1854 'contact_type' => 'Individual',
1855 'location_type_id' => 1,
1858 $contact = $this->callAPISuccess('contact', 'create', $params);
1861 'email' => 'man2@yahoo.com',
1863 $result = $this->callAPIAndDocument('contact', 'get', $params, __FUNCTION__
, __FILE__
);
1864 $this->assertEquals('man2@yahoo.com', $result['values'][$result['id']]['email']);
1866 $this->callAPISuccess('contact', 'delete', $contact);
1870 * Ensure consistent return format for option group fields.
1872 public function testSetPreferredCommunicationNull() {
1873 $contact = $this->callAPISuccess('contact', 'create', array_merge($this->_params
, array(
1874 'preferred_communication_method' => array('Phone', 'SMS'),
1876 $preferredCommunicationMethod = $this->callAPISuccessGetValue('Contact', array(
1877 'id' => $contact['id'],
1878 'return' => 'preferred_communication_method',
1880 $this->assertNotEmpty($preferredCommunicationMethod);
1881 $contact = $this->callAPISuccess('contact', 'create', array_merge($this->_params
, array(
1882 'preferred_communication_method' => 'null',
1883 'id' => $contact['id'],
1885 $preferredCommunicationMethod = $this->callAPISuccessGetValue('Contact', array(
1886 'id' => $contact['id'],
1887 'return' => 'preferred_communication_method',
1889 $this->assertEmpty($preferredCommunicationMethod);
1893 * Ensure consistent return format for option group fields.
1895 public function testPseudoFields() {
1897 'preferred_communication_method' => array('Phone', 'SMS'),
1898 'preferred_language' => 'en_US',
1899 'gender_id' => 'Female',
1900 'prefix_id' => 'Mrs.',
1901 'suffix_id' => 'II',
1902 'communication_style_id' => 'Formal',
1905 $contact = $this->callAPISuccess('contact', 'create', array_merge($this->_params
, $params));
1907 $result = $this->callAPISuccess('contact', 'getsingle', array('id' => $contact['id']));
1908 $this->assertEquals('Both', $result['preferred_mail_format']);
1910 $this->assertEquals('en_US', $result['preferred_language']);
1911 $this->assertEquals(1, $result['communication_style_id']);
1912 $this->assertEquals(1, $result['gender_id']);
1913 $this->assertEquals('Female', $result['gender']);
1914 $this->assertEquals('Mrs.', $result['individual_prefix']);
1915 $this->assertEquals(1, $result['prefix_id']);
1916 $this->assertEquals('II', $result['individual_suffix']);
1917 $this->assertEquals(CRM_Core_PseudoConstant
::getKey("CRM_Contact_BAO_Contact", 'suffix_id', 'II'), $result['suffix_id']);
1918 $this->callAPISuccess('contact', 'delete', $contact);
1919 $this->assertEquals(array(
1920 CRM_Core_PseudoConstant
::getKey("CRM_Contact_BAO_Contact", 'preferred_communication_method', 'Phone'),
1921 CRM_Core_PseudoConstant
::getKey("CRM_Contact_BAO_Contact", 'preferred_communication_method', 'SMS'),
1922 ), $result['preferred_communication_method']);
1927 * Test birth date parameters.
1929 * These include value, array & birth_date_high, birth_date_low
1932 public function testContactGetBirthDate() {
1933 $contact1 = $this->callAPISuccess('contact', 'create', array_merge($this->_params
, array('birth_date' => 'first day of next month - 2 years')));
1934 $contact2 = $this->callAPISuccess('contact', 'create', array_merge($this->_params
, array('birth_date' => 'first day of next month - 5 years')));
1935 $contact3 = $this->callAPISuccess('contact', 'create', array_merge($this->_params
, array('birth_date' => 'first day of next month -20 years')));
1937 $result = $this->callAPISuccess('contact', 'get', array());
1938 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -2 years')), $result['values'][$contact1['id']]['birth_date']);
1939 $result = $this->callAPISuccess('contact', 'get', array('birth_date' => 'first day of next month -5 years'));
1940 $this->assertEquals(1, $result['count']);
1941 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -5 years')), $result['values'][$contact2['id']]['birth_date']);
1942 $result = $this->callAPISuccess('contact', 'get', array('birth_date_high' => date('Y-m-d', strtotime('-6 years'))));
1943 $this->assertEquals(1, $result['count']);
1944 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -20 years')), $result['values'][$contact3['id']]['birth_date']);
1945 $result = $this->callAPISuccess('contact', 'get', array(
1946 'birth_date_low' => date('Y-m-d', strtotime('-6 years')),
1947 'birth_date_high' => date('Y-m-d', strtotime('- 3 years')),
1949 $this->assertEquals(1, $result['count']);
1950 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -5 years')), $result['values'][$contact2['id']]['birth_date']);
1951 $result = $this->callAPISuccess('contact', 'get', array(
1952 'birth_date_low' => '-6 years',
1953 'birth_date_high' => '- 3 years',
1955 $this->assertEquals(1, $result['count']);
1956 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -5 years')), $result['values'][$contact2['id']]['birth_date']);
1960 * Test Address parameters
1962 * This include state_province, state_province_name, country
1964 public function testContactGetWithAddressFields() {
1965 $individuals = array(
1967 'first_name' => 'abc1',
1968 'contact_type' => 'Individual',
1969 'last_name' => 'xyz1',
1970 'api.address.create' => array(
1971 'country' => 'United States',
1972 'state_province_id' => 'Michigan',
1973 'location_type_id' => 1,
1977 'first_name' => 'abc2',
1978 'contact_type' => 'Individual',
1979 'last_name' => 'xyz2',
1980 'api.address.create' => array(
1981 'country' => 'United States',
1982 'state_province_id' => 'Alabama',
1983 'location_type_id' => 1,
1987 foreach ($individuals as $params) {
1988 $contact = $this->callAPISuccess('contact', 'create', $params);
1991 // Check whether Contact get API return successfully with below Address params.
1992 $fieldsToTest = array(
1993 'state_province_name' => 'Michigan',
1994 'state_province' => 'Michigan',
1995 'country' => 'United States',
1996 'state_province_name' => array('IN' => array('Michigan', 'Alabama')),
1997 'state_province' => array('IN' => array('Michigan', 'Alabama')),
1999 foreach ($fieldsToTest as $field => $value) {
2001 'id' => $contact['id'],
2004 $result = $this->callAPISuccess('Contact', 'get', $getParams);
2005 $this->assertEquals(1, $result['count']);
2010 * Test Deceased date parameters.
2012 * These include value, array & Deceased_date_high, Deceased date_low
2015 public function testContactGetDeceasedDate() {
2016 $contact1 = $this->callAPISuccess('contact', 'create', array_merge($this->_params
, array('deceased_date' => 'first day of next month - 2 years')));
2017 $contact2 = $this->callAPISuccess('contact', 'create', array_merge($this->_params
, array('deceased_date' => 'first day of next month - 5 years')));
2018 $contact3 = $this->callAPISuccess('contact', 'create', array_merge($this->_params
, array('deceased_date' => 'first day of next month -20 years')));
2020 $result = $this->callAPISuccess('contact', 'get', array());
2021 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -2 years')), $result['values'][$contact1['id']]['deceased_date']);
2022 $result = $this->callAPISuccess('contact', 'get', array('deceased_date' => 'first day of next month -5 years'));
2023 $this->assertEquals(1, $result['count']);
2024 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -5 years')), $result['values'][$contact2['id']]['deceased_date']);
2025 $result = $this->callAPISuccess('contact', 'get', array('deceased_date_high' => date('Y-m-d', strtotime('-6 years'))));
2026 $this->assertEquals(1, $result['count']);
2027 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -20 years')), $result['values'][$contact3['id']]['deceased_date']);
2028 $result = $this->callAPISuccess('contact', 'get', array(
2029 'deceased_date_low' => '-6 years',
2030 'deceased_date_high' => date('Y-m-d', strtotime('- 3 years')),
2032 $this->assertEquals(1, $result['count']);
2033 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -5 years')), $result['values'][$contact2['id']]['deceased_date']);
2037 * Test for Contact.get id=@user:username.
2039 public function testContactGetByUsername() {
2040 // Setup - create contact with a uf-match.
2041 $cid = $this->individualCreate(array(
2042 'contact_type' => 'Individual',
2043 'first_name' => 'testGetByUsername',
2044 'last_name' => 'testGetByUsername',
2047 $ufMatchParams = array(
2048 'domain_id' => CRM_Core_Config
::domainID(),
2050 'uf_name' => 'the-email-matching-key-is-not-really-the-username',
2051 'contact_id' => $cid,
2053 $ufMatch = CRM_Core_BAO_UFMatch
::create($ufMatchParams);
2054 $this->assertTrue(is_numeric($ufMatch->id
));
2056 // setup - mock the calls to CRM_Utils_System_*::getUfId
2057 $mockFunction = $this->mockMethod
;
2058 $userSystem = $this->$mockFunction('CRM_Utils_System_UnitTests', array('getUfId'));
2059 $userSystem->expects($this->once())
2061 ->with($this->equalTo('exampleUser'))
2062 ->will($this->returnValue(99));
2063 CRM_Core_Config
::singleton()->userSystem
= $userSystem;
2066 $result = $this->callAPISuccess('Contact', 'get', array(
2067 'id' => '@user:exampleUser',
2069 $this->assertEquals('testGetByUsername', $result['values'][$cid]['first_name']);
2071 // Check search of contacts with & without uf records
2072 $result = $this->callAPISuccess('Contact', 'get', ['uf_user' => 1]);
2073 $this->assertArrayHasKey($cid, $result['values']);
2075 $result = $this->callAPISuccess('Contact', 'get', ['uf_user' => 0]);
2076 $this->assertArrayNotHasKey($cid, $result['values']);
2080 * Test to check return works OK.
2082 public function testContactGetReturnValues() {
2083 $extraParams = array(
2084 'nick_name' => 'Bob',
2086 'email' => 'e@mail.com',
2088 $contactID = $this->individualCreate($extraParams);
2089 //actually it turns out the above doesn't create a phone
2090 $this->callAPISuccess('phone', 'create', array('contact_id' => $contactID, 'phone' => '456'));
2091 $result = $this->callAPISuccess('contact', 'getsingle', array('id' => $contactID));
2092 foreach ($extraParams as $key => $value) {
2093 $this->assertEquals($result[$key], $value);
2095 //now we check they are still returned with 'return' key
2096 $result = $this->callAPISuccess('contact', 'getsingle', array(
2098 'return' => array_keys($extraParams),
2100 foreach ($extraParams as $key => $value) {
2101 $this->assertEquals($result[$key], $value);
2106 * Test creating multiple phones using chaining.
2108 * @throws \Exception
2110 public function testCRM13252MultipleChainedPhones() {
2111 $contactID = $this->householdCreate();
2112 $this->callAPISuccessGetCount('phone', array('contact_id' => $contactID), 0);
2114 'contact_id' => $contactID,
2115 'household_name' => 'Household 1',
2116 'contact_type' => 'Household',
2117 'api.phone.create' => array(
2119 'phone' => '111-111-1111',
2120 'location_type_id' => 1,
2121 'phone_type_id' => 1,
2124 'phone' => '222-222-2222',
2125 'location_type_id' => 1,
2126 'phone_type_id' => 2,
2130 $this->callAPISuccess('contact', 'create', $params);
2131 $this->callAPISuccessGetCount('phone', array('contact_id' => $contactID), 2);
2136 * Test for Contact.get id=@user:username (with an invalid username).
2138 public function testContactGetByUnknownUsername() {
2139 // setup - mock the calls to CRM_Utils_System_*::getUfId
2140 $mockFunction = $this->mockMethod
;
2141 $userSystem = $this->$mockFunction('CRM_Utils_System_UnitTests', array('getUfId'));
2142 $userSystem->expects($this->once())
2144 ->with($this->equalTo('exampleUser'))
2145 ->will($this->returnValue(NULL));
2146 CRM_Core_Config
::singleton()->userSystem
= $userSystem;
2149 $result = $this->callAPIFailure('Contact', 'get', array(
2150 'id' => '@user:exampleUser',
2152 $this->assertRegExp('/cannot be resolved to a contact ID/', $result['error_message']);
2156 * Verify attempt to create individual with chained arrays and sequential.
2158 public function testGetIndividualWithChainedArraysAndSequential() {
2159 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__
, __FILE__
);
2160 $params['custom_' . $ids['custom_field_id']] = "custom string";
2162 $moreIDs = $this->CustomGroupMultipleCreateWithFields();
2165 'first_name' => 'abc3',
2166 'last_name' => 'xyz3',
2167 'contact_type' => 'Individual',
2168 'email' => 'man3@yahoo.com',
2169 'api.website.create' => array(
2171 'url' => "http://civicrm.org",
2174 'url' => "https://civicrm.org",
2179 $result = $this->callAPISuccess('Contact', 'create', $params);
2181 // delete the contact and custom groups
2182 $this->callAPISuccess('contact', 'delete', array('id' => $result['id']));
2183 $this->customGroupDelete($ids['custom_group_id']);
2184 $this->customGroupDelete($moreIDs['custom_group_id']);
2186 $this->assertEquals($result['id'], $result['values'][0]['id']);
2187 $this->assertArrayKeyExists('api.website.create', $result['values'][0]);
2191 * Verify attempt to create individual with chained arrays.
2193 public function testGetIndividualWithChainedArrays() {
2194 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__
, __FILE__
);
2195 $params['custom_' . $ids['custom_field_id']] = "custom string";
2197 $moreIDs = $this->CustomGroupMultipleCreateWithFields();
2198 $description = "This demonstrates the usage of chained api functions.\nIn this case no notes or custom fields have been created.";
2199 $subfile = "APIChainedArray";
2201 'first_name' => 'abc3',
2202 'last_name' => 'xyz3',
2203 'contact_type' => 'Individual',
2204 'email' => 'man3@yahoo.com',
2205 'api.contribution.create' => array(
2206 'receive_date' => '2010-01-01',
2207 'total_amount' => 100.00,
2208 'financial_type_id' => 1,
2209 'payment_instrument_id' => 1,
2210 'non_deductible_amount' => 10.00,
2211 'fee_amount' => 50.00,
2212 'net_amount' => 90.00,
2214 'invoice_id' => 67890,
2216 'contribution_status_id' => 1,
2218 'api.contribution.create.1' => array(
2219 'receive_date' => '2011-01-01',
2220 'total_amount' => 120.00,
2221 'financial_type_id' => $this->_financialTypeId
= 1,
2222 'payment_instrument_id' => 1,
2223 'non_deductible_amount' => 10.00,
2224 'fee_amount' => 50.00,
2225 'net_amount' => 90.00,
2227 'invoice_id' => 67830,
2229 'contribution_status_id' => 1,
2231 'api.website.create' => array(
2233 'url' => "http://civicrm.org",
2238 $result = $this->callAPISuccess('Contact', 'create', $params);
2240 'id' => $result['id'],
2241 'api.website.get' => array(),
2242 'api.Contribution.get' => array(
2243 'total_amount' => '120.00',
2245 'api.CustomValue.get' => 1,
2246 'api.Note.get' => 1,
2248 $result = $this->callAPIAndDocument('Contact', 'Get', $params, __FUNCTION__
, __FILE__
, $description, $subfile);
2249 // delete the contact
2250 $this->callAPISuccess('contact', 'delete', $result);
2251 $this->customGroupDelete($ids['custom_group_id']);
2252 $this->customGroupDelete($moreIDs['custom_group_id']);
2253 $this->assertEquals(0, $result['values'][$result['id']]['api.website.get']['is_error']);
2254 $this->assertEquals("http://civicrm.org", $result['values'][$result['id']]['api.website.get']['values'][0]['url']);
2258 * Verify attempt to create individual with chained arrays and sequential.
2260 * See https://issues.civicrm.org/jira/browse/CRM-15815
2262 public function testCreateIndividualWithChainedArrayAndSequential() {
2265 'first_name' => 'abc5',
2266 'last_name' => 'xyz5',
2267 'contact_type' => 'Individual',
2268 'email' => 'woman5@yahoo.com',
2269 'api.phone.create' => array(
2270 array('phone' => '03-231 07 95'),
2271 array('phone' => '03-232 51 62'),
2273 'api.website.create' => array(
2274 'url' => 'http://civicrm.org',
2277 $result = $this->callAPISuccess('Contact', 'create', $params);
2279 // I could try to parse the result to see whether the two phone numbers
2280 // and the website are there, but I am not sure about the correct format.
2281 // So I will just fetch it again before checking.
2282 // See also http://forum.civicrm.org/index.php/topic,35393.0.html
2285 'id' => $result['id'],
2286 'api.website.get' => array(),
2287 'api.phone.get' => array(),
2289 $result = $this->callAPISuccess('Contact', 'get', $params);
2291 // delete the contact
2292 $this->callAPISuccess('contact', 'delete', $result);
2294 $this->assertEquals(2, $result['values'][0]['api.phone.get']['count']);
2295 $this->assertEquals(1, $result['values'][0]['api.website.get']['count']);
2299 * Test retrieving an individual with chained array syntax.
2301 public function testGetIndividualWithChainedArraysFormats() {
2302 $description = "This demonstrates the usage of chained api functions.\nIn this case no notes or custom fields have been created.";
2303 $subfile = "APIChainedArrayFormats";
2304 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__
, __FILE__
);
2305 $params['custom_' . $ids['custom_field_id']] = "custom string";
2307 $moreIDs = $this->CustomGroupMultipleCreateWithFields();
2309 'first_name' => 'abc3',
2310 'last_name' => 'xyz3',
2311 'contact_type' => 'Individual',
2312 'email' => 'man3@yahoo.com',
2313 'api.contribution.create' => array(
2314 'receive_date' => '2010-01-01',
2315 'total_amount' => 100.00,
2316 'financial_type_id' => $this->_financialTypeId
,
2317 'payment_instrument_id' => 1,
2318 'non_deductible_amount' => 10.00,
2319 'fee_amount' => 50.00,
2320 'net_amount' => 90.00,
2322 'contribution_status_id' => 1,
2323 'skipCleanMoney' => 1,
2325 'api.contribution.create.1' => array(
2326 'receive_date' => '2011-01-01',
2327 'total_amount' => 120.00,
2328 'financial_type_id' => $this->_financialTypeId
,
2329 'payment_instrument_id' => 1,
2330 'non_deductible_amount' => 10.00,
2331 'fee_amount' => 50.00,
2332 'net_amount' => 90.00,
2334 'contribution_status_id' => 1,
2335 'skipCleanMoney' => 1,
2337 'api.website.create' => array(
2339 'url' => "http://civicrm.org",
2344 $result = $this->callAPISuccess('Contact', 'create', $params);
2346 'id' => $result['id'],
2347 'api.website.getValue' => array('return' => 'url'),
2348 'api.Contribution.getCount' => array(),
2349 'api.CustomValue.get' => 1,
2350 'api.Note.get' => 1,
2351 'api.Membership.getCount' => array(),
2353 $result = $this->callAPIAndDocument('Contact', 'Get', $params, __FUNCTION__
, __FILE__
, $description, $subfile);
2354 $this->assertEquals(2, $result['values'][$result['id']]['api.Contribution.getCount']);
2355 $this->assertEquals(0, $result['values'][$result['id']]['api.Note.get']['is_error']);
2356 $this->assertEquals("http://civicrm.org", $result['values'][$result['id']]['api.website.getValue']);
2358 $this->callAPISuccess('contact', 'delete', $result);
2359 $this->customGroupDelete($ids['custom_group_id']);
2360 $this->customGroupDelete($moreIDs['custom_group_id']);
2364 * Test complex chaining.
2366 public function testGetIndividualWithChainedArraysAndMultipleCustom() {
2367 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__
, __FILE__
);
2368 $params['custom_' . $ids['custom_field_id']] = "custom string";
2369 $moreIDs = $this->CustomGroupMultipleCreateWithFields();
2370 $andMoreIDs = $this->CustomGroupMultipleCreateWithFields(array(
2371 'title' => "another group",
2372 'name' => 'another name',
2374 $description = "This demonstrates the usage of chained api functions with multiple custom fields.";
2375 $subfile = "APIChainedArrayMultipleCustom";
2377 'first_name' => 'abc3',
2378 'last_name' => 'xyz3',
2379 'contact_type' => 'Individual',
2380 'email' => 'man3@yahoo.com',
2381 'api.contribution.create' => array(
2382 'receive_date' => '2010-01-01',
2383 'total_amount' => 100.00,
2384 'financial_type_id' => 1,
2385 'payment_instrument_id' => 1,
2386 'non_deductible_amount' => 10.00,
2387 'fee_amount' => 50.00,
2388 'net_amount' => 90.00,
2390 'invoice_id' => 67890,
2392 'contribution_status_id' => 1,
2393 'skipCleanMoney' => 1,
2395 'api.contribution.create.1' => array(
2396 'receive_date' => '2011-01-01',
2397 'total_amount' => 120.00,
2398 'financial_type_id' => 1,
2399 'payment_instrument_id' => 1,
2400 'non_deductible_amount' => 10.00,
2401 'fee_amount' => 50.00,
2402 'net_amount' => 90.00,
2404 'invoice_id' => 67830,
2406 'contribution_status_id' => 1,
2407 'skipCleanMoney' => 1,
2409 'api.website.create' => array(
2411 'url' => "http://civicrm.org",
2414 'custom_' . $ids['custom_field_id'] => "value 1",
2415 'custom_' . $moreIDs['custom_field_id'][0] => "value 2",
2416 'custom_' . $moreIDs['custom_field_id'][1] => "warm beer",
2417 'custom_' . $andMoreIDs['custom_field_id'][1] => "vegemite",
2420 $result = $this->callAPISuccess('Contact', 'create', $params);
2421 $result = $this->callAPISuccess('Contact', 'create', array(
2422 'contact_type' => 'Individual',
2423 'id' => $result['id'],
2425 $moreIDs['custom_field_id'][0] => "value 3",
2427 $ids['custom_field_id'] => "value 4",
2431 'id' => $result['id'],
2432 'api.website.getValue' => array('return' => 'url'),
2433 'api.Contribution.getCount' => array(),
2434 'api.CustomValue.get' => 1,
2436 $result = $this->callAPIAndDocument('Contact', 'Get', $params, __FUNCTION__
, __FILE__
, $description, $subfile);
2438 $this->customGroupDelete($ids['custom_group_id']);
2439 $this->customGroupDelete($moreIDs['custom_group_id']);
2440 $this->customGroupDelete($andMoreIDs['custom_group_id']);
2441 $this->assertEquals(0, $result['values'][$result['id']]['api.CustomValue.get']['is_error']);
2442 $this->assertEquals('http://civicrm.org', $result['values'][$result['id']]['api.website.getValue']);
2446 * Test checks usage of $values to pick & choose inputs.
2448 public function testChainingValuesCreate() {
2449 $description = "This demonstrates the usage of chained api functions. Specifically it has one 'parent function' &
2450 2 child functions - one receives values from the parent (Contact) and the other child (Tag).";
2451 $subfile = "APIChainedArrayValuesFromSiblingFunction";
2453 'display_name' => 'batman',
2454 'contact_type' => 'Individual',
2455 'api.tag.create' => array(
2456 'name' => '$value.id',
2457 'description' => '$value.display_name',
2458 'format.only_id' => 1,
2460 'api.entity_tag.create' => array('tag_id' => '$value.api.tag.create'),
2462 $result = $this->callAPIAndDocument('Contact', 'Create', $params, __FUNCTION__
, __FILE__
, $description, $subfile);
2463 $this->assertEquals(0, $result['values'][$result['id']]['api.entity_tag.create']['is_error']);
2465 $tablesToTruncate = array(
2468 'civicrm_entity_tag',
2471 $this->quickCleanup($tablesToTruncate, TRUE);
2475 * Test TrueFalse format - I couldn't come up with an easy way to get an error on Get.
2477 public function testContactGetFormatIsSuccessTrue() {
2478 $this->createContactFromXML();
2479 $description = "This demonstrates use of the 'format.is_success' param.
2480 This param causes only the success or otherwise of the function to be returned as BOOLEAN";
2481 $subfile = "FormatIsSuccess_True";
2482 $params = array('id' => 17, 'format.is_success' => 1);
2483 $result = $this->callAPIAndDocument('Contact', 'Get', $params, __FUNCTION__
, __FILE__
, $description, $subfile);
2484 $this->assertEquals(1, $result);
2485 $this->callAPISuccess('Contact', 'Delete', $params);
2489 * Test TrueFalse format.
2491 public function testContactCreateFormatIsSuccessFalse() {
2493 $description = "This demonstrates use of the 'format.is_success' param.
2494 This param causes only the success or otherwise of the function to be returned as BOOLEAN";
2495 $subfile = "FormatIsSuccess_Fail";
2496 $params = array('id' => 500, 'format.is_success' => 1);
2497 $result = $this->callAPIAndDocument('Contact', 'Create', $params, __FUNCTION__
, __FILE__
, $description, $subfile);
2498 $this->assertEquals(0, $result);
2502 * Test long display names.
2506 public function testContactCreateLongDisplayName() {
2507 $result = $this->callAPISuccess('Contact', 'Create', array(
2508 'first_name' => str_pad('a', 64, 'a'),
2509 'last_name' => str_pad('a', 64, 'a'),
2510 'contact_type' => 'Individual',
2512 $this->assertEquals('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', $result['values'][$result['id']]['display_name']);
2513 $this->assertEquals('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', $result['values'][$result['id']]['sort_name']);
2517 * Test Single Entity format.
2519 public function testContactGetSingleEntityArray() {
2520 $this->createContactFromXML();
2521 $description = "This demonstrates use of the 'format.single_entity_array' param.
2522 This param causes the only contact to be returned as an array without the other levels.
2523 It will be ignored if there is not exactly 1 result";
2524 $subfile = "GetSingleContact";
2525 $params = array('id' => 17);
2526 $result = $this->callAPIAndDocument('Contact', 'GetSingle', $params, __FUNCTION__
, __FILE__
, $description, $subfile);
2527 $this->assertEquals('Test Contact', $result['display_name']);
2528 $this->callAPISuccess('Contact', 'Delete', $params);
2532 * Test Single Entity format.
2534 public function testContactGetFormatCountOnly() {
2535 $this->createContactFromXML();
2536 $description = "This demonstrates use of the 'getCount' action.
2537 This param causes the count of the only function to be returned as an integer.";
2538 $params = array('id' => 17);
2539 $result = $this->callAPIAndDocument('Contact', 'GetCount', $params, __FUNCTION__
, __FILE__
, $description,
2541 $this->assertEquals('1', $result);
2542 $this->callAPISuccess('Contact', 'Delete', $params);
2546 * Test id only format.
2548 public function testContactGetFormatIDOnly() {
2549 $this->createContactFromXML();
2550 $description = "This demonstrates use of the 'format.id_only' param.
2551 This param causes the id of the only entity to be returned as an integer.
2552 It will be ignored if there is not exactly 1 result";
2553 $subfile = "FormatOnlyID";
2554 $params = array('id' => 17, 'format.only_id' => 1);
2555 $result = $this->callAPIAndDocument('Contact', 'Get', $params, __FUNCTION__
, __FILE__
, $description, $subfile);
2556 $this->assertEquals('17', $result);
2557 $this->callAPISuccess('Contact', 'Delete', $params);
2561 * Test id only format.
2563 public function testContactGetFormatSingleValue() {
2564 $this->createContactFromXML();
2565 $description = "This demonstrates use of the 'format.single_value' param.
2566 This param causes only a single value of the only entity to be returned as an string.
2567 It will be ignored if there is not exactly 1 result";
2568 $subFile = "FormatSingleValue";
2569 $params = array('id' => 17, 'return' => 'display_name');
2570 $result = $this->callAPIAndDocument('Contact', 'getvalue', $params, __FUNCTION__
, __FILE__
, $description, $subFile);
2571 $this->assertEquals('Test Contact', $result);
2572 $this->callAPISuccess('Contact', 'Delete', $params);
2576 * Test that permissions are respected when creating contacts.
2578 public function testContactCreationPermissions() {
2580 'contact_type' => 'Individual',
2581 'first_name' => 'Foo',
2582 'last_name' => 'Bear',
2583 'check_permissions' => TRUE,
2585 $config = CRM_Core_Config
::singleton();
2586 $config->userPermissionClass
->permissions
= array('access CiviCRM');
2587 $result = $this->callAPIFailure('contact', 'create', $params);
2588 $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');
2590 $config->userPermissionClass
->permissions
= array('access CiviCRM', 'add contacts', 'import contacts');
2591 $this->callAPISuccess('contact', 'create', $params);
2595 * Test that delete with skip undelete respects permissions.
2597 public function testContactDeletePermissions() {
2598 $contactID = $this->individualCreate();
2599 CRM_Core_Config
::singleton()->userPermissionClass
->permissions
= array('access CiviCRM');
2600 $this->callAPIFailure('Contact', 'delete', array(
2602 'check_permissions' => 1,
2603 'skip_undelete' => 1,
2605 $this->callAPISuccess('Contact', 'delete', array(
2607 'check_permissions' => 0,
2608 'skip_undelete' => 1,
2613 * Test update with check permissions set.
2615 public function testContactUpdatePermissions() {
2617 'contact_type' => 'Individual',
2618 'first_name' => 'Foo',
2619 'last_name' => 'Bear',
2620 'check_permissions' => TRUE,
2622 $result = $this->callAPISuccess('contact', 'create', $params);
2623 $config = CRM_Core_Config
::singleton();
2625 'id' => $result['id'],
2626 'contact_type' => 'Individual',
2627 'last_name' => 'Bar',
2628 'check_permissions' => TRUE,
2631 $config->userPermissionClass
->permissions
= array('access CiviCRM');
2632 $result = $this->callAPIFailure('contact', 'update', $params);
2633 $this->assertEquals('Permission denied to modify contact record', $result['error_message']);
2635 $config->userPermissionClass
->permissions
= array(
2638 'view all contacts',
2639 'edit all contacts',
2642 $this->callAPISuccess('contact', 'update', $params);
2646 * Set up helper to create a contact.
2648 public function createContactFromXML() {
2649 // Insert a row in civicrm_contact creating contact 17.
2650 $op = new PHPUnit_Extensions_Database_Operation_Insert();
2651 $op->execute($this->_dbconn
,
2652 $this->createXMLDataSet(
2653 dirname(__FILE__
) . '/dataset/contact_17.xml'
2659 * Test contact proximity api.
2661 public function testContactProximity() {
2662 // first create a contact with a SF location with a specific
2664 $contactID = $this->organizationCreate();
2666 // now create the address
2668 'street_address' => '123 Main Street',
2669 'city' => 'San Francisco',
2671 'country_id' => 1228,
2672 'state_province_id' => 1004,
2673 'geo_code_1' => '37.79',
2674 'geo_code_2' => '-122.40',
2675 'location_type_id' => 1,
2676 'contact_id' => $contactID,
2679 $result = $this->callAPISuccess('address', 'create', $params);
2680 $this->assertEquals(1, $result['count']);
2682 // now do a proximity search with a close enough geocode and hope to match
2683 // that specific contact only!
2684 $proxParams = array(
2686 'longitude' => -122.3,
2690 $result = $this->callAPISuccess('contact', 'proximity', $proxParams);
2691 $this->assertEquals(1, $result['count']);
2695 * Test that Ajax API permission is sufficient to access getquick api.
2697 * (note that getquick api is required for autocomplete & has ACL permissions applied)
2699 public function testGetquickPermissionCRM13744() {
2700 CRM_Core_Config
::singleton()->userPermissionClass
->permissions
= array('access CiviEvent');
2701 $this->callAPIFailure('contact', 'getquick', array('name' => 'b', 'check_permissions' => TRUE));
2702 CRM_Core_Config
::singleton()->userPermissionClass
->permissions
= array('access CiviCRM');
2703 $this->callAPISuccess('contact', 'getquick', array('name' => 'b', 'check_permissions' => TRUE));
2704 CRM_Core_Config
::singleton()->userPermissionClass
->permissions
= array('access AJAX API');
2705 $this->callAPISuccess('contact', 'getquick', array('name' => 'b', 'check_permissions' => TRUE));
2709 * Test that getquick returns contacts with an exact first name match first.
2711 * The search string 'b' & 'bob' both return ordered by sort_name if includeOrderByClause
2712 * is true (default) but if it is false then matches are returned in ID order.
2714 * @dataProvider getSearchSortOptions
2716 public function testGetQuickExactFirst($searchParameters, $settings, $firstContact, $secondContact = NULL) {
2717 $this->getQuickSearchSampleData();
2718 $this->callAPISuccess('Setting', 'create', $settings);
2719 $result = $this->callAPISuccess('contact', 'getquick', $searchParameters);
2720 $this->assertEquals($firstContact, $result['values'][0]['sort_name']);
2721 $this->assertEquals($secondContact, $result['values'][1]['sort_name']);
2722 $this->callAPISuccess('Setting', 'create', array('includeWildCardInName' => TRUE, 'includeOrderByClause' => TRUE));
2725 public function getSearchSortOptions() {
2726 $firstAlphabeticalContactBySortName = 'A Bobby, Bobby';
2727 $secondAlphabeticalContactBySortName = 'Aadvark, Bob';
2728 $secondAlphabeticalContactWithEmailBySortName = 'Bob, Bob';
2729 $firstAlphabeticalContactFirstNameBob = 'Aadvark, Bob';
2730 $secondAlphabeticalContactFirstNameBob = 'Bob, Bob';
2731 $firstByIDContactFirstNameBob = 'Bob, Bob';
2732 $secondByIDContactFirstNameBob = 'K Bobby, Bob';
2733 $firstContactByID = 'Bob, Bob';
2734 $secondContactByID = 'E Bobby, Bobby';
2735 $bobLikeEmail = 'A Bobby, Bobby';
2738 'empty_search_basic' => array(
2739 'search_parameters' => array('name' => '%'),
2740 'settings' => array('includeWildCardInName' => TRUE, 'includeOrderByClause' => TRUE),
2741 'first_contact' => $firstAlphabeticalContactBySortName,
2742 'second_contact' => $secondAlphabeticalContactBySortName,
2744 'empty_search_basic_no_wildcard' => array(
2745 'search_parameters' => array('name' => '%'),
2746 'settings' => array('includeWildCardInName' => FALSE, 'includeOrderByClause' => TRUE),
2747 'first_contact' => $firstAlphabeticalContactBySortName,
2748 'second_contact' => $secondAlphabeticalContactBySortName,
2750 'single_letter_search_basic' => array(
2751 'search_parameters' => array('name' => 'b'),
2752 'settings' => array('includeWildCardInName' => TRUE, 'includeOrderByClause' => TRUE),
2753 'first_contact' => $firstAlphabeticalContactBySortName,
2754 'second_contact' => $secondAlphabeticalContactBySortName,
2756 'bob_search_basic' => array(
2757 'search_parameters' => array('name' => 'bob'),
2758 'settings' => array('includeWildCardInName' => TRUE, 'includeOrderByClause' => TRUE),
2759 'first_contact' => $firstAlphabeticalContactBySortName,
2760 'second_contact' => $secondAlphabeticalContactBySortName,
2762 // This test has been disabled as is proving to be problematic to reproduce due to MySQL sorting issues between different versions
2763 // 'bob_search_no_orderby' => array(
2764 // 'search_parameters' => array('name' => 'bob'),
2765 // 'settings' => array('includeWildCardInName' => TRUE, 'includeOrderByClause' => FALSE),
2766 // 'first_contact' => $firstContactByID,
2767 // 'second_contact' => $secondContactByID,
2769 'bob_search_no_wildcard' => array(
2770 'search_parameters' => array('name' => 'bob'),
2771 'settings' => array('includeWildCardInName' => FALSE, 'includeOrderByClause' => TRUE),
2772 'second_contact' => $bobLikeEmail,
2773 'first_contact' => $secondAlphabeticalContactFirstNameBob,
2775 // This should be the same as just no wildcard as if we had an exactMatch while searching by
2776 // sort name it would rise to the top CRM-19547
2777 'bob_search_no_wildcard_no_orderby' => array(
2778 'search_parameters' => array('name' => 'bob'),
2779 'settings' => array('includeWildCardInName' => FALSE, 'includeOrderByClause' => TRUE),
2780 'second_contact' => $bobLikeEmail,
2781 'first_contact' => $secondAlphabeticalContactFirstNameBob,
2783 'first_name_search_basic' => array(
2784 'search_parameters' => array('name' => 'bob', 'field_name' => 'first_name'),
2785 'settings' => array('includeWildCardInName' => TRUE, 'includeOrderByClause' => TRUE),
2786 'first_contact' => $firstAlphabeticalContactFirstNameBob,
2787 'second_contact' => $secondAlphabeticalContactFirstNameBob,
2789 'first_name_search_no_wildcard' => array(
2790 'search_parameters' => array('name' => 'bob', 'field_name' => 'first_name'),
2791 'settings' => array('includeWildCardInName' => FALSE, 'includeOrderByClause' => TRUE),
2792 'first_contact' => $firstAlphabeticalContactFirstNameBob,
2793 'second_contact' => $secondAlphabeticalContactFirstNameBob,
2795 // This test has been disabled as is proving to be problematic to reproduce due to MySQL sorting issues between different versions
2796 //'first_name_search_no_orderby' => array(
2797 // 'search_parameters' => array('name' => 'bob', 'field_name' => 'first_name'),
2798 // 'settings' => array('includeWildCardInName' => TRUE, 'includeOrderByClause' => FALSE),
2799 // 'first_contact' => $firstByIDContactFirstNameBob,
2800 // 'second_contact' => $secondByIDContactFirstNameBob,
2802 'email_search_basic' => array(
2803 'search_parameters' => array('name' => 'bob', 'field_name' => 'email', 'table_name' => 'eml'),
2804 'settings' => array('includeWildCardInName' => FALSE, 'includeOrderByClause' => TRUE),
2805 'first_contact' => $firstAlphabeticalContactBySortName,
2806 'second_contact' => $secondAlphabeticalContactWithEmailBySortName,
2812 * Test that getquick returns contacts with an exact first name match first.
2814 public function testGetQuickEmail() {
2815 $this->getQuickSearchSampleData();
2816 $loggedInContactID = $this->createLoggedInUser();
2817 $result = $this->callAPISuccess('contact', 'getquick', array(
2820 $expectedData = array(
2821 'A Bobby, Bobby :: bob@bobby.com',
2822 'Bob, Bob :: bob@bob.com',
2824 'H Bobby, Bobby :: bob@h.com',
2826 $this->callAPISuccessGetValue('Contact', array('id' => $loggedInContactID, 'return' => 'last_name')) . ', Logged In :: anthony_anderson@civicrm.org',
2828 $this->assertEquals(6, $result['count']);
2829 foreach ($expectedData as $index => $value) {
2830 $this->assertEquals($value, $result['values'][$index]['data']);
2832 $result = $this->callAPISuccess('contact', 'getquick', array(
2835 $expectedData = array(
2836 'H Bobby, Bobby :: bob@h.com',
2838 foreach ($expectedData as $index => $value) {
2839 $this->assertEquals($value, $result['values'][$index]['data']);
2841 $this->callAPISuccess('Setting', 'create', array('includeWildCardInName' => FALSE));
2842 $result = $this->callAPISuccess('contact', 'getquick', array(
2845 $this->callAPISuccess('Setting', 'create', array('includeWildCardInName' => TRUE));
2846 $this->assertEquals(0, $result['count']);
2850 * Test that getquick returns contacts with an exact first name match first.
2852 public function testGetQuickEmailACL() {
2853 $this->getQuickSearchSampleData();
2854 $loggedInContactID = $this->createLoggedInUser();
2855 CRM_Core_Config
::singleton()->userPermissionClass
->permissions
= array();
2856 $result = $this->callAPISuccess('contact', 'getquick', array(
2859 $this->assertEquals(0, $result['count']);
2861 $this->hookClass
->setHook('civicrm_aclWhereClause', array($this, 'aclWhereNoBobH'));
2862 CRM_Contact_BAO_Contact_Permission
::cache($loggedInContactID, CRM_Core_Permission
::VIEW
, TRUE);
2863 $result = $this->callAPISuccess('contact', 'getquick', array(
2867 // Without the acl it would be 6 like the previous email getquick test.
2868 $this->assertEquals(5, $result['count']);
2869 $expectedData = array(
2870 'A Bobby, Bobby :: bob@bobby.com',
2871 'Bob, Bob :: bob@bob.com',
2874 $this->callAPISuccessGetValue('Contact', array('id' => $loggedInContactID, 'return' => 'last_name')) . ', Logged In :: anthony_anderson@civicrm.org',
2876 foreach ($expectedData as $index => $value) {
2877 $this->assertEquals($value, $result['values'][$index]['data']);
2882 * Test that getquick returns contacts with an exact first name match first.
2884 public function testGetQuickExternalID() {
2885 $this->getQuickSearchSampleData();
2886 $result = $this->callAPISuccess('contact', 'getquick', array(
2888 'field_name' => 'external_identifier',
2889 'table_name' => 'cc',
2891 $this->assertEquals(0, $result['count']);
2892 $result = $this->callAPISuccess('contact', 'getquick', array(
2894 'field_name' => 'external_identifier',
2895 'table_name' => 'cc',
2897 $this->assertEquals(1, $result['count']);
2898 $this->assertEquals('Bob, Bob', $result['values'][0]['sort_name']);
2902 * Test that getquick returns contacts with an exact first name match first.
2904 public function testGetQuickID() {
2905 $max = CRM_Core_DAO
::singleValueQuery("SELECT max(id) FROM civicrm_contact");
2906 $this->getQuickSearchSampleData();
2907 $result = $this->callAPISuccess('contact', 'getquick', array(
2909 'field_name' => 'id',
2910 'table_name' => 'cc',
2912 $this->assertEquals(1, $result['count']);
2913 $this->assertEquals('E Bobby, Bobby', $result['values'][0]['sort_name']);
2914 $result = $this->callAPISuccess('contact', 'getquick', array(
2916 'field_name' => 'contact_id',
2917 'table_name' => 'cc',
2919 $this->assertEquals(1, $result['count']);
2920 $this->assertEquals('E Bobby, Bobby', $result['values'][0]['sort_name']);
2924 * Test that getquick returns contacts with an exact first name match first.
2926 * Depending on the setting the sort name sort might click in next or not - test!
2928 public function testGetQuickFirstName() {
2929 $this->getQuickSearchSampleData();
2930 $this->callAPISuccess('Setting', 'create', array('includeOrderByClause' => TRUE));
2931 $result = $this->callAPISuccess('contact', 'getquick', array(
2933 'field_name' => 'first_name',
2934 'table_name' => 'cc',
2943 foreach ($expected as $index => $value) {
2944 $this->assertEquals($value, $result['values'][$index]['sort_name']);
2946 $this->callAPISuccess('Setting', 'create', array('includeOrderByClause' => FALSE));
2947 $result = $this->callAPISuccess('contact', 'getquick', array('name' => 'bob'));
2948 $this->assertEquals('Bob, Bob', $result['values'][0]['sort_name']);
2949 // This test has been disabled as is proving to be problematic to reproduce due to MySQL sorting issues between different versions
2950 //$this->assertEquals('E Bobby, Bobby', $result['values'][1]['sort_name']);
2954 * Test that getquick applies ACLs.
2956 public function testGetQuickFirstNameACLs() {
2957 $this->getQuickSearchSampleData();
2958 $userID = $this->createLoggedInUser();
2959 $this->callAPISuccess('Setting', 'create', array('includeOrderByClause' => TRUE, 'search_autocomplete_count' => 15));
2960 CRM_Core_Config
::singleton()->userPermissionClass
->permissions
= array();
2961 $result = $this->callAPISuccess('contact', 'getquick', array(
2963 'field_name' => 'first_name',
2964 'table_name' => 'cc',
2966 $this->assertEquals(0, $result['count']);
2968 $this->hookClass
->setHook('civicrm_aclWhereClause', array($this, 'aclWhereNoBobH'));
2969 CRM_Contact_BAO_Contact_Permission
::cache($userID, CRM_Core_Permission
::VIEW
, TRUE);
2970 $result = $this->callAPISuccess('contact', 'getquick', array(
2972 'field_name' => 'first_name',
2973 'table_name' => 'cc',
2975 $this->assertEquals('K Bobby, Bob', $result['values'][2]['sort_name']);
2976 // Without the ACL 9 would be bob@h.com.
2977 $this->assertEquals('I Bobby, Bobby', $result['values'][10]['sort_name']);
2981 * Full results returned.
2982 * @implements CRM_Utils_Hook::aclWhereClause
2984 * @param string $type
2985 * @param array $tables
2986 * @param array $whereTables
2987 * @param int $contactID
2988 * @param string $where
2990 public function aclWhereNoBobH($type, &$tables, &$whereTables, &$contactID, &$where) {
2991 $where = " (email <> 'bob@h.com' OR email IS NULL) ";
2992 $whereTables['civicrm_email'] = "LEFT JOIN civicrm_email e ON contact_a.id = e.contact_id";
2996 * Test that getquick returns contacts with an exact last name match first.
2998 public function testGetQuickLastName() {
2999 $this->getQuickSearchSampleData();
3000 $this->callAPISuccess('Setting', 'create', array('includeOrderByClause' => TRUE));
3001 $result = $this->callAPISuccess('contact', 'getquick', array(
3003 'field_name' => 'last_name',
3004 'table_name' => 'cc',
3012 foreach ($expected as $index => $value) {
3013 $this->assertEquals($value, $result['values'][$index]['sort_name']);
3015 $this->callAPISuccess('Setting', 'create', array('includeOrderByClause' => FALSE));
3016 $result = $this->callAPISuccess('contact', 'getquick', array('name' => 'bob'));
3017 $this->assertEquals('Bob, Bob :: bob@bob.com', $result['values'][0]['data']);
3021 * Test that getquick returns contacts by city.
3023 public function testGetQuickCity() {
3024 $this->getQuickSearchSampleData();
3025 $result = $this->callAPISuccess('contact', 'getquick', array(
3027 'field_name' => 'city',
3028 'table_name' => 'sts',
3030 $this->assertEquals('B Bobby, Bobby :: Toronto', $result['values'][0]['data']);
3031 $result = $this->callAPISuccess('contact', 'getquick', array(
3033 'field_name' => 'city',
3034 'table_name' => 'sts',
3036 $this->assertEquals('B Bobby, Bobby :: Toronto', $result['values'][0]['data']);
3037 $this->assertEquals('C Bobby, Bobby :: Whanganui', $result['values'][1]['data']);
3041 * Set up some sample data for testing quicksearch.
3043 public function getQuickSearchSampleData() {
3045 array('first_name' => 'Bob', 'last_name' => 'Bob', 'external_identifier' => 'abc', 'email' => 'bob@bob.com'),
3046 array('first_name' => 'Bobby', 'last_name' => 'E Bobby', 'external_identifier' => 'abcd'),
3048 'first_name' => 'Bobby',
3049 'last_name' => 'B Bobby',
3050 'external_identifier' => 'bcd',
3051 'api.address.create' => array(
3052 'street_address' => 'Sesame Street',
3053 'city' => 'Toronto',
3054 'location_type_id' => 1,
3058 'first_name' => 'Bobby',
3059 'last_name' => 'C Bobby',
3060 'external_identifier' => 'bcde',
3061 'api.address.create' => array(
3062 'street_address' => 'Te huarahi',
3063 'city' => 'Whanganui',
3064 'location_type_id' => 1,
3067 array('first_name' => 'Bobby', 'last_name' => 'D Bobby', 'external_identifier' => 'efg'),
3068 array('first_name' => 'Bobby', 'last_name' => 'A Bobby', 'external_identifier' => 'hij', 'email' => 'bob@bobby.com'),
3069 array('first_name' => 'Bobby', 'last_name' => 'F Bobby', 'external_identifier' => 'klm'),
3070 array('first_name' => 'Bobby', 'last_name' => 'G Bobby', 'external_identifier' => 'nop'),
3071 array('first_name' => 'Bobby', 'last_name' => 'H Bobby', 'external_identifier' => 'qrs', 'email' => 'bob@h.com'),
3072 array('first_name' => 'Bobby', 'last_name' => 'I Bobby'),
3073 array('first_name' => 'Bobby', 'last_name' => 'J Bobby'),
3074 array('first_name' => 'Bob', 'last_name' => 'K Bobby', 'external_identifier' => 'bcdef'),
3075 array('first_name' => 'Bob', 'last_name' => 'Aadvark'),
3077 foreach ($contacts as $type => $contact) {
3078 $contact['contact_type'] = 'Individual';
3079 $this->callAPISuccess('Contact', 'create', $contact);
3084 * Test get ref api - gets a list of references to an entity.
3086 public function testGetReferenceCounts() {
3087 $result = $this->callAPISuccess('Contact', 'create', array(
3088 'first_name' => 'Testily',
3089 'last_name' => 'McHaste',
3090 'contact_type' => 'Individual',
3091 'api.Address.replace' => array(
3092 'values' => array(),
3094 'api.Email.replace' => array(
3097 'email' => 'spam@dev.null',
3099 'location_type_id' => 1,
3103 'api.Phone.replace' => array(
3106 'phone' => '234-567-0001',
3108 'location_type_id' => 1,
3111 'phone' => '234-567-0002',
3113 'location_type_id' => 1,
3119 //$dao = new CRM_Contact_BAO_Contact();
3120 //$dao->id = $result['id'];
3121 //$this->assertTrue((bool) $dao->find(TRUE));
3123 //$refCounts = $dao->getReferenceCounts();
3124 //$this->assertTrue(is_array($refCounts));
3125 //$refCountsIdx = CRM_Utils_Array::index(array('name'), $refCounts);
3127 $refCounts = $this->callAPISuccess('Contact', 'getrefcount', array(
3128 'id' => $result['id'],
3130 $refCountsIdx = CRM_Utils_Array
::index(array('name'), $refCounts['values']);
3132 $this->assertEquals(1, $refCountsIdx['sql:civicrm_email:contact_id']['count']);
3133 $this->assertEquals('civicrm_email', $refCountsIdx['sql:civicrm_email:contact_id']['table']);
3134 $this->assertEquals(2, $refCountsIdx['sql:civicrm_phone:contact_id']['count']);
3135 $this->assertEquals('civicrm_phone', $refCountsIdx['sql:civicrm_phone:contact_id']['table']);
3136 $this->assertTrue(!isset($refCountsIdx['sql:civicrm_address:contact_id']));
3140 * Test the use of sql operators.
3142 public function testSQLOperatorsOnContactAPI() {
3143 $this->individualCreate();
3144 $this->organizationCreate();
3145 $this->householdCreate();
3146 $contacts = $this->callAPISuccess('contact', 'get', array('legal_name' => array('IS NOT NULL' => TRUE)));
3147 $this->assertEquals($contacts['count'], CRM_Core_DAO
::singleValueQuery('select count(*) FROM civicrm_contact WHERE legal_name IS NOT NULL'));
3148 $contacts = $this->callAPISuccess('contact', 'get', array('legal_name' => array('IS NULL' => TRUE)));
3149 $this->assertEquals($contacts['count'], CRM_Core_DAO
::singleValueQuery('select count(*) FROM civicrm_contact WHERE legal_name IS NULL'));
3153 * CRM-14743 - test api respects search operators.
3155 public function testGetModifiedDateByOperators() {
3156 $preExistingContactCount = CRM_Core_DAO
::singleValueQuery('select count(*) FROM civicrm_contact');
3157 $contact1 = $this->individualCreate();
3158 $sql = "UPDATE civicrm_contact SET created_date = '2012-01-01', modified_date = '2013-01-01' WHERE id = " . $contact1;
3159 CRM_Core_DAO
::executeQuery($sql);
3160 $contact2 = $this->individualCreate();
3161 $sql = "UPDATE civicrm_contact SET created_date = '2012-02-01', modified_date = '2013-02-01' WHERE id = " . $contact2;
3162 CRM_Core_DAO
::executeQuery($sql);
3163 $contact3 = $this->householdCreate();
3164 $sql = "UPDATE civicrm_contact SET created_date = '2012-03-01', modified_date = '2013-03-01' WHERE id = " . $contact3;
3165 CRM_Core_DAO
::executeQuery($sql);
3166 $contacts = $this->callAPISuccess('contact', 'get', array('modified_date' => array('<' => '2014-01-01')));
3167 $this->assertEquals($contacts['count'], 3);
3168 $contacts = $this->callAPISuccess('contact', 'get', array('modified_date' => array('>' => '2014-01-01')));
3169 $this->assertEquals($contacts['count'], $preExistingContactCount);
3173 * CRM-14743 - test api respects search operators.
3175 public function testGetCreatedDateByOperators() {
3176 $preExistingContactCount = CRM_Core_DAO
::singleValueQuery('select count(*) FROM civicrm_contact');
3177 $contact1 = $this->individualCreate();
3178 $sql = "UPDATE civicrm_contact SET created_date = '2012-01-01' WHERE id = " . $contact1;
3179 CRM_Core_DAO
::executeQuery($sql);
3180 $contact2 = $this->individualCreate();
3181 $sql = "UPDATE civicrm_contact SET created_date = '2012-02-01' WHERE id = " . $contact2;
3182 CRM_Core_DAO
::executeQuery($sql);
3183 $contact3 = $this->householdCreate();
3184 $sql = "UPDATE civicrm_contact SET created_date = '2012-03-01' WHERE id = " . $contact3;
3185 CRM_Core_DAO
::executeQuery($sql);
3186 $contacts = $this->callAPISuccess('contact', 'get', array('created_date' => array('<' => '2014-01-01')));
3187 $this->assertEquals($contacts['count'], 3);
3188 $contacts = $this->callAPISuccess('contact', 'get', array('created_date' => array('>' => '2014-01-01')));
3189 $this->assertEquals($contacts['count'], $preExistingContactCount);
3193 * CRM-14263 check that API is not affected by search profile related bug.
3195 public function testReturnCityProfile() {
3196 $contactID = $this->individualCreate();
3197 CRM_Core_Config
::singleton()->defaultSearchProfileID
= 1;
3198 $this->callAPISuccess('address', 'create', array(
3199 'contact_id' => $contactID,
3200 'city' => 'Cool City',
3201 'location_type_id' => 1,
3203 $result = $this->callAPISuccess('contact', 'get', array('city' => 'Cool City', 'return' => 'contact_type'));
3204 $this->assertEquals(1, $result['count']);
3208 * CRM-15443 - ensure getlist api does not return deleted contacts.
3210 public function testGetlistExcludeConditions() {
3212 $contact = $this->individualCreate(array('last_name' => $name));
3213 $this->individualCreate(array('last_name' => $name, 'is_deceased' => 1));
3214 $this->individualCreate(array('last_name' => $name, 'is_deleted' => 1));
3215 // We should get all but the deleted contact.
3216 $result = $this->callAPISuccess('contact', 'getlist', array('input' => $name));
3217 $this->assertEquals(2, $result['count']);
3218 // Force-exclude the deceased contact.
3219 $result = $this->callAPISuccess('contact', 'getlist', array(
3221 'params' => array('is_deceased' => 0),
3223 $this->assertEquals(1, $result['count']);
3224 $this->assertEquals($contact, $result['values'][0]['id']);
3228 * Test contact getactions.
3230 public function testGetActions() {
3231 $description = "Getting the available actions for an entity.";
3232 $result = $this->callAPIAndDocument($this->_entity
, 'getactions', array(), __FUNCTION__
, __FILE__
, $description);
3252 $deprecated = array(
3256 foreach ($expected as $action) {
3257 $this->assertTrue(in_array($action, $result['values']), "Expected action $action");
3259 foreach ($deprecated as $action) {
3260 $this->assertArrayKeyExists($action, $result['deprecated']);
3265 * Test the duplicate check function.
3267 public function testDuplicateCheck() {
3269 'first_name' => 'Harry',
3270 'last_name' => 'Potter',
3271 'email' => 'harry@hogwarts.edu',
3272 'contact_type' => 'Individual',
3274 $this->callAPISuccess('Contact', 'create', $harry);
3275 $result = $this->callAPISuccess('Contact', 'duplicatecheck', array(
3279 $this->assertEquals(1, $result['count']);
3280 $result = $this->callAPISuccess('Contact', 'duplicatecheck', array(
3282 'first_name' => 'Harry',
3283 'last_name' => 'Potter',
3284 'email' => 'no5@privet.drive',
3285 'contact_type' => 'Individual',
3288 $this->assertEquals(0, $result['count']);
3289 $this->callAPIFailure('Contact', 'create', array_merge($harry, array('dupe_check' => 1)));
3293 * Test the duplicate check function.
3295 public function testDuplicateCheckRuleNotReserved() {
3297 'first_name' => 'Harry',
3298 'last_name' => 'Potter',
3299 'email' => 'harry@hogwarts.edu',
3300 'contact_type' => 'Individual',
3302 $defaultRule = $this->callAPISuccess('RuleGroup', 'getsingle', array('used' => 'Unsupervised', 'is_reserved' => 1));
3303 $this->callAPISuccess('RuleGroup', 'create', array('id' => $defaultRule['id'], 'is_reserved' => 0));
3304 $this->callAPISuccess('Contact', 'create', $harry);
3305 $result = $this->callAPISuccess('Contact', 'duplicatecheck', array(
3309 $this->assertEquals(1, $result['count']);
3310 $this->callAPISuccess('RuleGroup', 'create', array('id' => $defaultRule['id'], 'is_reserved' => 1));
3314 * Test variants on retrieving contact by type.
3316 public function testGetByContactType() {
3317 $individual = $this->callAPISuccess('Contact', 'create', array(
3318 'email' => 'individual@test.com',
3319 'contact_type' => 'Individual',
3321 $household = $this->callAPISuccess('Contact', 'create', array(
3322 'household_name' => 'household@test.com',
3323 'contact_type' => 'Household',
3325 $organization = $this->callAPISuccess('Contact', 'create', array(
3326 'organization_name' => 'organization@test.com',
3327 'contact_type' => 'Organization',
3329 // Test with id - getsingle will throw an exception if not found
3330 $this->callAPISuccess('Contact', 'getsingle', array(
3331 'id' => $individual['id'],
3332 'contact_type' => 'Individual',
3334 $this->callAPISuccess('Contact', 'getsingle', array(
3335 'id' => $individual['id'],
3336 'contact_type' => array('IN' => array('Individual')),
3339 $this->callAPISuccess('Contact', 'getsingle', array(
3340 'id' => $organization['id'],
3341 'contact_type' => array('IN' => array('Individual', 'Organization')),
3344 $result = $this->callAPISuccess('Contact', 'get', array(
3345 'contact_type' => array('IN' => array('Individual', 'Organization')),
3346 'options' => array('limit' => 0),
3349 $this->assertContains($organization['id'], array_keys($result['values']));
3350 $this->assertContains($individual['id'], array_keys($result['values']));
3351 $this->assertNotContains($household['id'], array_keys($result['values']));
3353 $result = $this->callAPISuccess('Contact', 'get', array(
3354 'contact_type' => 'Household',
3355 'options' => array('limit' => 0),
3358 $this->assertNotContains($organization['id'], array_keys($result['values']));
3359 $this->assertNotContains($individual['id'], array_keys($result['values']));
3360 $this->assertContains($household['id'], array_keys($result['values']));
3364 * Test merging 2 contacts.
3366 * Someone kindly bequethed us the legacy of mixed up use of main_id & other_id
3367 * in the params for contact.merge api.
3369 * This test protects that legacy.
3371 public function testMergeBizzareOldParams() {
3372 $this->createLoggedInUser();
3373 $otherContact = $this->callAPISuccess('contact', 'create', $this->_params
);
3374 $mainContact = $this->callAPISuccess('contact', 'create', $this->_params
);
3375 $this->callAPISuccess('contact', 'merge', array(
3376 'main_id' => $mainContact['id'],
3377 'other_id' => $otherContact['id'],
3379 $contacts = $this->callAPISuccess('contact', 'get', $this->_params
);
3380 $this->assertEquals($otherContact['id'], $contacts['id']);
3384 * Test merging 2 contacts.
3386 public function testMerge() {
3387 $this->createLoggedInUser();
3388 $otherContact = $this->callAPISuccess('contact', 'create', $this->_params
);
3389 $retainedContact = $this->callAPISuccess('contact', 'create', $this->_params
);
3390 $this->callAPISuccess('contact', 'merge', array(
3391 'to_keep_id' => $retainedContact['id'],
3392 'to_remove_id' => $otherContact['id'],
3393 'auto_flip' => FALSE,
3396 $contacts = $this->callAPISuccess('contact', 'get', $this->_params
);
3397 $this->assertEquals($retainedContact['id'], $contacts['id']);
3398 $activity = $this->callAPISuccess('Activity', 'getsingle', array(
3399 'target_contact_id' => $retainedContact['id'],
3400 'activity_type_id' => 'Contact Merged',
3402 $this->assertEquals(date('Y-m-d'), date('Y-m-d', strtotime($activity['activity_date_time'])));
3403 $activity2 = $this->callAPISuccess('Activity', 'getsingle', array(
3404 'target_contact_id' => $otherContact['id'],
3405 'activity_type_id' => 'Contact Deleted by Merge',
3407 $this->assertEquals($activity['id'], $activity2['parent_id']);
3408 $this->assertEquals('Normal', civicrm_api3('option_value', 'getvalue', array(
3409 'value' => $activity['priority_id'],
3410 'return' => 'label',
3411 'option_group_id' => 'priority',
3417 * Test retrieving merged contacts.
3419 * The goal here is to start with a contact deleted by merged and find out the contact that is the current version of them.
3421 public function testMergedGet() {
3422 $this->contactIDs
[] = $this->individualCreate();
3423 $this->contactIDs
[] = $this->individualCreate();
3424 $this->contactIDs
[] = $this->individualCreate();
3425 $this->contactIDs
[] = $this->individualCreate();
3427 // First do an 'unnatural merge' - they 'like to merge into the lowest but this will mean that contact 0 merged to contact [3].
3428 // When the batch merge runs.... the new lowest contact is contact[1]. All contacts will merge into that contact,
3429 // including contact[3], resulting in only 3 existing at the end. For each contact the correct answer to 'who did I eventually
3430 // wind up being should be [1]
3431 $this->callAPISuccess('Contact', 'merge', ['to_remove_id' => $this->contactIDs
[0], 'to_keep_id' => $this->contactIDs
[3]]);
3433 $this->callAPISuccess('Job', 'process_batch_merge', []);
3434 foreach ($this->contactIDs
as $contactID) {
3435 if ($contactID === $this->contactIDs
[1]) {
3438 $result = $this->callAPIAndDocument('Contact', 'getmergedto', ['sequential' => 1, 'contact_id' => $contactID], __FUNCTION__
, __FILE__
);
3439 $this->assertEquals(1, $result['count']);
3440 $this->assertEquals($this->contactIDs
[1], $result['values'][0]['id']);
3443 $result = $this->callAPIAndDocument('Contact', 'getmergedfrom', ['contact_id' => $this->contactIDs
[1]], __FUNCTION__
, __FILE__
)['values'];
3444 $mergedContactIds = array_merge(array_diff($this->contactIDs
, [$this->contactIDs
[1]]));
3445 $this->assertEquals($mergedContactIds, array_keys($result));
3449 * Test merging 2 contacts with delete to trash off.
3451 * We are checking that there is no error due to attempting to add an activity for the
3456 public function testMergeNoTrash() {
3457 $this->createLoggedInUser();
3458 $this->callAPISuccess('Setting', 'create', array('contact_undelete' => FALSE));
3459 $otherContact = $this->callAPISuccess('contact', 'create', $this->_params
);
3460 $retainedContact = $this->callAPISuccess('contact', 'create', $this->_params
);
3461 $this->callAPISuccess('contact', 'merge', array(
3462 'to_keep_id' => $retainedContact['id'],
3463 'to_remove_id' => $otherContact['id'],
3464 'auto_flip' => FALSE,
3466 $this->callAPISuccess('Setting', 'create', array('contact_undelete' => TRUE));
3470 * Ensure format with return=group shows comma-separated group IDs.
3474 public function testContactGetReturnGroup() {
3475 // Set up a contact, asser that they were created.
3476 $contact_params = array(
3477 'contact_type' => 'Individual',
3478 'first_name' => 'Test',
3479 'last_name' => 'Groupmember',
3480 'email' => 'test@example.org',
3482 $create_contact = $this->callApiSuccess('Contact', 'create', $contact_params);
3483 $this->assertEquals(0, $create_contact['is_error']);
3484 $this->assertInternalType('int', $create_contact['id']);
3486 $created_contact_id = $create_contact['id'];
3488 // Set up multiple groups, add the contact to the groups.
3489 $test_groups = array('Test group A', 'Test group B');
3490 foreach ($test_groups as $title) {
3491 // Use this contact as group owner, since we know they exist.
3492 $group_params = array(
3494 'created_id' => $created_contact_id,
3496 $create_group = $this->callApiSuccess('Group', 'create', $group_params);
3497 $this->assertEquals(0, $create_group['is_error']);
3498 $this->assertInternalType('int', $create_group['id']);
3500 $created_group_ids[] = $create_group['id'];
3502 // Add contact to the new group.
3503 $group_contact_params = array(
3504 'contact_id' => $created_contact_id,
3505 'group_id' => $create_group['id'],
3507 $create_group_contact = $this->callApiSuccess('GroupContact', 'create', $group_contact_params);
3508 $this->assertEquals(0, $create_group_contact['is_error']);
3509 $this->assertInternalType('int', $create_group_contact['added']);
3512 // Use the Contact,get API to retrieve the contact
3513 $contact_get_params = array(
3514 'id' => $created_contact_id,
3515 'return' => 'group',
3517 $contact_get = $this->callApiSuccess('Contact', 'get', $contact_get_params);
3518 $this->assertInternalType('array', $contact_get['values'][$created_contact_id]);
3519 $this->assertInternalType('string', $contact_get['values'][$created_contact_id]['groups']);
3521 // Ensure they are shown as being in each created group.
3522 $contact_group_ids = explode(',', $contact_get['values'][$created_contact_id]['groups']);
3523 foreach ($created_group_ids as $created_group_id) {
3524 $this->assertContains($created_group_id, $contact_group_ids);
3529 * CRM-20144 Verify that passing title of group works as well as id
3530 * Tests the following formats
3531 * contact.get group='title1'
3532 * contact.get group=id1
3534 public function testContactGetWithGroupTitle() {
3535 // Set up a contact, asser that they were created.
3536 $contact_params = array(
3537 'contact_type' => 'Individual',
3538 'first_name' => 'Test2',
3539 'last_name' => 'Groupmember',
3540 'email' => 'test@example.org',
3542 $create_contact = $this->callApiSuccess('Contact', 'create', $contact_params);
3543 $created_contact_id = $create_contact['id'];
3544 // Set up multiple groups, add the contact to the groups.
3545 $test_groups = array('Test group C', 'Test group D');
3546 foreach ($test_groups as $title) {
3547 $group_params = array(
3549 'created_id' => $created_contact_id,
3551 $create_group = $this->callApiSuccess('Group', 'create', $group_params);
3552 $created_group_id = $create_group['id'];
3554 // Add contact to the new group.
3555 $group_contact_params = array(
3556 'contact_id' => $created_contact_id,
3557 'group_id' => $create_group['id'],
3559 $this->callApiSuccess('GroupContact', 'create', $group_contact_params);
3560 $contact_get = $this->callAPISuccess('contact', 'get', array('group' => $title, 'return' => 'group'));
3561 $this->assertEquals(1, $contact_get['count']);
3562 $this->assertEquals($created_contact_id, $contact_get['id']);
3563 $contact_groups = explode(',', $contact_get['values'][$created_contact_id]['groups']);
3564 $this->assertContains((string) $create_group['id'], $contact_groups);
3565 $contact_get2 = $this->callAPISuccess('contact', 'get', array('group' => $created_group_id, 'return' => 'group'));
3566 $this->assertEquals($created_contact_id, $contact_get2['id']);
3567 $contact_groups2 = explode(',', $contact_get2['values'][$created_contact_id]['groups']);
3568 $this->assertContains((string) $create_group['id'], $contact_groups2);
3569 $this->callAPISuccess('group', 'delete', array('id' => $created_group_id));
3571 $this->callAPISuccess('contact', 'delete', array('id' => $created_contact_id, 'skip_undelete' => TRUE));
3575 * CRM-20144 Verify that passing title of group works as well as id
3576 * Tests the following formats
3577 * contact.get group=array('title1', title1)
3578 * contact.get group=array('IN' => array('title1', 'title2)
3580 public function testContactGetWithGroupTitleMultipleGroups() {
3581 $description = "Get all from group and display contacts.";
3582 $subFile = "GroupFilterUsingContactAPI";
3583 // Set up a contact, asser that they were created.
3584 $contact_params = array(
3585 'contact_type' => 'Individual',
3586 'first_name' => 'Test2',
3587 'last_name' => 'Groupmember',
3588 'email' => 'test@example.org',
3590 $create_contact = $this->callApiSuccess('Contact', 'create', $contact_params);
3591 $created_contact_id = $create_contact['id'];
3592 $createdGroupsTitles = $createdGroupsIds = array();
3593 // Set up multiple groups, add the contact to the groups.
3594 $test_groups = array('Test group C', 'Test group D');
3595 foreach ($test_groups as $title) {
3596 $group_params = array(
3598 'created_id' => $created_contact_id,
3600 $create_group = $this->callApiSuccess('Group', 'create', $group_params);
3601 $created_group_id = $create_group['id'];
3602 $createdGroupsIds[] = $create_group['id'];
3603 $createdGroupTitles[] = $title;
3604 // Add contact to the new group.
3605 $group_contact_params = array(
3606 'contact_id' => $created_contact_id,
3607 'group_id' => $create_group['id'],
3609 $create_group_contact = $this->callApiSuccess('GroupContact', 'create', $group_contact_params);
3611 $contact_get = $this->callAPISuccess('contact', 'get', array('group' => $createdGroupTitles, 'return' => 'group'));
3612 $this->assertEquals(1, $contact_get['count']);
3613 $this->assertEquals($created_contact_id, $contact_get['id']);
3614 $contact_groups = explode(',', $contact_get['values'][$created_contact_id]['groups']);
3615 foreach ($createdGroupsIds as $id) {
3616 $this->assertContains((string) $id, $contact_groups);
3618 $contact_get2 = $this->callAPIAndDocument('contact', 'get', array('group' => array('IN' => $createdGroupTitles)), __FUNCTION__
, __FILE__
, $description, $subFile);
3619 $contact_get2 = $this->callAPISuccess('contact', 'get', array('group' => array('IN' => $createdGroupTitles), 'return' => 'group'));
3620 $this->assertEquals($created_contact_id, $contact_get2['id']);
3621 $contact_groups2 = explode(',', $contact_get2['values'][$created_contact_id]['groups']);
3622 foreach ($createdGroupsIds as $id) {
3623 $this->assertContains((string) $id, $contact_groups2);
3625 foreach ($createdGroupsIds as $id) {
3626 $this->callAPISuccess('group', 'delete', array('id' => $id));
3628 $this->callAPISuccess('contact', 'delete', array('id' => $created_contact_id, 'skip_undelete' => TRUE));
3632 * CRM-20144 Verify that passing title of group works as well as id
3633 * Tests the following formats
3634 * contact.get group=array('title1' => 1)
3635 * contact.get group=array('titke1' => 1, 'title2' => 1)
3636 * contact.get group=array('id1' => 1)
3637 * contact.get group=array('id1' => 1, id2 => 1)
3639 public function testContactGetWithGroupTitleMultipleGroupsLegacyFormat() {
3640 // Set up a contact, asser that they were created.
3641 $contact_params = array(
3642 'contact_type' => 'Individual',
3643 'first_name' => 'Test2',
3644 'last_name' => 'Groupmember',
3645 'email' => 'test@example.org',
3647 $create_contact = $this->callApiSuccess('Contact', 'create', $contact_params);
3648 $created_contact_id = $create_contact['id'];
3649 $createdGroupsTitles = $createdGroupsIds = array();
3650 // Set up multiple groups, add the contact to the groups.
3651 $test_groups = array('Test group C', 'Test group D');
3652 foreach ($test_groups as $title) {
3653 $group_params = array(
3655 'created_id' => $created_contact_id,
3657 $create_group = $this->callApiSuccess('Group', 'create', $group_params);
3658 $created_group_id = $create_group['id'];
3659 $createdGroupsIds[] = $create_group['id'];
3660 $createdGroupTitles[] = $title;
3661 // Add contact to the new group.
3662 $group_contact_params = array(
3663 'contact_id' => $created_contact_id,
3664 'group_id' => $create_group['id'],
3666 $create_group_contact = $this->callApiSuccess('GroupContact', 'create', $group_contact_params);
3668 $contact_get = $this->callAPISuccess('contact', 'get', array('group' => array($createdGroupTitles[0] => 1), 'return' => 'group'));
3669 $this->assertEquals(1, $contact_get['count']);
3670 $this->assertEquals($created_contact_id, $contact_get['id']);
3671 $contact_groups = explode(',', $contact_get['values'][$created_contact_id]['groups']);
3672 foreach ($createdGroupsIds as $id) {
3673 $this->assertContains((string) $id, $contact_groups);
3675 $contact_get2 = $this->callAPISuccess('contact', 'get', array('group' => array($createdGroupTitles[0] => 1, $createdGroupTitles[1] => 1), 'return' => 'group'));
3676 $this->assertEquals(1, $contact_get2['count']);
3677 $this->assertEquals($created_contact_id, $contact_get2['id']);
3678 $contact_groups2 = explode(',', $contact_get2['values'][$created_contact_id]['groups']);
3679 foreach ($createdGroupsIds as $id) {
3680 $this->assertContains((string) $id, $contact_groups2);
3682 $contact_get3 = $this->callAPISuccess('contact', 'get', array('group' => array($createdGroupsIds[0] => 1), 'return' => 'group'));
3683 $this->assertEquals($created_contact_id, $contact_get3['id']);
3684 $contact_groups3 = explode(',', $contact_get3['values'][$created_contact_id]['groups']);
3685 foreach ($createdGroupsIds as $id) {
3686 $this->assertContains((string) $id, $contact_groups3);
3688 $contact_get4 = $this->callAPISuccess('contact', 'get', array('group' => array($createdGroupsIds[0] => 1, $createdGroupsIds[1] => 1), 'return' => 'group'));
3689 $this->assertEquals($created_contact_id, $contact_get4['id']);
3690 $contact_groups4 = explode(',', $contact_get4['values'][$created_contact_id]['groups']);
3691 foreach ($createdGroupsIds as $id) {
3692 $this->assertContains((string) $id, $contact_groups4);
3694 foreach ($createdGroupsIds as $id) {
3695 $this->callAPISuccess('group', 'delete', array('id' => $id));
3697 $this->callAPISuccess('contact', 'delete', array('id' => $created_contact_id, 'skip_undelete' => TRUE));
3701 * Test the prox_distance functionality works.
3703 * This is primarily testing functionality in the BAO_Query object that 'happens to be'
3704 * accessible via the api.
3706 public function testContactGetProximity() {
3707 CRM_Core_Config
::singleton()->geocodeMethod
= 'CRM_Utils_MockGeocoder';
3708 $this->individualCreate();
3709 $contactID = $this->individualCreate();
3710 $this->callAPISuccess('Address', 'create', [
3711 'contact_id' => $contactID,
3713 'city' => 'Whangarei',
3714 'street_address' => 'Dent St',
3715 'geo_code_1' => '-35.8743325',
3716 'geo_code_2' => '174.4567136',
3717 'location_type_id' => 'Home',
3719 $contact = $this->callAPISuccess('Contact', 'get', [
3720 'prox_distance' => 100,
3721 'prox_geo_code_1' => '-35.72192',
3722 'prox_geo_code_2' => '174.32034',
3724 $this->assertEquals(1, $contact['count']);
3725 $this->assertEquals($contactID, $contact['id']);
3728 public function testLoggedInUserAPISupportToken() {
3729 $description = "Get contact id of the current logged in user";
3730 $subFile = "ContactIDOfLoggedInUserContactAPI";
3731 $cid = $this->createLoggedInUser();
3732 $contact = $this->callAPIAndDocument('contact', 'get', array('id' => 'user_contact_id'), __FUNCTION__
, __FILE__
, $description, $subFile);
3733 $this->assertEquals($cid, $contact['id']);
3740 protected function putGroupContactCacheInClearableState($groupID, $contact) {
3741 // We need to force the situation where there is invalid data in the cache and it
3742 // is due to be cleared.
3743 CRM_Core_DAO
::executeQuery("
3744 INSERT INTO civicrm_group_contact_cache (group_id, contact_id)
3745 VALUES ({$groupID}, {$contact['id']})
3747 CRM_Core_DAO
::executeQuery("UPDATE civicrm_group SET cache_date = '2017-01-01'");
3748 // Reset so it does not skip.
3749 Civi
::$statics['CRM_Contact_BAO_GroupContactCache']['is_refresh_init'] = FALSE;
3753 * CRM-21041 Test if 'communication style' is set to site default if not passed.
3755 public function testCreateCommunicationStyleUnset() {
3756 $this->callAPISuccess('Contact', 'create', array(
3757 'first_name' => 'John',
3758 'last_name' => 'Doe',
3759 'contact_type' => 'Individual')
3761 $result = $this->callAPISuccessGetSingle('Contact', array('last_name' => 'Doe'));
3762 $this->assertEquals(1, $result['communication_style_id']);
3766 * CRM-21041 Test if 'communication style' is set if value is passed.
3768 public function testCreateCommunicationStylePassed() {
3769 $this->callAPISuccess('Contact', 'create', array(
3770 'first_name' => 'John',
3771 'last_name' => 'Doe',
3772 'contact_type' => 'Individual',
3773 'communication_style_id' => 'Familiar',
3775 $result = $this->callAPISuccessGetSingle('Contact', array('last_name' => 'Doe'));
3777 'option_group_id' => 'communication_style',
3778 'label' => 'Familiar',
3779 'return' => 'value',
3781 $optionResult = civicrm_api3('OptionValue', 'get', $params);
3782 $communicationStyle = reset($optionResult['values']);
3783 $this->assertEquals($communicationStyle['value'], $result['communication_style_id']);
3787 * Test that creating a contact with various contact greetings works.
3789 public function testContactGreetingsCreate() {
3790 $contact = $this->callAPISuccess('Contact', 'create', array('first_name' => 'Alan', 'last_name' => 'MouseMouse', 'contact_type' => 'Individual'));
3791 $contact = $this->callAPISuccessGetSingle('Contact', array('id' => $contact['id'], 'return' => 'postal_greeting'));
3792 $this->assertEquals('Dear Alan', $contact['postal_greeting_display']);
3794 $contact = $this->callAPISuccess('Contact', 'create', array('id' => $contact['id'], 'postal_greeting_id' => 2));
3795 $contact = $this->callAPISuccessGetSingle('Contact', array('id' => $contact['id'], 'return' => 'postal_greeting'));
3796 $this->assertEquals('Dear Alan MouseMouse', $contact['postal_greeting_display']);
3798 $contact = $this->callAPISuccess('Contact', 'create', array('organization_name' => 'Alan\'s Show', 'contact_type' => 'Organization'));
3799 $contact = $this->callAPISuccessGetSingle('Contact', array('id' => $contact['id'], 'return' => 'postal_greeting, addressee, email_greeting'));
3800 $this->assertEquals('', $contact['postal_greeting_display']);
3801 $this->assertEquals('', $contact['email_greeting_display']);
3802 $this->assertEquals('Alan\'s Show', $contact['addressee_display']);
3806 * Test that creating a contact with various contact greetings works.
3808 public function testContactGreetingsCreateWithCustomField() {
3809 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__
, __FILE__
);
3810 $contact = $this->callAPISuccess('Contact', 'create', array('first_name' => 'Alan', 'contact_type' => 'Individual', 'custom_' . $ids['custom_field_id'] => 'Mice'));
3812 // Change postal greeting to involve a custom field.
3813 $postalOption = $this->callAPISuccessGetSingle('OptionValue', array('option_group_id' => 'postal_greeting', 'filter' => 1, 'is_default' => 1));
3814 $this->callAPISuccess('OptionValue', 'create', array(
3815 'id' => $postalOption['id'],
3816 'name' => 'Dear {contact.first_name} {contact.custom_' . $ids['custom_field_id'] . '}',
3817 'label' => 'Dear {contact.first_name} {contact.custom_' . $ids['custom_field_id'] . '}',
3820 // Update contact & see if postal greeting now reflects the new string.
3821 $this->callAPISuccess('Contact', 'create', array('id' => $contact['id'], 'last_name' => 'MouseyMousey'));
3822 $contact = $this->callAPISuccessGetSingle('Contact', array('id' => $contact['id'], 'return' => 'postal_greeting'));
3823 $this->assertEquals('Dear Alan Mice', $contact['postal_greeting_display']);
3825 // Set contact to have no postal greeting & check it is correct.
3826 $this->callAPISuccess('Contact', 'create', array('id' => $contact['id'], 'postal_greeting_id' => 'null'));
3827 $contact = $this->callAPISuccessGetSingle('Contact', array('id' => $contact['id'], 'return' => 'postal_greeting'));
3828 $this->assertEquals('', $contact['postal_greeting_display']);
3831 $this->callAPISuccess('OptionValue', 'create', array('id' => $postalOption['id'], 'name' => 'Dear {contact.first_name}'));
3832 $this->customFieldDelete($ids['custom_field_id']);
3833 $this->customGroupDelete($ids['custom_group_id']);
3837 * Test getunique api call for Contact entity
3839 public function testContactGetUnique() {
3840 $result = $this->callAPIAndDocument($this->_entity
, 'getunique', array(), __FUNCTION__
, __FILE__
);
3841 $this->assertEquals(1, $result['count']);
3842 $this->assertEquals(array('external_identifier'), $result['values']['UI_external_identifier']);
3846 * API test to retrieve contact from group having different group title and name.
3848 public function testContactGetFromGroup() {
3849 $groupId = $this->groupCreate([
3850 'name' => 'Test_Group',
3852 'title' => 'New Test Group Created',
3853 'description' => 'New Test Group Created',
3855 'visibility' => 'User and User Admin Only',
3857 $contact = $this->callAPISuccess('contact', 'create', $this->_params
);
3858 $groupContactCreateParams = array(
3859 'contact_id' => $contact['id'],
3860 'group_id' => $groupId,
3861 'status' => 'Pending',
3863 $groupContact = $this->callAPISuccess('groupContact', 'create', $groupContactCreateParams);
3864 $groupGetContact = $this->CallAPISuccess('groupContact', 'get', $groupContactCreateParams);
3865 $this->CallAPISuccess('Contact', 'getcount', [
3866 'group' => "Test_Group",
3870 public function testSmartGroupsForRelatedContacts() {
3871 $rtype1 = $this->callAPISuccess('relationship_type', 'create', array(
3872 "name_a_b" => uniqid() . " Child of",
3873 "name_b_a" => uniqid() . " Parent of",
3875 $rtype2 = $this->callAPISuccess('relationship_type', 'create', array(
3876 "name_a_b" => uniqid() . " Household Member of",
3877 "name_b_a" => uniqid() . " Household Member is",
3879 $h1 = $this->householdCreate();
3880 $c1 = $this->individualCreate(array('last_name' => 'Adams'));
3881 $c2 = $this->individualCreate(array('last_name' => 'Adams'));
3882 $this->callAPISuccess('relationship', 'create', array(
3883 'contact_id_a' => $c1,
3884 'contact_id_b' => $c2,
3886 'relationship_type_id' => $rtype1['id'], // Child of
3888 $this->callAPISuccess('relationship', 'create', array(
3889 'contact_id_a' => $c1,
3890 'contact_id_b' => $h1,
3892 'relationship_type_id' => $rtype2['id'], // Household Member of
3894 $this->callAPISuccess('relationship', 'create', array(
3895 'contact_id_a' => $c2,
3896 'contact_id_b' => $h1,
3898 'relationship_type_id' => $rtype2['id'], // Household Member of
3902 'formValues' => array(
3903 'display_relationship_type' => $rtype1['id'] . '_a_b', // Child of
3904 'sort_name' => 'Adams',
3907 $g1ID = $this->smartGroupCreate($ssParams, array('name' => uniqid(), 'title' => uniqid()));
3909 'formValues' => array(
3910 'display_relationship_type' => $rtype2['id'] . '_a_b', // Household Member of
3913 $g2ID = $this->smartGroupCreate($ssParams, array('name' => uniqid(), 'title' => uniqid()));
3915 'formValues' => array(
3916 'display_relationship_type' => $rtype2['id'] . '_b_a', // Household Member is
3919 // the reverse of g2 which adds another layer for overlap at related contact filter
3920 $g3ID = $this->smartGroupCreate($ssParams, array('name' => uniqid(), 'title' => uniqid()));
3921 CRM_Contact_BAO_GroupContactCache
::loadAll();
3922 $g1Contacts = $this->callAPISuccess('contact', 'get', array('group' => $g1ID));
3923 $g2Contacts = $this->callAPISuccess('contact', 'get', array('group' => $g2ID));
3924 $g3Contacts = $this->callAPISuccess('contact', 'get', array('group' => $g3ID));
3925 $this->assertTrue($g1Contacts['count'] == 1);
3926 $this->assertTrue($g2Contacts['count'] == 2);
3927 $this->assertTrue($g3Contacts['count'] == 1);
3931 * Test creating a note from the contact.create API call when only passing the note as a string.
3933 public function testCreateNoteinCreate() {
3934 $loggedInContactID = $this->createLoggedInUser();
3935 $this->_params
['note'] = "Test note created by API Call as a String";
3936 $contact = $this->callAPISuccess('Contact', 'create', $this->_params
);
3937 $note = $this->callAPISuccess('Note', 'get', ['contact_id' => $loggedInContactID]);
3938 $this->assertEquals($note['values'][$note['id']]['note'], "Test note created by API Call as a String");
3939 $note = $this->callAPISuccess('Note', 'get', ['entity_id' => $contact['id']]);
3940 $this->assertEquals($note['values'][$note['id']]['note'], "Test note created by API Call as a String");
3941 $this->callAPISuccess('Contact', 'delete', ['id' => $contact['id'], 'skip_undelete' => TRUE]);
3945 * Test Creating a note from the contact.create api call when passing the note params as an array.
3947 public function testCreateNoteinCreateArrayFormat() {
3948 $contact1 = $this->callAPISuccess('Contact', 'create', array('first_name' => 'Alan', 'last_name' => 'MouseMouse', 'contact_type' => 'Individual'));
3949 $this->_params
['note'] = [['note' => "Test note created by API Call as array", 'contact_id' => $contact1['id']]];
3950 $contact2 = $this->callAPISuccess('Contact', 'create', $this->_params
);
3951 $note = $this->callAPISuccess('Note', 'get', ['contact_id' => $contact1['id']]);
3952 $this->assertEquals($note['values'][$note['id']]['note'], "Test note created by API Call as array");
3953 $note = $this->callAPISuccess('Note', 'get', ['entity_id' => $contact2['id']]);
3954 $this->assertEquals($note['values'][$note['id']]['note'], "Test note created by API Call as array");
3958 * Verify that passing tag IDs to Contact.get works
3960 * Tests the following formats
3961 * - Contact.get tag='id1'
3962 * - Contact.get tag='id1,id2'
3963 * - Contact.get tag='id1, id2'
3965 public function testContactGetWithTag() {
3966 $contact = $this->callApiSuccess('Contact', 'create', [
3967 'contact_type' => 'Individual',
3968 'first_name' => 'Test',
3969 'last_name' => 'Tagged',
3970 'email' => 'test@example.org',
3973 foreach (['Tag A', 'Tag B'] as $name) {
3974 $tags[] = $this->callApiSuccess('Tag', 'create', [
3979 // assign contact to "Tag B"
3980 $this->callApiSuccess('EntityTag', 'create', [
3981 'entity_table' => 'civicrm_contact',
3982 'entity_id' => $contact['id'],
3983 'tag_id' => $tags[1]['id'],
3986 // test format Contact.get tag='id1'
3987 $contact_get = $this->callAPISuccess('Contact', 'get', [
3988 'tag' => $tags[1]['id'],
3991 $this->assertEquals(1, $contact_get['count']);
3992 $this->assertEquals($contact['id'], $contact_get['id']);
3993 $this->assertEquals('Tag B', $contact_get['values'][$contact['id']]['tags']);
3995 // test format Contact.get tag='id1,id2'
3996 $contact_get = $this->callAPISuccess('Contact', 'get', [
3997 'tag' => $tags[0]['id'] . ',' . $tags[1]['id'],
4000 $this->assertEquals(1, $contact_get['count']);
4001 $this->assertEquals($contact['id'], $contact_get['id']);
4002 $this->assertEquals('Tag B', $contact_get['values'][$contact['id']]['tags']);
4004 // test format Contact.get tag='id1, id2'
4005 $contact_get = $this->callAPISuccess('Contact', 'get', [
4006 'tag' => $tags[0]['id'] . ', ' . $tags[1]['id'],
4009 $this->assertEquals(1, $contact_get['count']);
4010 $this->assertEquals($contact['id'], $contact_get['id']);
4011 $this->assertEquals('Tag B', $contact_get['values'][$contact['id']]['tags']);
4013 foreach ($tags as $tag) {
4014 $this->callAPISuccess('Tag', 'delete', ['id' => $tag['id']]);
4016 $this->callAPISuccess('Contact', 'delete', [
4017 'id' => $contact['id'],
4018 'skip_undelete' => TRUE