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).
148 * @dataProvider getInternationalStrings
150 * @param string $string
151 * String to be tested.
155 public function testInternationalStrings($string) {
156 $this->callAPISuccess('Contact', 'create', array_merge(
158 array('first_name' => $string)
160 $result = $this->callAPISuccessGetSingle('Contact', array('first_name' => $string));
161 $this->assertEquals($string, $result['first_name']);
163 $organizationParams = array(
164 'organization_name' => $string,
165 'contact_type' => 'Organization',
168 $this->callAPISuccess('Contact', 'create', $organizationParams);
169 $result = $this->callAPISuccessGetSingle('Contact', $organizationParams);
170 $this->assertEquals($string, $result['organization_name']);
174 * Get international string data for testing against api calls.
176 public function getInternationalStrings() {
177 $invocations = array();
178 $invocations[] = array('Scarabée');
179 $invocations[] = array('Iñtërnâtiônàlizætiøn');
180 $invocations[] = array('これは日本語のテキストです。読めますか');
181 $invocations[] = array('देखें हिन्दी कैसी नजर आती है। अरे वाह ये तो नजर आती है।');
186 * Test civicrm_contact_create.
188 * Verify that preferred language can be set.
190 public function testAddCreateIndividualWithPreferredLanguage() {
192 'first_name' => 'abc1',
193 'contact_type' => 'Individual',
194 'last_name' => 'xyz1',
195 'preferred_language' => 'es_ES',
198 $contact = $this->callAPISuccess('contact', 'create', $params);
199 $this->getAndCheck($params, $contact['id'], 'Contact');
203 * Test civicrm_contact_create with sub-types.
205 * Verify that sub-types are created successfully and not deleted by subsequent updates.
207 public function testIndividualSubType() {
209 'first_name' => 'test abc',
210 'contact_type' => 'Individual',
211 'last_name' => 'test xyz',
212 'contact_sub_type' => array('Student', 'Staff'),
214 $contact = $this->callAPISuccess('contact', 'create', $params);
215 $cid = $contact['id'];
219 'middle_name' => 'foo',
221 $this->callAPISuccess('contact', 'create', $params);
222 unset($params['middle_name']);
224 $contact = $this->callAPISuccess('contact', 'get', $params);
226 $this->assertEquals(array('Student', 'Staff'), $contact['values'][$cid]['contact_sub_type']);
230 * Verify that we can retreive contacts of different sub types
232 public function testGetMultipleContactSubTypes() {
234 // This test presumes that there are no parents or students in the dataset
237 $student = $this->callAPISuccess('contact', 'create', array(
238 'email' => 'student@example.com',
239 'contact_type' => 'Individual',
240 'contact_sub_type' => 'Student',
244 $parent = $this->callAPISuccess('contact', 'create', array(
245 'email' => 'parent@example.com',
246 'contact_type' => 'Individual',
247 'contact_sub_type' => 'Parent',
251 $contact = $this->callAPISuccess('contact', 'create', array(
252 'email' => 'parent@example.com',
253 'contact_type' => 'Individual',
256 // get all students and parents
257 $getParams = array('contact_sub_type' => array('IN' => array('Parent', 'Student')));
258 $result = civicrm_api3('contact', 'get', $getParams);
260 // check that we retrieved the student and the parent
261 $this->assertArrayHasKey($student['id'], $result['values']);
262 $this->assertArrayHasKey($parent['id'], $result['values']);
263 $this->assertEquals(2, $result['count']);
268 * Verify that attempt to create contact with empty params fails.
270 public function testCreateEmptyContact() {
271 $this->callAPIFailure('contact', 'create', array());
275 * Verify that attempt to create contact with bad contact type fails.
277 public function testCreateBadTypeContact() {
279 'email' => 'man1@yahoo.com',
280 'contact_type' => 'Does not Exist',
282 $this->callAPIFailure('contact', 'create', $params, "'Does not Exist' is not a valid option for field contact_type");
286 * Verify that attempt to create individual contact without required fields fails.
288 public function testCreateBadRequiredFieldsIndividual() {
290 'middle_name' => 'This field is not required',
291 'contact_type' => 'Individual',
293 $this->callAPIFailure('contact', 'create', $params);
297 * Verify that attempt to create household contact without required fields fails.
299 public function testCreateBadRequiredFieldsHousehold() {
301 'middle_name' => 'This field is not required',
302 'contact_type' => 'Household',
304 $this->callAPIFailure('contact', 'create', $params);
308 * Test required field check.
310 * Verify that attempt to create organization contact without required fields fails.
312 public function testCreateBadRequiredFieldsOrganization() {
314 'middle_name' => 'This field is not required',
315 'contact_type' => 'Organization',
318 $this->callAPIFailure('contact', 'create', $params);
322 * Verify that attempt to create individual contact with only an email succeeds.
324 public function testCreateEmailIndividual() {
325 $primaryEmail = 'man3@yahoo.com';
326 $notPrimaryEmail = 'man4@yahoo.com';
328 'email' => $primaryEmail,
329 'contact_type' => 'Individual',
330 'location_type_id' => 1,
333 $contact1 = $this->callAPISuccess('contact', 'create', $params);
335 $this->assertEquals(3, $contact1['id']);
336 $email1 = $this->callAPISuccess('email', 'get', array('contact_id' => $contact1['id']));
337 $this->assertEquals(1, $email1['count']);
338 $this->assertEquals($primaryEmail, $email1['values'][$email1['id']]['email']);
340 $email2 = $this->callAPISuccess('email', 'create', array('contact_id' => $contact1['id'], 'is_primary' => 0, 'email' => $notPrimaryEmail));
342 // Case 1: Check with criteria primary 'email' => array('IS NOT NULL' => 1)
343 $result = $this->callAPISuccess('contact', 'get', array('email' => array('IS NOT NULL' => 1)));
344 $primaryEmailContactIds = array_keys($result['values']);
345 $this->assertEquals($primaryEmail, $email1['values'][$email1['id']]['email']);
347 // Case 2: Check with criteria primary 'email' => array('<>' => '')
348 $result = $this->callAPISuccess('contact', 'get', array('email' => array('<>' => '')));
349 $primaryEmailContactIds = array_keys($result['values']);
350 $this->assertEquals($primaryEmail, $email1['values'][$email1['id']]['email']);
352 // Case 3: Check with email_id='primary email id'
353 $result = $this->callAPISuccess('contact', 'get', array('email_id' => $email1['id']));
354 $this->assertEquals(1, $result['count']);
355 $this->assertEquals($contact1['id'], $result['id']);
357 $this->callAPISuccess('contact', 'delete', $contact1);
361 * Test creating individual by name.
363 * Verify create individual contact with only first and last names succeeds.
365 public function testCreateNameIndividual() {
367 'first_name' => 'abc1',
368 'contact_type' => 'Individual',
369 'last_name' => 'xyz1',
372 $this->callAPISuccess('contact', 'create', $params);
376 * Test creating individual by display_name.
378 * Display name & sort name should be set.
380 public function testCreateDisplayNameIndividual() {
382 'display_name' => 'abc1',
383 'contact_type' => 'Individual',
386 $contact = $this->callAPISuccess('contact', 'create', $params);
387 $params['sort_name'] = 'abc1';
388 $this->getAndCheck($params, $contact['id'], 'contact');
392 * Test old keys still work.
394 * Verify that attempt to create individual contact with
395 * first and last names and old key values works
397 public function testCreateNameIndividualOldKeys() {
399 'individual_prefix' => 'Dr.',
400 'first_name' => 'abc1',
401 'contact_type' => 'Individual',
402 'last_name' => 'xyz1',
403 'individual_suffix' => 'Jr.',
406 $contact = $this->callAPISuccess('contact', 'create', $params);
407 $result = $this->callAPISuccess('contact', 'getsingle', array('id' => $contact['id']));
409 $this->assertArrayKeyExists('prefix_id', $result);
410 $this->assertArrayKeyExists('suffix_id', $result);
411 $this->assertArrayKeyExists('gender_id', $result);
412 $this->assertEquals(4, $result['prefix_id']);
413 $this->assertEquals(1, $result['suffix_id']);
417 * Test preferred keys work.
419 * Verify that attempt to create individual contact with
420 * first and last names and old key values works
422 public function testCreateNameIndividualRecommendedKeys2() {
424 'prefix_id' => 'Dr.',
425 'first_name' => 'abc1',
426 'contact_type' => 'Individual',
427 'last_name' => 'xyz1',
428 'suffix_id' => 'Jr.',
429 'gender_id' => 'Male',
432 $contact = $this->callAPISuccess('contact', 'create', $params);
433 $result = $this->callAPISuccess('contact', 'getsingle', array('id' => $contact['id']));
435 $this->assertArrayKeyExists('prefix_id', $result);
436 $this->assertArrayKeyExists('suffix_id', $result);
437 $this->assertArrayKeyExists('gender_id', $result);
438 $this->assertEquals(4, $result['prefix_id']);
439 $this->assertEquals(1, $result['suffix_id']);
443 * Test household name is sufficient for create.
445 * Verify that attempt to create household contact with only
446 * household name succeeds
448 public function testCreateNameHousehold() {
450 'household_name' => 'The abc Household',
451 'contact_type' => 'Household',
453 $this->callAPISuccess('contact', 'create', $params);
457 * Test organization name is sufficient for create.
459 * Verify that attempt to create organization contact with only
460 * organization name succeeds.
462 public function testCreateNameOrganization() {
464 'organization_name' => 'The abc Organization',
465 'contact_type' => 'Organization',
467 $this->callAPISuccess('contact', 'create', $params);
471 * Verify that attempt to create organization contact without organization name fails.
473 public function testCreateNoNameOrganization() {
475 'first_name' => 'The abc Organization',
476 'contact_type' => 'Organization',
478 $this->callAPIFailure('contact', 'create', $params);
482 * Check that permissions on API key are restricted (CRM-18112).
484 public function testCreateApiKey() {
485 $config = CRM_Core_Config
::singleton();
486 $contactId = $this->individualCreate(array(
491 // Allow edit -- because permissions aren't being checked
492 $config->userPermissionClass
->permissions
= array();
493 $result = $this->callAPISuccess('Contact', 'create', array(
495 'api_key' => 'original',
497 $this->assertEquals('original', $result['values'][$contactId]['api_key']);
499 // Allow edit -- because we have adequate permission
500 $config->userPermissionClass
->permissions
= array('access CiviCRM', 'edit all contacts', 'edit api keys');
501 $result = $this->callAPISuccess('Contact', 'create', array(
502 'check_permissions' => 1,
504 'api_key' => 'abcd1234',
506 $this->assertEquals('abcd1234', $result['values'][$contactId]['api_key']);
508 // Disallow edit -- because we don't have permission
509 $config->userPermissionClass
->permissions
= array('access CiviCRM', 'edit all contacts');
510 $result = $this->callAPIFailure('Contact', 'create', array(
511 'check_permissions' => 1,
513 'api_key' => 'defg4321',
515 $this->assertRegExp(';Permission denied to modify api key;', $result['error_message']);
517 // Return everything -- because permissions are not being checked
518 $config->userPermissionClass
->permissions
= array();
519 $result = $this->callAPISuccess('Contact', 'create', array(
521 'first_name' => 'A2',
523 $this->assertEquals('A2', $result['values'][$contactId]['first_name']);
524 $this->assertEquals('B', $result['values'][$contactId]['last_name']);
525 $this->assertEquals('abcd1234', $result['values'][$contactId]['api_key']);
527 // Return everything -- because we have adequate permission
528 $config->userPermissionClass
->permissions
= array('access CiviCRM', 'edit all contacts', 'edit api keys');
529 $result = $this->callAPISuccess('Contact', 'create', array(
530 'check_permissions' => 1,
532 'first_name' => 'A3',
534 $this->assertEquals('A3', $result['values'][$contactId]['first_name']);
535 $this->assertEquals('B', $result['values'][$contactId]['last_name']);
536 $this->assertEquals('abcd1234', $result['values'][$contactId]['api_key']);
538 // Restricted return -- because we don't have permission
539 $config->userPermissionClass
->permissions
= array('access CiviCRM', 'edit all contacts');
540 $result = $this->callAPISuccess('Contact', 'create', array(
541 'check_permissions' => 1,
543 'first_name' => 'A4',
545 $this->assertEquals('A4', $result['values'][$contactId]['first_name']);
546 $this->assertEquals('B', $result['values'][$contactId]['last_name']);
547 $this->assertTrue(empty($result['values'][$contactId]['api_key']));
551 * Check with complete array + custom field.
553 * Note that the test is written on purpose without any
554 * variables specific to participant so it can be replicated into other entities
555 * and / or moved to the automated test suite
557 public function testCreateWithCustom() {
558 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__
, __FILE__
);
560 $params = $this->_params
;
561 $params['custom_' . $ids['custom_field_id']] = "custom string";
562 $description = "This demonstrates setting a custom field through the API.";
563 $result = $this->callAPIAndDocument($this->_entity
, 'create', $params, __FUNCTION__
, __FILE__
, $description);
565 $check = $this->callAPISuccess($this->_entity
, 'get', array(
566 'return.custom_' . $ids['custom_field_id'] => 1,
567 'id' => $result['id'],
569 $this->assertEquals("custom string", $check['values'][$check['id']]['custom_' . $ids['custom_field_id']]);
571 $this->customFieldDelete($ids['custom_field_id']);
572 $this->customGroupDelete($ids['custom_group_id']);
576 * CRM-12773 - expectation is that civicrm quietly ignores fields without values.
578 public function testCreateWithNULLCustomCRM12773() {
579 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__
, __FILE__
);
580 $params = $this->_params
;
581 $params['custom_' . $ids['custom_field_id']] = NULL;
582 $this->callAPISuccess('contact', 'create', $params);
583 $this->customFieldDelete($ids['custom_field_id']);
584 $this->customGroupDelete($ids['custom_group_id']);
588 * CRM-14232 test preferred language set to site default if not passed.
590 public function testCreatePreferredLanguageUnset() {
591 $this->callAPISuccess('Contact', 'create', array(
592 'first_name' => 'Snoop',
593 'last_name' => 'Dog',
594 'contact_type' => 'Individual')
596 $result = $this->callAPISuccessGetSingle('Contact', array('last_name' => 'Dog'));
597 $this->assertEquals('en_US', $result['preferred_language']);
601 * CRM-14232 test preferred language returns setting if not passed.
603 public function testCreatePreferredLanguageSet() {
604 $this->callAPISuccess('Setting', 'create', array('contact_default_language' => 'fr_FR'));
605 $this->callAPISuccess('Contact', 'create', array(
606 'first_name' => 'Snoop',
607 'last_name' => 'Dog',
608 'contact_type' => 'Individual',
610 $result = $this->callAPISuccessGetSingle('Contact', array('last_name' => 'Dog'));
611 $this->assertEquals('fr_FR', $result['preferred_language']);
615 * CRM-14232 test preferred language returns setting if not passed where setting is NULL.
617 public function testCreatePreferredLanguageNull() {
618 $this->callAPISuccess('Setting', 'create', array('contact_default_language' => 'null'));
619 $this->callAPISuccess('Contact', 'create', array(
620 'first_name' => 'Snoop',
621 'last_name' => 'Dog',
622 'contact_type' => 'Individual',
625 $result = $this->callAPISuccessGetSingle('Contact', array('last_name' => 'Dog'));
626 $this->assertEquals(NULL, $result['preferred_language']);
630 * CRM-14232 test preferred language returns setting if not passed where setting is NULL.
632 public function testCreatePreferredLanguagePassed() {
633 $this->callAPISuccess('Setting', 'create', array('contact_default_language' => 'null'));
634 $this->callAPISuccess('Contact', 'create', array(
635 'first_name' => 'Snoop',
636 'last_name' => 'Dog',
637 'contact_type' => 'Individual',
638 'preferred_language' => 'en_AU',
640 $result = $this->callAPISuccessGetSingle('Contact', array('last_name' => 'Dog'));
641 $this->assertEquals('en_AU', $result['preferred_language']);
645 * CRM-15792 - create/update datetime field for contact.
647 public function testCreateContactCustomFldDateTime() {
648 $customGroup = $this->customGroupCreate(array('extends' => 'Individual', 'title' => 'datetime_test_group'));
649 $dateTime = CRM_Utils_Date
::currentDBDate();
650 //check date custom field is saved along with time when time_format is set
652 'first_name' => 'abc3',
653 'last_name' => 'xyz3',
654 'contact_type' => 'Individual',
655 'email' => 'man3@yahoo.com',
656 'api.CustomField.create' => array(
657 'custom_group_id' => $customGroup['id'],
658 'name' => 'test_datetime',
659 'label' => 'Demo Date',
660 'html_type' => 'Select Date',
661 'data_type' => 'Date',
665 'is_searchable' => 0,
670 $result = $this->callAPISuccess('Contact', 'create', $params);
671 $customFldId = $result['values'][$result['id']]['api.CustomField.create']['id'];
672 $this->assertNotNull($result['id']);
673 $this->assertNotNull($customFldId);
676 'id' => $result['id'],
677 "custom_{$customFldId}" => $dateTime,
678 'api.CustomValue.get' => 1,
681 $result = $this->callAPISuccess('Contact', 'create', $params);
682 $this->assertNotNull($result['id']);
683 $customFldDate = date("YmdHis", strtotime($result['values'][$result['id']]['api.CustomValue.get']['values'][0]['latest']));
684 $this->assertNotNull($customFldDate);
685 $this->assertEquals($dateTime, $customFldDate);
686 $customValueId = $result['values'][$result['id']]['api.CustomValue.get']['values'][0]['id'];
687 $dateTime = date('Ymd');
688 //date custom field should not contain time part when time_format is null
690 'id' => $result['id'],
691 'api.CustomField.create' => array(
692 'id' => $customFldId,
693 'html_type' => 'Select Date',
694 'data_type' => 'Date',
697 'api.CustomValue.create' => array(
698 'id' => $customValueId,
699 'entity_id' => $result['id'],
700 "custom_{$customFldId}" => $dateTime,
702 'api.CustomValue.get' => 1,
704 $result = $this->callAPISuccess('Contact', 'create', $params);
705 $this->assertNotNull($result['id']);
706 $customFldDate = date("Ymd", strtotime($result['values'][$result['id']]['api.CustomValue.get']['values'][0]['latest']));
707 $customFldTime = date("His", strtotime($result['values'][$result['id']]['api.CustomValue.get']['values'][0]['latest']));
708 $this->assertNotNull($customFldDate);
709 $this->assertEquals($dateTime, $customFldDate);
710 $this->assertEquals(000000, $customFldTime);
711 $this->callAPISuccess('Contact', 'create', $params);
716 * Test creating a current employer through API.
718 public function testContactCreateCurrentEmployer() {
719 // Here we will just do the get for set-up purposes.
720 $count = $this->callAPISuccess('contact', 'getcount', array(
721 'organization_name' => 'new employer org',
722 'contact_type' => 'Organization',
724 $this->assertEquals(0, $count);
725 $employerResult = $this->callAPISuccess('contact', 'create', array_merge($this->_params
, array(
726 'current_employer' => 'new employer org',
729 // do it again as an update to check it doesn't cause an error
730 $employerResult = $this->callAPISuccess('contact', 'create', array_merge($this->_params
, array(
731 'current_employer' => 'new employer org',
732 'id' => $employerResult['id'],
736 $this->callAPISuccess('contact', 'getcount', array(
737 'organization_name' => 'new employer org',
738 'contact_type' => 'Organization',
742 $result = $this->callAPISuccess('contact', 'getsingle', array(
743 'id' => $employerResult['id'],
746 $this->assertEquals('new employer org', $result['current_employer']);
751 * Test creating a current employer through API.
753 * Check it will re-activate a de-activated employer
755 public function testContactCreateDuplicateCurrentEmployerEnables() {
756 // Set up - create employer relationship.
757 $employerResult = $this->callAPISuccess('contact', 'create', array_merge($this->_params
, array(
758 'current_employer' => 'new employer org',
761 $relationship = $this->callAPISuccess('relationship', 'get', array(
762 'contact_id_a' => $employerResult['id'],
765 //disable & check it is disabled
766 $this->callAPISuccess('relationship', 'create', array('id' => $relationship['id'], 'is_active' => 0));
767 $this->callAPISuccess('relationship', 'getvalue', array(
768 'id' => $relationship['id'],
769 'return' => 'is_active',
772 // Re-set the current employer - thus enabling the relationship.
773 $this->callAPISuccess('contact', 'create', array_merge($this->_params
, array(
774 'current_employer' => 'new employer org',
775 'id' => $employerResult['id'],
778 //check is_active is now 1
779 $relationship = $this->callAPISuccess('relationship', 'getsingle', array(
780 'return' => 'is_active',
782 $this->assertEquals(1, $relationship['is_active']);
786 * Check deceased contacts are not retrieved.
788 * Note at time of writing the default is to return default. This should possibly be changed & test added.
790 public function testGetDeceasedRetrieved() {
791 $this->callAPISuccess($this->_entity
, 'create', $this->_params
);
792 $c2 = $this->callAPISuccess($this->_entity
, 'create', array(
793 'first_name' => 'bb',
794 'last_name' => 'ccc',
795 'contact_type' => 'Individual',
798 $result = $this->callAPISuccess($this->_entity
, 'get', array('is_deceased' => 0));
799 $this->assertFalse(array_key_exists($c2['id'], $result['values']));
803 * Test that sort works - old syntax.
805 public function testGetSort() {
806 $c1 = $this->callAPISuccess($this->_entity
, 'create', $this->_params
);
807 $c2 = $this->callAPISuccess($this->_entity
, 'create', array(
808 'first_name' => 'bb',
809 'last_name' => 'ccc',
810 'contact_type' => 'Individual',
812 $result = $this->callAPISuccess($this->_entity
, 'get', array(
813 'sort' => 'first_name ASC',
814 'return.first_name' => 1,
817 'contact_type' => 'Individual',
820 $this->assertEquals('abc1', $result['values'][0]['first_name']);
821 $result = $this->callAPISuccess($this->_entity
, 'get', array(
822 'sort' => 'first_name DESC',
823 'return.first_name' => 1,
827 $this->assertEquals('bb', $result['values'][0]['first_name']);
829 $this->callAPISuccess($this->_entity
, 'delete', array('id' => $c1['id']));
830 $this->callAPISuccess($this->_entity
, 'delete', array('id' => $c2['id']));
834 * Test that we can retrieve contacts using array syntax.
836 * I.e 'id' => array('IN' => array('3,4')).
838 public function testGetINIDArray() {
839 $c1 = $this->callAPISuccess($this->_entity
, 'create', $this->_params
);
840 $c2 = $this->callAPISuccess($this->_entity
, 'create', array(
841 'first_name' => 'bb',
842 'last_name' => 'ccc',
843 'contact_type' => 'Individual',
845 $c3 = $this->callAPISuccess($this->_entity
, 'create', array(
846 'first_name' => 'hh',
848 'contact_type' => 'Individual',
850 $result = $this->callAPISuccess($this->_entity
, 'get', array('id' => array('IN' => array($c1['id'], $c3['id']))));
851 $this->assertEquals(2, $result['count']);
852 $this->assertEquals(array($c1['id'], $c3['id']), array_keys($result['values']));
853 $this->callAPISuccess($this->_entity
, 'delete', array('id' => $c1['id']));
854 $this->callAPISuccess($this->_entity
, 'delete', array('id' => $c2['id']));
855 $this->callAPISuccess($this->_entity
, 'delete', array('id' => $c3['id']));
859 * Test variants on deleted behaviour.
861 public function testGetDeleted() {
862 $params = $this->_params
;
863 $contact1 = $this->callAPISuccess('contact', 'create', $params);
864 $params['is_deleted'] = 1;
865 $params['last_name'] = 'bcd';
866 $contact2 = $this->callAPISuccess('contact', 'create', $params);
867 $countActive = $this->callAPISuccess('contact', 'getcount', array(
868 'showAll' => 'active',
869 'contact_type' => 'Individual',
871 $countAll = $this->callAPISuccess('contact', 'getcount', array('showAll' => 'all', 'contact_type' => 'Individual'));
872 $countTrash = $this->callAPISuccess('contact', 'getcount', array('showAll' => 'trash', 'contact_type' => 'Individual'));
873 $countDefault = $this->callAPISuccess('contact', 'getcount', array('contact_type' => 'Individual'));
874 $countDeleted = $this->callAPISuccess('contact', 'getcount', array(
875 'contact_type' => 'Individual',
876 'contact_is_deleted' => 1,
878 $countNotDeleted = $this->callAPISuccess('contact', 'getcount', array(
879 'contact_is_deleted' => 0,
880 'contact_type' => 'Individual',
882 $this->callAPISuccess('contact', 'delete', array('id' => $contact1['id']));
883 $this->callAPISuccess('contact', 'delete', array('id' => $contact2['id']));
884 $this->assertEquals(1, $countNotDeleted, 'contact_is_deleted => 0 is respected');
885 $this->assertEquals(1, $countActive);
886 $this->assertEquals(1, $countTrash);
887 $this->assertEquals(2, $countAll);
888 $this->assertEquals(1, $countDeleted);
889 $this->assertEquals(1, $countDefault, 'Only active by default in line');
893 * Test that sort works - new syntax.
895 public function testGetSortNewSyntax() {
896 $c1 = $this->callAPISuccess($this->_entity
, 'create', $this->_params
);
897 $c2 = $this->callAPISuccess($this->_entity
, 'create', array(
898 'first_name' => 'bb',
899 'last_name' => 'ccc',
900 'contact_type' => 'Individual',
902 $result = $this->callAPISuccess($this->_entity
, 'getvalue', array(
903 'return' => 'first_name',
904 'contact_type' => 'Individual',
907 'sort' => 'first_name',
910 $this->assertEquals('abc1', $result);
912 $result = $this->callAPISuccess($this->_entity
, 'getvalue', array(
913 'return' => 'first_name',
914 'contact_type' => 'Individual',
917 'sort' => 'first_name DESC',
920 $this->assertEquals('bb', $result);
922 $this->callAPISuccess($this->_entity
, 'delete', array('id' => $c1['id']));
923 $this->callAPISuccess($this->_entity
, 'delete', array('id' => $c2['id']));
927 * Test sort and limit for chained relationship get.
929 * https://issues.civicrm.org/jira/browse/CRM-15983
931 public function testSortLimitChainedRelationshipGetCRM15983() {
933 $create_result_1 = $this->callAPISuccess('contact', 'create', array(
934 'first_name' => 'Jules',
935 'last_name' => 'Smos',
936 'contact_type' => 'Individual',
939 // Create another contact with two relationships.
940 $create_params = array(
941 'first_name' => 'Jos',
942 'last_name' => 'Smos',
943 'contact_type' => 'Individual',
944 'api.relationship.create' => array(
946 'contact_id_a' => '$value.id',
947 'contact_id_b' => $create_result_1['id'],
949 'relationship_type_id' => 2,
950 'start_date' => '2005-01-12',
951 'end_date' => '2006-01-11',
952 'description' => 'old',
955 'contact_id_a' => '$value.id',
956 'contact_id_b' => $create_result_1['id'],
957 // spouse of (was married twice :))
958 'relationship_type_id' => 2,
959 'start_date' => '2006-07-01',
960 'end_date' => '2010-07-01',
961 'description' => 'new',
965 $create_result = $this->callAPISuccess('contact', 'create', $create_params);
967 // Try to retrieve the contact and the most recent relationship.
970 'id' => $create_result['id'],
971 'api.relationship.get' => array(
972 'contact_id_a' => '$value.id',
975 'sort' => 'start_date DESC',
978 $get_result = $this->callAPISuccess('contact', 'getsingle', $get_params);
981 $this->callAPISuccess('contact', 'delete', array(
982 'id' => $create_result['id'],
986 $this->assertEquals(1, $get_result['api.relationship.get']['count']);
987 $this->assertEquals('new', $get_result['api.relationship.get']['values'][0]['description']);
991 * Test apostrophe works in get & create.
993 public function testGetApostropheCRM10857() {
994 $params = array_merge($this->_params
, array('last_name' => "O'Connor"));
995 $this->callAPISuccess($this->_entity
, 'create', $params);
996 $result = $this->callAPISuccess($this->_entity
, 'getsingle', array(
997 'last_name' => "O'Connor",
1000 $this->assertEquals("O'Connor", $result['last_name'], 'in line' . __LINE__
);
1004 * Test retrieval by addressee id.
1006 public function testGetByAddresseeID() {
1007 $individual1ID = $this->individualCreate([
1008 'skip_greeting_processing' => 1,
1009 'addressee_id' => 'null',
1010 'email_greeting_id' => 'null',
1011 'postal_greeting_id' => 'null'
1013 $individual2ID = $this->individualCreate();
1015 $this->assertEquals($individual1ID,
1016 $this->callAPISuccessGetValue('Contact', ['contact_type' => 'Individual', 'addressee_id' => ['IS NULL' => 1], 'return' => 'id'])
1018 $this->assertEquals($individual1ID,
1019 $this->callAPISuccessGetValue('Contact', ['contact_type' => 'Individual', 'email_greeting_id' => ['IS NULL' => 1], 'return' => 'id'])
1021 $this->assertEquals($individual1ID,
1022 $this->callAPISuccessGetValue('Contact', ['contact_type' => 'Individual', 'postal_greeting_id' => ['IS NULL' => 1], 'return' => 'id'])
1025 $this->assertEquals($individual2ID,
1026 $this->callAPISuccessGetValue('Contact', ['contact_type' => 'Individual', 'addressee_id' => ['NOT NULL' => 1], 'return' => 'id'])
1031 * Check with complete array + custom field.
1033 * Note that the test is written on purpose without any
1034 * variables specific to participant so it can be replicated into other entities
1035 * and / or moved to the automated test suite
1037 public function testGetWithCustom() {
1038 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__
, __FILE__
);
1040 $params = $this->_params
;
1041 $params['custom_' . $ids['custom_field_id']] = "custom string";
1042 $description = "This demonstrates setting a custom field through the API.";
1043 $subfile = "CustomFieldGet";
1044 $result = $this->callAPISuccess($this->_entity
, 'create', $params);
1046 $check = $this->callAPIAndDocument($this->_entity
, 'get', array(
1047 'return.custom_' . $ids['custom_field_id'] => 1,
1048 'id' => $result['id'],
1049 ), __FUNCTION__
, __FILE__
, $description, $subfile);
1051 $this->assertEquals("custom string", $check['values'][$check['id']]['custom_' . $ids['custom_field_id']]);
1052 $fields = ($this->callAPISuccess('contact', 'getfields', $params));
1053 $this->assertTrue(is_array($fields['values']['custom_' . $ids['custom_field_id']]));
1054 $this->customFieldDelete($ids['custom_field_id']);
1055 $this->customGroupDelete($ids['custom_group_id']);
1059 * Check with complete array + custom field.
1061 * Note that the test is written on purpose without any
1062 * variables specific to participant so it can be replicated into other entities
1063 * and / or moved to the automated test suite
1065 public function testGetWithCustomReturnSyntax() {
1066 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__
, __FILE__
);
1068 $params = $this->_params
;
1069 $params['custom_' . $ids['custom_field_id']] = "custom string";
1070 $description = "This demonstrates setting a custom field through the API.";
1071 $subfile = "CustomFieldGetReturnSyntaxVariation";
1072 $result = $this->callAPISuccess($this->_entity
, 'create', $params);
1073 $params = array('return' => 'custom_' . $ids['custom_field_id'], 'id' => $result['id']);
1074 $check = $this->callAPIAndDocument($this->_entity
, 'get', $params, __FUNCTION__
, __FILE__
, $description, $subfile);
1076 $this->assertEquals("custom string", $check['values'][$check['id']]['custom_' . $ids['custom_field_id']]);
1077 $this->customFieldDelete($ids['custom_field_id']);
1078 $this->customGroupDelete($ids['custom_group_id']);
1082 * Check that address name, ID is returned if required.
1084 public function testGetReturnAddress() {
1085 $contactID = $this->individualCreate();
1086 $result = $this->callAPISuccess('address', 'create', array(
1087 'contact_id' => $contactID,
1088 'address_name' => 'My house',
1089 'location_type_id' => 'Home',
1090 'street_address' => '1 my road',
1092 $addressID = $result['id'];
1094 $result = $this->callAPISuccessGetSingle('contact', array(
1095 'return' => 'address_name, street_address, address_id',
1098 $this->assertEquals($addressID, $result['address_id']);
1099 $this->assertEquals('1 my road', $result['street_address']);
1100 $this->assertEquals('My house', $result['address_name']);
1105 * Test group filter syntaxes.
1107 public function testGetGroupIDFromContact() {
1108 $groupId = $this->groupCreate();
1110 'email' => 'man2@yahoo.com',
1111 'contact_type' => 'Individual',
1112 'location_type_id' => 1,
1113 'api.group_contact.create' => array('group_id' => $groupId),
1116 $this->callAPISuccess('contact', 'create', $params);
1117 // testing as integer
1119 'filter.group_id' => $groupId,
1120 'contact_type' => 'Individual',
1122 $result = $this->callAPISuccess('contact', 'get', $params);
1123 $this->assertEquals(1, $result['count']);
1124 // group 26 doesn't exist, but we can still search contacts in it.
1126 'filter.group_id' => 26,
1127 'contact_type' => 'Individual',
1129 $this->callAPISuccess('contact', 'get', $params);
1130 // testing as string
1132 'filter.group_id' => "$groupId, 26",
1133 'contact_type' => 'Individual',
1135 $result = $this->callAPISuccess('contact', 'get', $params);
1136 $this->assertEquals(1, $result['count']);
1138 'filter.group_id' => "26,27",
1139 'contact_type' => 'Individual',
1141 $this->callAPISuccess('contact', 'get', $params);
1143 // testing as string
1145 'filter.group_id' => array($groupId, 26),
1146 'contact_type' => 'Individual',
1148 $result = $this->callAPISuccess('contact', 'get', $params);
1149 $this->assertEquals(1, $result['count']);
1151 //test in conjunction with other criteria
1153 'filter.group_id' => array($groupId, 26),
1154 'contact_type' => 'Organization',
1156 $this->callAPISuccess('contact', 'get', $params);
1158 'filter.group_id' => array(26, 27),
1159 'contact_type' => 'Individual',
1161 $result = $this->callAPISuccess('contact', 'get', $params);
1162 $this->assertEquals(0, $result['count']);
1166 * Verify that attempt to create individual contact with two chained websites succeeds.
1168 public function testCreateIndividualWithContributionDottedSyntax() {
1169 $description = "This demonstrates the syntax to create 2 chained entities.";
1170 $subFile = "ChainTwoWebsites";
1172 'first_name' => 'abc3',
1173 'last_name' => 'xyz3',
1174 'contact_type' => 'Individual',
1175 'email' => 'man3@yahoo.com',
1176 'api.contribution.create' => array(
1177 'receive_date' => '2010-01-01',
1178 'total_amount' => 100.00,
1179 'financial_type_id' => $this->_financialTypeId
,
1180 'payment_instrument_id' => 1,
1181 'non_deductible_amount' => 10.00,
1182 'fee_amount' => 50.00,
1183 'net_amount' => 90.00,
1185 'invoice_id' => 67990,
1187 'contribution_status_id' => 1,
1188 'skipCleanMoney' => 1,
1190 'api.website.create' => array(
1191 'url' => "http://civicrm.org",
1193 'api.website.create.2' => array(
1194 'url' => "http://chained.org",
1198 $result = $this->callAPIAndDocument('Contact', 'create', $params, __FUNCTION__
, __FILE__
, $description, $subFile);
1200 // checking child function result not covered in callAPIAndDocument
1201 $this->assertAPISuccess($result['values'][$result['id']]['api.website.create']);
1202 $this->assertEquals("http://chained.org", $result['values'][$result['id']]['api.website.create.2']['values'][0]['url']);
1203 $this->assertEquals("http://civicrm.org", $result['values'][$result['id']]['api.website.create']['values'][0]['url']);
1205 // delete the contact
1206 $this->callAPISuccess('contact', 'delete', $result);
1210 * Verify that attempt to create individual contact with chained contribution and website succeeds.
1212 public function testCreateIndividualWithContributionChainedArrays() {
1214 'first_name' => 'abc3',
1215 'last_name' => 'xyz3',
1216 'contact_type' => 'Individual',
1217 'email' => 'man3@yahoo.com',
1218 'api.contribution.create' => array(
1219 'receive_date' => '2010-01-01',
1220 'total_amount' => 100.00,
1221 'financial_type_id' => $this->_financialTypeId
,
1222 'payment_instrument_id' => 1,
1223 'non_deductible_amount' => 10.00,
1224 'fee_amount' => 50.00,
1225 'net_amount' => 90.00,
1227 'invoice_id' => 67890,
1229 'contribution_status_id' => 1,
1230 'skipCleanMoney' => 1,
1232 'api.website.create' => array(
1234 'url' => "http://civicrm.org",
1237 'url' => "http://chained.org",
1238 'website_type_id' => 2,
1243 $description = "Demonstrates creating two websites as an array.";
1244 $subfile = "ChainTwoWebsitesSyntax2";
1245 $result = $this->callAPIAndDocument('Contact', 'create', $params, __FUNCTION__
, __FILE__
, $description, $subfile);
1247 // the callAndDocument doesn't check the chained call
1248 $this->assertEquals(0, $result['values'][$result['id']]['api.website.create'][0]['is_error']);
1249 $this->assertEquals("http://chained.org", $result['values'][$result['id']]['api.website.create'][1]['values'][0]['url']);
1250 $this->assertEquals("http://civicrm.org", $result['values'][$result['id']]['api.website.create'][0]['values'][0]['url']);
1252 $this->callAPISuccess('contact', 'delete', $result);
1256 * Test for direction when chaining relationships.
1258 * https://issues.civicrm.org/jira/browse/CRM-16084
1260 public function testDirectionChainingRelationshipsCRM16084() {
1261 // Some contact, called Jules.
1262 $create_result_1 = $this->callAPISuccess('contact', 'create', array(
1263 'first_name' => 'Jules',
1264 'last_name' => 'Smos',
1265 'contact_type' => 'Individual',
1268 // Another contact: Jos, child of Jules.
1269 $create_params = array(
1270 'first_name' => 'Jos',
1271 'last_name' => 'Smos',
1272 'contact_type' => 'Individual',
1273 'api.relationship.create' => array(
1275 'contact_id_a' => '$value.id',
1276 'contact_id_b' => $create_result_1['id'],
1278 'relationship_type_id' => 1,
1282 $create_result_2 = $this->callAPISuccess('contact', 'create', $create_params);
1284 // Mia is the child of Jos.
1285 $create_params = array(
1286 'first_name' => 'Mia',
1287 'last_name' => 'Smos',
1288 'contact_type' => 'Individual',
1289 'api.relationship.create' => array(
1291 'contact_id_a' => '$value.id',
1292 'contact_id_b' => $create_result_2['id'],
1294 'relationship_type_id' => 1,
1298 $create_result_3 = $this->callAPISuccess('contact', 'create', $create_params);
1300 // Get Jos and his children.
1301 $get_params = array(
1303 'id' => $create_result_2['id'],
1304 'api.relationship.get' => array(
1305 'contact_id_b' => '$value.id',
1306 'relationship_type_id' => 1,
1309 $get_result = $this->callAPISuccess('contact', 'getsingle', $get_params);
1312 $this->callAPISuccess('contact', 'delete', array(
1313 'id' => $create_result_1['id'],
1315 $this->callAPISuccess('contact', 'delete', array(
1316 'id' => $create_result_2['id'],
1318 $this->callAPISuccess('contact', 'delete', array(
1319 'id' => $create_result_2['id'],
1323 $this->assertEquals(1, $get_result['api.relationship.get']['count']);
1324 $this->assertEquals($create_result_3['id'], $get_result['api.relationship.get']['values'][0]['contact_id_a']);
1328 * Verify that attempt to create individual contact with first, and last names and email succeeds.
1330 public function testCreateIndividualWithNameEmail() {
1332 'first_name' => 'abc3',
1333 'last_name' => 'xyz3',
1334 'contact_type' => 'Individual',
1335 'email' => 'man3@yahoo.com',
1338 $contact = $this->callAPISuccess('contact', 'create', $params);
1340 $this->callAPISuccess('contact', 'delete', $contact);
1344 * Verify that attempt to create individual contact with no data fails.
1346 public function testCreateIndividualWithOutNameEmail() {
1348 'contact_type' => 'Individual',
1350 $this->callAPIFailure('contact', 'create', $params);
1354 * Test create individual contact with first &last names, email and location type succeeds.
1356 public function testCreateIndividualWithNameEmailLocationType() {
1358 'first_name' => 'abc4',
1359 'last_name' => 'xyz4',
1360 'email' => 'man4@yahoo.com',
1361 'contact_type' => 'Individual',
1362 'location_type_id' => 1,
1364 $result = $this->callAPISuccess('contact', 'create', $params);
1366 $this->callAPISuccess('contact', 'delete', array('id' => $result['id']));
1370 * Verify that when changing employers the old employer relationship becomes inactive.
1372 public function testCreateIndividualWithEmployer() {
1373 $employer = $this->organizationCreate();
1374 $employer2 = $this->organizationCreate();
1377 'email' => 'man4@yahoo.com',
1378 'contact_type' => 'Individual',
1379 'employer_id' => $employer,
1382 $result = $this->callAPISuccess('contact', 'create', $params);
1383 $relationships = $this->callAPISuccess('relationship', 'get', array(
1384 'contact_id_a' => $result['id'],
1388 $this->assertEquals($employer, $relationships['values'][0]['contact_id_b']);
1390 // Add more random relationships to make the test more realistic
1391 foreach (array('Employee of', 'Volunteer for') as $relationshipType) {
1392 $relTypeId = CRM_Core_DAO
::getFieldValue('CRM_Contact_DAO_RelationshipType', $relationshipType, 'id', 'name_a_b');
1393 $this->callAPISuccess('relationship', 'create', array(
1394 'contact_id_a' => $result['id'],
1395 'contact_id_b' => $this->organizationCreate(),
1397 'relationship_type_id' => $relTypeId,
1401 // Add second employer
1402 $params['employer_id'] = $employer2;
1403 $params['id'] = $result['id'];
1404 $result = $this->callAPISuccess('contact', 'create', $params);
1406 $relationships = $this->callAPISuccess('relationship', 'get', array(
1407 'contact_id_a' => $result['id'],
1412 $this->assertEquals($employer, $relationships['values'][0]['contact_id_b']);
1416 * Verify that attempt to create household contact with details succeeds.
1418 public function testCreateHouseholdDetails() {
1420 'household_name' => 'abc8\'s House',
1421 'nick_name' => 'x House',
1422 'email' => 'man8@yahoo.com',
1423 'contact_type' => 'Household',
1426 $contact = $this->callAPISuccess('contact', 'create', $params);
1428 $this->callAPISuccess('contact', 'delete', $contact);
1432 * Verify that attempt to create household contact with inadequate details fails.
1434 public function testCreateHouseholdInadequateDetails() {
1436 'nick_name' => 'x House',
1437 'email' => 'man8@yahoo.com',
1438 'contact_type' => 'Household',
1440 $this->callAPIFailure('contact', 'create', $params);
1444 * Verify successful update of individual contact.
1446 public function testUpdateIndividualWithAll() {
1447 // Insert a row in civicrm_contact creating individual contact.
1448 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1449 $op->execute($this->_dbconn
,
1450 $this->createXMLDataSet(
1451 dirname(__FILE__
) . '/dataset/contact_ind.xml'
1457 'first_name' => 'abcd',
1458 'contact_type' => 'Individual',
1459 'nick_name' => 'This is nickname first',
1460 'do_not_email' => '1',
1461 'do_not_phone' => '1',
1462 'do_not_mail' => '1',
1463 'do_not_trade' => '1',
1464 'legal_identifier' => 'ABC23853ZZ2235',
1465 'external_identifier' => '1928837465',
1466 'image_URL' => 'http://some.url.com/image.jpg',
1467 'home_url' => 'http://www.example.org',
1471 $this->callAPISuccess('Contact', 'Update', $params);
1472 $getResult = $this->callAPISuccess('Contact', 'Get', $params);
1473 unset($params['contact_id']);
1474 //Todo - neither API v2 or V3 are testing for home_url - not sure if it is being set.
1475 //reducing this test partially back to api v2 level to get it through
1476 unset($params['home_url']);
1477 foreach ($params as $key => $value) {
1478 $this->assertEquals($value, $getResult['values'][23][$key]);
1480 // Check updated civicrm_contact against expected.
1481 $expected = $this->createXMLDataSet(
1482 dirname(__FILE__
) . '/dataset/contact_ind_upd.xml'
1484 $actual = new PHPUnit_Extensions_Database_DataSet_QueryDataSet(
1487 $actual->addTable('civicrm_contact');
1488 $expected->matches($actual);
1492 * Verify successful update of organization contact.
1494 public function testUpdateOrganizationWithAll() {
1495 // Insert a row in civicrm_contact creating organization contact
1496 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1497 $op->execute($this->_dbconn
,
1498 $this->createXMLDataSet(
1499 dirname(__FILE__
) . '/dataset/contact_org.xml'
1505 'organization_name' => 'WebAccess India Pvt Ltd',
1506 'legal_name' => 'WebAccess',
1507 'sic_code' => 'ABC12DEF',
1508 'contact_type' => 'Organization',
1511 $this->callAPISuccess('Contact', 'Update', $params);
1513 // Check updated civicrm_contact against expected.
1514 $expected = $this->createXMLDataSet(
1515 dirname(__FILE__
) . '/dataset/contact_org_upd.xml'
1517 $actual = new PHPUnit_Extensions_Database_DataSet_QueryDataSet(
1520 $actual->addTable('civicrm_contact');
1521 $expected->matches($actual);
1525 * Test merging 2 organizations.
1527 * CRM-20421: This test make sure that inherited memberships are deleted upon merging organization.
1529 public function testMergeOrganizations() {
1530 $organizationID1 = $this->organizationCreate(array(), 0);
1531 $organizationID2 = $this->organizationCreate(array(), 1);
1532 $contact = $this->callAPISuccess('contact', 'create', array_merge($this->_params
, array(
1533 'employer_id' => $organizationID1,
1536 $contact = $contact["values"][$contact["id"]];
1538 $membershipType = $this->createEmployerOfMembership();
1539 $membershipParams = array(
1540 'membership_type_id' => $membershipType["id"],
1541 'contact_id' => $organizationID1,
1542 'start_date' => "01/01/2015",
1543 'join_date' => "01/01/2010",
1544 'end_date' => "12/31/2015",
1546 $ownermembershipid = $this->contactMembershipCreate($membershipParams);
1548 $contactmembership = $this->callAPISuccess("membership", "getsingle", array(
1549 "contact_id" => $contact["id"],
1552 $this->assertEquals($ownermembershipid, $contactmembership["owner_membership_id"], "Contact membership must be inherited from Organization");
1554 CRM_Dedupe_Merger
::moveAllBelongings($organizationID2, $organizationID1, array(
1555 "move_rel_table_memberships" => "0",
1556 "move_rel_table_relationships" => "1",
1557 "main_details" => array(
1558 "contact_id" => $organizationID2,
1559 "contact_type" => "Organization",
1561 "other_details" => array(
1562 "contact_id" => $organizationID1,
1563 "contact_type" => "Organization",
1567 $contactmembership = $this->callAPISuccess("membership", "get", array(
1568 "contact_id" => $contact["id"],
1571 $this->assertEquals(0, $contactmembership["count"], "Contact membership must be deleted after merging organization without memberships.");
1574 private function createEmployerOfMembership() {
1576 'domain_id' => CRM_Core_Config
::domainID(),
1577 'name' => 'Organization Membership',
1578 'description' => NULL,
1579 'member_of_contact_id' => 1,
1580 'financial_type_id' => 1,
1581 'minimum_fee' => 10,
1582 'duration_unit' => 'year',
1583 'duration_interval' => 1,
1584 'period_type' => 'rolling',
1585 'relationship_type_id' => 5,
1586 'relationship_direction' => 'b_a',
1587 'visibility' => 'Public',
1590 $membershipType = $this->callAPISuccess('membership_type', 'create', $params);
1591 return $membershipType["values"][$membershipType["id"]];
1595 * Verify successful update of household contact.
1597 public function testUpdateHouseholdWithAll() {
1598 // Insert a row in civicrm_contact creating household contact
1599 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1600 $op->execute($this->_dbconn
,
1601 $this->createXMLDataSet(
1602 dirname(__FILE__
) . '/dataset/contact_hld.xml'
1608 'household_name' => 'ABC household',
1609 'nick_name' => 'ABC House',
1610 'contact_type' => 'Household',
1613 $result = $this->callAPISuccess('Contact', 'Update', $params);
1616 'contact_type' => 'Household',
1618 'sort_name' => 'ABC household',
1619 'display_name' => 'ABC household',
1620 'nick_name' => 'ABC House',
1622 $this->getAndCheck($expected, $result['id'], 'contact');
1626 * Test civicrm_update() without contact type.
1628 * Deliberately exclude contact_type as it should still cope using civicrm_api.
1632 public function testUpdateCreateWithID() {
1633 // Insert a row in civicrm_contact creating individual contact.
1634 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1635 $op->execute($this->_dbconn
,
1636 $this->createXMLDataSet(
1637 dirname(__FILE__
) . '/dataset/contact_ind.xml'
1643 'first_name' => 'abcd',
1644 'last_name' => 'wxyz',
1646 $this->callAPISuccess('Contact', 'Update', $params);
1650 * Test civicrm_contact_delete() with no contact ID.
1652 public function testContactDeleteNoID() {
1656 $this->callAPIFailure('contact', 'delete', $params);
1660 * Test civicrm_contact_delete() with error.
1662 public function testContactDeleteError() {
1663 $params = array('contact_id' => 999);
1664 $this->callAPIFailure('contact', 'delete', $params);
1668 * Test civicrm_contact_delete().
1670 public function testContactDelete() {
1671 $contactID = $this->individualCreate();
1675 $this->callAPIAndDocument('contact', 'delete', $params, __FUNCTION__
, __FILE__
);
1679 * Test civicrm_contact_get() return only first name.
1681 public function testContactGetRetFirst() {
1682 $contact = $this->callAPISuccess('contact', 'create', $this->_params
);
1684 'contact_id' => $contact['id'],
1685 'return_first_name' => TRUE,
1686 'sort' => 'first_name',
1688 $result = $this->callAPISuccess('contact', 'get', $params);
1689 $this->assertEquals(1, $result['count']);
1690 $this->assertEquals($contact['id'], $result['id']);
1691 $this->assertEquals('abc1', $result['values'][$contact['id']]['first_name']);
1695 * Test civicrm_contact_get() return only first name & last name.
1697 * Use comma separated string return with a space.
1699 public function testContactGetReturnFirstLast() {
1700 $contact = $this->callAPISuccess('contact', 'create', $this->_params
);
1702 'contact_id' => $contact['id'],
1703 'return' => 'first_name, last_name',
1705 $result = $this->callAPISuccess('contact', 'getsingle', $params);
1706 $this->assertEquals('abc1', $result['first_name']);
1707 $this->assertEquals('xyz1', $result['last_name']);
1708 //check that other defaults not returns
1709 $this->assertArrayNotHasKey('sort_name', $result);
1711 'contact_id' => $contact['id'],
1712 'return' => 'first_name,last_name',
1714 $result = $this->callAPISuccess('contact', 'getsingle', $params);
1715 $this->assertEquals('abc1', $result['first_name']);
1716 $this->assertEquals('xyz1', $result['last_name']);
1717 //check that other defaults not returns
1718 $this->assertArrayNotHasKey('sort_name', $result);
1722 * Test civicrm_contact_get() return only first name & last name.
1724 * Use comma separated string return without a space
1726 public function testContactGetReturnFirstLastNoComma() {
1727 $contact = $this->callAPISuccess('contact', 'create', $this->_params
);
1729 'contact_id' => $contact['id'],
1730 'return' => 'first_name,last_name',
1732 $result = $this->callAPISuccess('contact', 'getsingle', $params);
1733 $this->assertEquals('abc1', $result['first_name']);
1734 $this->assertEquals('xyz1', $result['last_name']);
1735 //check that other defaults not returns
1736 $this->assertArrayNotHasKey('sort_name', $result);
1740 * Test civicrm_contact_get() with default return properties.
1742 public function testContactGetRetDefault() {
1743 $contactID = $this->individualCreate();
1745 'contact_id' => $contactID,
1746 'sort' => 'first_name',
1748 $result = $this->callAPISuccess('contact', 'get', $params);
1749 $this->assertEquals($contactID, $result['values'][$contactID]['contact_id']);
1750 $this->assertEquals('Anthony', $result['values'][$contactID]['first_name']);
1754 * Test civicrm_contact_getquick() with empty name param.
1756 public function testContactGetQuick() {
1757 // Insert a row in civicrm_contact creating individual contact.
1758 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1759 $op->execute($this->_dbconn
,
1760 $this->createXMLDataSet(
1761 dirname(__FILE__
) . '/dataset/contact_17.xml'
1764 $op->execute($this->_dbconn
,
1765 $this->createXMLDataSet(
1766 dirname(__FILE__
) . '/dataset/email_contact_17.xml'
1773 $result = $this->callAPISuccess('contact', 'getquick', $params);
1774 $this->assertEquals(17, $result['values'][0]['id']);
1778 * Test civicrm_contact_get) with empty params.
1780 public function testContactGetEmptyParams() {
1781 $this->callAPISuccess('contact', 'get', array());
1785 * Test civicrm_contact_get(,true) with no matches.
1787 public function testContactGetOldParamsNoMatches() {
1788 // Insert a row in civicrm_contact creating contact 17.
1789 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1790 $op->execute($this->_dbconn
,
1791 $this->createXMLDataSet(
1792 dirname(__FILE__
) . '/dataset/contact_17.xml'
1797 'first_name' => 'Fred',
1799 $result = $this->callAPISuccess('contact', 'get', $params);
1800 $this->assertEquals(0, $result['count']);
1804 * Test civicrm_contact_get(,true) with one match.
1806 public function testContactGetOldParamsOneMatch() {
1807 // Insert a row in civicrm_contact creating contact 17
1808 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1809 $op->execute($this->_dbconn
,
1810 $this->createXMLDataSet(dirname(__FILE__
) . '/dataset/contact_17.xml'
1815 'first_name' => 'Test',
1817 $result = $this->callAPISuccess('contact', 'get', $params);
1818 $this->assertEquals(17, $result['values'][17]['contact_id']);
1819 $this->assertEquals(17, $result['id']);
1823 * Test civicrm_contact_search_count().
1825 public function testContactGetEmail() {
1827 'email' => 'man2@yahoo.com',
1828 'contact_type' => 'Individual',
1829 'location_type_id' => 1,
1832 $contact = $this->callAPISuccess('contact', 'create', $params);
1835 'email' => 'man2@yahoo.com',
1837 $result = $this->callAPIAndDocument('contact', 'get', $params, __FUNCTION__
, __FILE__
);
1838 $this->assertEquals('man2@yahoo.com', $result['values'][$result['id']]['email']);
1840 $this->callAPISuccess('contact', 'delete', $contact);
1844 * Ensure consistent return format for option group fields.
1846 public function testSetPreferredCommunicationNull() {
1847 $contact = $this->callAPISuccess('contact', 'create', array_merge($this->_params
, array(
1848 'preferred_communication_method' => array('Phone', 'SMS'),
1850 $preferredCommunicationMethod = $this->callAPISuccessGetValue('Contact', array(
1851 'id' => $contact['id'],
1852 'return' => 'preferred_communication_method',
1854 $this->assertNotEmpty($preferredCommunicationMethod);
1855 $contact = $this->callAPISuccess('contact', 'create', array_merge($this->_params
, array(
1856 'preferred_communication_method' => 'null',
1857 'id' => $contact['id'],
1859 $preferredCommunicationMethod = $this->callAPISuccessGetValue('Contact', array(
1860 'id' => $contact['id'],
1861 'return' => 'preferred_communication_method',
1863 $this->assertEmpty($preferredCommunicationMethod);
1867 * Ensure consistent return format for option group fields.
1869 public function testPseudoFields() {
1871 'preferred_communication_method' => array('Phone', 'SMS'),
1872 'preferred_language' => 'en_US',
1873 'gender_id' => 'Female',
1874 'prefix_id' => 'Mrs.',
1875 'suffix_id' => 'II',
1876 'communication_style_id' => 'Formal',
1879 $contact = $this->callAPISuccess('contact', 'create', array_merge($this->_params
, $params));
1881 $result = $this->callAPISuccess('contact', 'getsingle', array('id' => $contact['id']));
1882 $this->assertEquals('Both', $result['preferred_mail_format']);
1884 $this->assertEquals('en_US', $result['preferred_language']);
1885 $this->assertEquals(1, $result['communication_style_id']);
1886 $this->assertEquals(1, $result['gender_id']);
1887 $this->assertEquals('Female', $result['gender']);
1888 $this->assertEquals('Mrs.', $result['individual_prefix']);
1889 $this->assertEquals(1, $result['prefix_id']);
1890 $this->assertEquals('II', $result['individual_suffix']);
1891 $this->assertEquals(CRM_Core_PseudoConstant
::getKey("CRM_Contact_BAO_Contact", 'suffix_id', 'II'), $result['suffix_id']);
1892 $this->callAPISuccess('contact', 'delete', $contact);
1893 $this->assertEquals(array(
1894 CRM_Core_PseudoConstant
::getKey("CRM_Contact_BAO_Contact", 'preferred_communication_method', 'Phone'),
1895 CRM_Core_PseudoConstant
::getKey("CRM_Contact_BAO_Contact", 'preferred_communication_method', 'SMS'),
1896 ), $result['preferred_communication_method']);
1901 * Test birth date parameters.
1903 * These include value, array & birth_date_high, birth_date_low
1906 public function testContactGetBirthDate() {
1907 $contact1 = $this->callAPISuccess('contact', 'create', array_merge($this->_params
, array('birth_date' => 'first day of next month - 2 years')));
1908 $contact2 = $this->callAPISuccess('contact', 'create', array_merge($this->_params
, array('birth_date' => 'first day of next month - 5 years')));
1909 $contact3 = $this->callAPISuccess('contact', 'create', array_merge($this->_params
, array('birth_date' => 'first day of next month -20 years')));
1911 $result = $this->callAPISuccess('contact', 'get', array());
1912 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -2 years')), $result['values'][$contact1['id']]['birth_date']);
1913 $result = $this->callAPISuccess('contact', 'get', array('birth_date' => 'first day of next month -5 years'));
1914 $this->assertEquals(1, $result['count']);
1915 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -5 years')), $result['values'][$contact2['id']]['birth_date']);
1916 $result = $this->callAPISuccess('contact', 'get', array('birth_date_high' => date('Y-m-d', strtotime('-6 years'))));
1917 $this->assertEquals(1, $result['count']);
1918 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -20 years')), $result['values'][$contact3['id']]['birth_date']);
1919 $result = $this->callAPISuccess('contact', 'get', array(
1920 'birth_date_low' => date('Y-m-d', strtotime('-6 years')),
1921 'birth_date_high' => date('Y-m-d', strtotime('- 3 years')),
1923 $this->assertEquals(1, $result['count']);
1924 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -5 years')), $result['values'][$contact2['id']]['birth_date']);
1925 $result = $this->callAPISuccess('contact', 'get', array(
1926 'birth_date_low' => '-6 years',
1927 'birth_date_high' => '- 3 years',
1929 $this->assertEquals(1, $result['count']);
1930 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -5 years')), $result['values'][$contact2['id']]['birth_date']);
1934 * Test Address parameters
1936 * This include state_province, state_province_name, country
1938 public function testContactGetWithAddressFields() {
1939 $individuals = array(
1941 'first_name' => 'abc1',
1942 'contact_type' => 'Individual',
1943 'last_name' => 'xyz1',
1944 'api.address.create' => array(
1945 'country' => 'United States',
1946 'state_province_id' => 'Michigan',
1947 'location_type_id' => 1,
1951 'first_name' => 'abc2',
1952 'contact_type' => 'Individual',
1953 'last_name' => 'xyz2',
1954 'api.address.create' => array(
1955 'country' => 'United States',
1956 'state_province_id' => 'Alabama',
1957 'location_type_id' => 1,
1961 foreach ($individuals as $params) {
1962 $contact = $this->callAPISuccess('contact', 'create', $params);
1965 // Check whether Contact get API return successfully with below Address params.
1966 $fieldsToTest = array(
1967 'state_province_name' => 'Michigan',
1968 'state_province' => 'Michigan',
1969 'country' => 'United States',
1970 'state_province_name' => array('IN' => array('Michigan', 'Alabama')),
1971 'state_province' => array('IN' => array('Michigan', 'Alabama')),
1973 foreach ($fieldsToTest as $field => $value) {
1975 'id' => $contact['id'],
1978 $result = $this->callAPISuccess('Contact', 'get', $getParams);
1979 $this->assertEquals(1, $result['count']);
1984 * Test Deceased date parameters.
1986 * These include value, array & Deceased_date_high, Deceased date_low
1989 public function testContactGetDeceasedDate() {
1990 $contact1 = $this->callAPISuccess('contact', 'create', array_merge($this->_params
, array('deceased_date' => 'first day of next month - 2 years')));
1991 $contact2 = $this->callAPISuccess('contact', 'create', array_merge($this->_params
, array('deceased_date' => 'first day of next month - 5 years')));
1992 $contact3 = $this->callAPISuccess('contact', 'create', array_merge($this->_params
, array('deceased_date' => 'first day of next month -20 years')));
1994 $result = $this->callAPISuccess('contact', 'get', array());
1995 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -2 years')), $result['values'][$contact1['id']]['deceased_date']);
1996 $result = $this->callAPISuccess('contact', 'get', array('deceased_date' => 'first day of next month -5 years'));
1997 $this->assertEquals(1, $result['count']);
1998 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -5 years')), $result['values'][$contact2['id']]['deceased_date']);
1999 $result = $this->callAPISuccess('contact', 'get', array('deceased_date_high' => date('Y-m-d', strtotime('-6 years'))));
2000 $this->assertEquals(1, $result['count']);
2001 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -20 years')), $result['values'][$contact3['id']]['deceased_date']);
2002 $result = $this->callAPISuccess('contact', 'get', array(
2003 'deceased_date_low' => '-6 years',
2004 'deceased_date_high' => date('Y-m-d', strtotime('- 3 years')),
2006 $this->assertEquals(1, $result['count']);
2007 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -5 years')), $result['values'][$contact2['id']]['deceased_date']);
2011 * Test for Contact.get id=@user:username.
2013 public function testContactGetByUsername() {
2014 // Setup - create contact with a uf-match.
2015 $cid = $this->individualCreate(array(
2016 'contact_type' => 'Individual',
2017 'first_name' => 'testGetByUsername',
2018 'last_name' => 'testGetByUsername',
2021 $ufMatchParams = array(
2022 'domain_id' => CRM_Core_Config
::domainID(),
2024 'uf_name' => 'the-email-matching-key-is-not-really-the-username',
2025 'contact_id' => $cid,
2027 $ufMatch = CRM_Core_BAO_UFMatch
::create($ufMatchParams);
2028 $this->assertTrue(is_numeric($ufMatch->id
));
2030 // setup - mock the calls to CRM_Utils_System_*::getUfId
2031 $userSystem = $this->getMock('CRM_Utils_System_UnitTests', array('getUfId'));
2032 $userSystem->expects($this->once())
2034 ->with($this->equalTo('exampleUser'))
2035 ->will($this->returnValue(99));
2036 CRM_Core_Config
::singleton()->userSystem
= $userSystem;
2039 $result = $this->callAPISuccess('Contact', 'get', array(
2040 'id' => '@user:exampleUser',
2042 $this->assertEquals('testGetByUsername', $result['values'][$cid]['first_name']);
2046 * Test to check return works OK.
2048 public function testContactGetReturnValues() {
2049 $extraParams = array(
2050 'nick_name' => 'Bob',
2052 'email' => 'e@mail.com',
2054 $contactID = $this->individualCreate($extraParams);
2055 //actually it turns out the above doesn't create a phone
2056 $this->callAPISuccess('phone', 'create', array('contact_id' => $contactID, 'phone' => '456'));
2057 $result = $this->callAPISuccess('contact', 'getsingle', array('id' => $contactID));
2058 foreach ($extraParams as $key => $value) {
2059 $this->assertEquals($result[$key], $value);
2061 //now we check they are still returned with 'return' key
2062 $result = $this->callAPISuccess('contact', 'getsingle', array(
2064 'return' => array_keys($extraParams),
2066 foreach ($extraParams as $key => $value) {
2067 $this->assertEquals($result[$key], $value);
2072 * Test creating multiple phones using chaining.
2074 * @throws \Exception
2076 public function testCRM13252MultipleChainedPhones() {
2077 $contactID = $this->householdCreate();
2078 $this->callAPISuccessGetCount('phone', array('contact_id' => $contactID), 0);
2080 'contact_id' => $contactID,
2081 'household_name' => 'Household 1',
2082 'contact_type' => 'Household',
2083 'api.phone.create' => array(
2085 'phone' => '111-111-1111',
2086 'location_type_id' => 1,
2087 'phone_type_id' => 1,
2090 'phone' => '222-222-2222',
2091 'location_type_id' => 1,
2092 'phone_type_id' => 2,
2096 $this->callAPISuccess('contact', 'create', $params);
2097 $this->callAPISuccessGetCount('phone', array('contact_id' => $contactID), 2);
2102 * Test for Contact.get id=@user:username (with an invalid username).
2104 public function testContactGetByUnknownUsername() {
2105 // setup - mock the calls to CRM_Utils_System_*::getUfId
2106 $userSystem = $this->getMock('CRM_Utils_System_UnitTests', array('getUfId'));
2107 $userSystem->expects($this->once())
2109 ->with($this->equalTo('exampleUser'))
2110 ->will($this->returnValue(NULL));
2111 CRM_Core_Config
::singleton()->userSystem
= $userSystem;
2114 $result = $this->callAPIFailure('Contact', 'get', array(
2115 'id' => '@user:exampleUser',
2117 $this->assertRegExp('/cannot be resolved to a contact ID/', $result['error_message']);
2121 * Verify attempt to create individual with chained arrays and sequential.
2123 public function testGetIndividualWithChainedArraysAndSequential() {
2124 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__
, __FILE__
);
2125 $params['custom_' . $ids['custom_field_id']] = "custom string";
2127 $moreIDs = $this->CustomGroupMultipleCreateWithFields();
2130 'first_name' => 'abc3',
2131 'last_name' => 'xyz3',
2132 'contact_type' => 'Individual',
2133 'email' => 'man3@yahoo.com',
2134 'api.website.create' => array(
2136 'url' => "http://civicrm.org",
2139 'url' => "https://civicrm.org",
2144 $result = $this->callAPISuccess('Contact', 'create', $params);
2146 // delete the contact and custom groups
2147 $this->callAPISuccess('contact', 'delete', array('id' => $result['id']));
2148 $this->customGroupDelete($ids['custom_group_id']);
2149 $this->customGroupDelete($moreIDs['custom_group_id']);
2151 $this->assertEquals($result['id'], $result['values'][0]['id']);
2152 $this->assertArrayKeyExists('api.website.create', $result['values'][0]);
2156 * Verify attempt to create individual with chained arrays.
2158 public function testGetIndividualWithChainedArrays() {
2159 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__
, __FILE__
);
2160 $params['custom_' . $ids['custom_field_id']] = "custom string";
2162 $moreIDs = $this->CustomGroupMultipleCreateWithFields();
2163 $description = "This demonstrates the usage of chained api functions.\nIn this case no notes or custom fields have been created.";
2164 $subfile = "APIChainedArray";
2166 'first_name' => 'abc3',
2167 'last_name' => 'xyz3',
2168 'contact_type' => 'Individual',
2169 'email' => 'man3@yahoo.com',
2170 'api.contribution.create' => array(
2171 'receive_date' => '2010-01-01',
2172 'total_amount' => 100.00,
2173 'financial_type_id' => 1,
2174 'payment_instrument_id' => 1,
2175 'non_deductible_amount' => 10.00,
2176 'fee_amount' => 50.00,
2177 'net_amount' => 90.00,
2179 'invoice_id' => 67890,
2181 'contribution_status_id' => 1,
2183 'api.contribution.create.1' => array(
2184 'receive_date' => '2011-01-01',
2185 'total_amount' => 120.00,
2186 'financial_type_id' => $this->_financialTypeId
= 1,
2187 'payment_instrument_id' => 1,
2188 'non_deductible_amount' => 10.00,
2189 'fee_amount' => 50.00,
2190 'net_amount' => 90.00,
2192 'invoice_id' => 67830,
2194 'contribution_status_id' => 1,
2196 'api.website.create' => array(
2198 'url' => "http://civicrm.org",
2203 $result = $this->callAPISuccess('Contact', 'create', $params);
2205 'id' => $result['id'],
2206 'api.website.get' => array(),
2207 'api.Contribution.get' => array(
2208 'total_amount' => '120.00',
2210 'api.CustomValue.get' => 1,
2211 'api.Note.get' => 1,
2213 $result = $this->callAPIAndDocument('Contact', 'Get', $params, __FUNCTION__
, __FILE__
, $description, $subfile);
2214 // delete the contact
2215 $this->callAPISuccess('contact', 'delete', $result);
2216 $this->customGroupDelete($ids['custom_group_id']);
2217 $this->customGroupDelete($moreIDs['custom_group_id']);
2218 $this->assertEquals(0, $result['values'][$result['id']]['api.website.get']['is_error']);
2219 $this->assertEquals("http://civicrm.org", $result['values'][$result['id']]['api.website.get']['values'][0]['url']);
2223 * Verify attempt to create individual with chained arrays and sequential.
2225 * See https://issues.civicrm.org/jira/browse/CRM-15815
2227 public function testCreateIndividualWithChainedArrayAndSequential() {
2230 'first_name' => 'abc5',
2231 'last_name' => 'xyz5',
2232 'contact_type' => 'Individual',
2233 'email' => 'woman5@yahoo.com',
2234 'api.phone.create' => array(
2235 array('phone' => '03-231 07 95'),
2236 array('phone' => '03-232 51 62'),
2238 'api.website.create' => array(
2239 'url' => 'http://civicrm.org',
2242 $result = $this->callAPISuccess('Contact', 'create', $params);
2244 // I could try to parse the result to see whether the two phone numbers
2245 // and the website are there, but I am not sure about the correct format.
2246 // So I will just fetch it again before checking.
2247 // See also http://forum.civicrm.org/index.php/topic,35393.0.html
2250 'id' => $result['id'],
2251 'api.website.get' => array(),
2252 'api.phone.get' => array(),
2254 $result = $this->callAPISuccess('Contact', 'get', $params);
2256 // delete the contact
2257 $this->callAPISuccess('contact', 'delete', $result);
2259 $this->assertEquals(2, $result['values'][0]['api.phone.get']['count']);
2260 $this->assertEquals(1, $result['values'][0]['api.website.get']['count']);
2264 * Test retrieving an individual with chained array syntax.
2266 public function testGetIndividualWithChainedArraysFormats() {
2267 $description = "This demonstrates the usage of chained api functions.\nIn this case no notes or custom fields have been created.";
2268 $subfile = "APIChainedArrayFormats";
2269 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__
, __FILE__
);
2270 $params['custom_' . $ids['custom_field_id']] = "custom string";
2272 $moreIDs = $this->CustomGroupMultipleCreateWithFields();
2274 'first_name' => 'abc3',
2275 'last_name' => 'xyz3',
2276 'contact_type' => 'Individual',
2277 'email' => 'man3@yahoo.com',
2278 'api.contribution.create' => array(
2279 'receive_date' => '2010-01-01',
2280 'total_amount' => 100.00,
2281 'financial_type_id' => $this->_financialTypeId
,
2282 'payment_instrument_id' => 1,
2283 'non_deductible_amount' => 10.00,
2284 'fee_amount' => 50.00,
2285 'net_amount' => 90.00,
2287 'contribution_status_id' => 1,
2288 'skipCleanMoney' => 1,
2290 'api.contribution.create.1' => array(
2291 'receive_date' => '2011-01-01',
2292 'total_amount' => 120.00,
2293 'financial_type_id' => $this->_financialTypeId
,
2294 'payment_instrument_id' => 1,
2295 'non_deductible_amount' => 10.00,
2296 'fee_amount' => 50.00,
2297 'net_amount' => 90.00,
2299 'contribution_status_id' => 1,
2300 'skipCleanMoney' => 1,
2302 'api.website.create' => array(
2304 'url' => "http://civicrm.org",
2309 $result = $this->callAPISuccess('Contact', 'create', $params);
2311 'id' => $result['id'],
2312 'api.website.getValue' => array('return' => 'url'),
2313 'api.Contribution.getCount' => array(),
2314 'api.CustomValue.get' => 1,
2315 'api.Note.get' => 1,
2316 'api.Membership.getCount' => array(),
2318 $result = $this->callAPIAndDocument('Contact', 'Get', $params, __FUNCTION__
, __FILE__
, $description, $subfile);
2319 $this->assertEquals(2, $result['values'][$result['id']]['api.Contribution.getCount']);
2320 $this->assertEquals(0, $result['values'][$result['id']]['api.Note.get']['is_error']);
2321 $this->assertEquals("http://civicrm.org", $result['values'][$result['id']]['api.website.getValue']);
2323 $this->callAPISuccess('contact', 'delete', $result);
2324 $this->customGroupDelete($ids['custom_group_id']);
2325 $this->customGroupDelete($moreIDs['custom_group_id']);
2329 * Test complex chaining.
2331 public function testGetIndividualWithChainedArraysAndMultipleCustom() {
2332 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__
, __FILE__
);
2333 $params['custom_' . $ids['custom_field_id']] = "custom string";
2334 $moreIDs = $this->CustomGroupMultipleCreateWithFields();
2335 $andMoreIDs = $this->CustomGroupMultipleCreateWithFields(array(
2336 'title' => "another group",
2337 'name' => 'another name',
2339 $description = "This demonstrates the usage of chained api functions with multiple custom fields.";
2340 $subfile = "APIChainedArrayMultipleCustom";
2342 'first_name' => 'abc3',
2343 'last_name' => 'xyz3',
2344 'contact_type' => 'Individual',
2345 'email' => 'man3@yahoo.com',
2346 'api.contribution.create' => array(
2347 'receive_date' => '2010-01-01',
2348 'total_amount' => 100.00,
2349 'financial_type_id' => 1,
2350 'payment_instrument_id' => 1,
2351 'non_deductible_amount' => 10.00,
2352 'fee_amount' => 50.00,
2353 'net_amount' => 90.00,
2355 'invoice_id' => 67890,
2357 'contribution_status_id' => 1,
2358 'skipCleanMoney' => 1,
2360 'api.contribution.create.1' => array(
2361 'receive_date' => '2011-01-01',
2362 'total_amount' => 120.00,
2363 'financial_type_id' => 1,
2364 'payment_instrument_id' => 1,
2365 'non_deductible_amount' => 10.00,
2366 'fee_amount' => 50.00,
2367 'net_amount' => 90.00,
2369 'invoice_id' => 67830,
2371 'contribution_status_id' => 1,
2372 'skipCleanMoney' => 1,
2374 'api.website.create' => array(
2376 'url' => "http://civicrm.org",
2379 'custom_' . $ids['custom_field_id'] => "value 1",
2380 'custom_' . $moreIDs['custom_field_id'][0] => "value 2",
2381 'custom_' . $moreIDs['custom_field_id'][1] => "warm beer",
2382 'custom_' . $andMoreIDs['custom_field_id'][1] => "vegemite",
2385 $result = $this->callAPISuccess('Contact', 'create', $params);
2386 $result = $this->callAPISuccess('Contact', 'create', array(
2387 'contact_type' => 'Individual',
2388 'id' => $result['id'],
2390 $moreIDs['custom_field_id'][0] => "value 3",
2392 $ids['custom_field_id'] => "value 4",
2396 'id' => $result['id'],
2397 'api.website.getValue' => array('return' => 'url'),
2398 'api.Contribution.getCount' => array(),
2399 'api.CustomValue.get' => 1,
2401 $result = $this->callAPIAndDocument('Contact', 'Get', $params, __FUNCTION__
, __FILE__
, $description, $subfile);
2403 $this->customGroupDelete($ids['custom_group_id']);
2404 $this->customGroupDelete($moreIDs['custom_group_id']);
2405 $this->customGroupDelete($andMoreIDs['custom_group_id']);
2406 $this->assertEquals(0, $result['values'][$result['id']]['api.CustomValue.get']['is_error']);
2407 $this->assertEquals('http://civicrm.org', $result['values'][$result['id']]['api.website.getValue']);
2411 * Test checks usage of $values to pick & choose inputs.
2413 public function testChainingValuesCreate() {
2414 $description = "This demonstrates the usage of chained api functions. Specifically it has one 'parent function' &
2415 2 child functions - one receives values from the parent (Contact) and the other child (Tag).";
2416 $subfile = "APIChainedArrayValuesFromSiblingFunction";
2418 'display_name' => 'batman',
2419 'contact_type' => 'Individual',
2420 'api.tag.create' => array(
2421 'name' => '$value.id',
2422 'description' => '$value.display_name',
2423 'format.only_id' => 1,
2425 'api.entity_tag.create' => array('tag_id' => '$value.api.tag.create'),
2427 $result = $this->callAPIAndDocument('Contact', 'Create', $params, __FUNCTION__
, __FILE__
, $description, $subfile);
2428 $this->assertEquals(0, $result['values'][$result['id']]['api.entity_tag.create']['is_error']);
2430 $tablesToTruncate = array(
2433 'civicrm_entity_tag',
2436 $this->quickCleanup($tablesToTruncate, TRUE);
2440 * Test TrueFalse format - I couldn't come up with an easy way to get an error on Get.
2442 public function testContactGetFormatIsSuccessTrue() {
2443 $this->createContactFromXML();
2444 $description = "This demonstrates use of the 'format.is_success' param.
2445 This param causes only the success or otherwise of the function to be returned as BOOLEAN";
2446 $subfile = "FormatIsSuccess_True";
2447 $params = array('id' => 17, 'format.is_success' => 1);
2448 $result = $this->callAPIAndDocument('Contact', 'Get', $params, __FUNCTION__
, __FILE__
, $description, $subfile);
2449 $this->assertEquals(1, $result);
2450 $this->callAPISuccess('Contact', 'Delete', $params);
2454 * Test TrueFalse format.
2456 public function testContactCreateFormatIsSuccessFalse() {
2458 $description = "This demonstrates use of the 'format.is_success' param.
2459 This param causes only the success or otherwise of the function to be returned as BOOLEAN";
2460 $subfile = "FormatIsSuccess_Fail";
2461 $params = array('id' => 500, 'format.is_success' => 1);
2462 $result = $this->callAPIAndDocument('Contact', 'Create', $params, __FUNCTION__
, __FILE__
, $description, $subfile);
2463 $this->assertEquals(0, $result);
2467 * Test long display names.
2471 public function testContactCreateLongDisplayName() {
2472 $result = $this->callAPISuccess('Contact', 'Create', array(
2473 'first_name' => str_pad('a', 64, 'a'),
2474 'last_name' => str_pad('a', 64, 'a'),
2475 'contact_type' => 'Individual',
2477 $this->assertEquals('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', $result['values'][$result['id']]['display_name']);
2478 $this->assertEquals('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', $result['values'][$result['id']]['sort_name']);
2482 * Test Single Entity format.
2484 public function testContactGetSingleEntityArray() {
2485 $this->createContactFromXML();
2486 $description = "This demonstrates use of the 'format.single_entity_array' param.
2487 This param causes the only contact to be returned as an array without the other levels.
2488 It will be ignored if there is not exactly 1 result";
2489 $subfile = "GetSingleContact";
2490 $params = array('id' => 17);
2491 $result = $this->callAPIAndDocument('Contact', 'GetSingle', $params, __FUNCTION__
, __FILE__
, $description, $subfile);
2492 $this->assertEquals('Test Contact', $result['display_name']);
2493 $this->callAPISuccess('Contact', 'Delete', $params);
2497 * Test Single Entity format.
2499 public function testContactGetFormatCountOnly() {
2500 $this->createContactFromXML();
2501 $description = "This demonstrates use of the 'getCount' action.
2502 This param causes the count of the only function to be returned as an integer.";
2503 $params = array('id' => 17);
2504 $result = $this->callAPIAndDocument('Contact', 'GetCount', $params, __FUNCTION__
, __FILE__
, $description,
2506 $this->assertEquals('1', $result);
2507 $this->callAPISuccess('Contact', 'Delete', $params);
2511 * Test id only format.
2513 public function testContactGetFormatIDOnly() {
2514 $this->createContactFromXML();
2515 $description = "This demonstrates use of the 'format.id_only' param.
2516 This param causes the id of the only entity to be returned as an integer.
2517 It will be ignored if there is not exactly 1 result";
2518 $subfile = "FormatOnlyID";
2519 $params = array('id' => 17, 'format.only_id' => 1);
2520 $result = $this->callAPIAndDocument('Contact', 'Get', $params, __FUNCTION__
, __FILE__
, $description, $subfile);
2521 $this->assertEquals('17', $result);
2522 $this->callAPISuccess('Contact', 'Delete', $params);
2526 * Test id only format.
2528 public function testContactGetFormatSingleValue() {
2529 $this->createContactFromXML();
2530 $description = "This demonstrates use of the 'format.single_value' param.
2531 This param causes only a single value of the only entity to be returned as an string.
2532 It will be ignored if there is not exactly 1 result";
2533 $subFile = "FormatSingleValue";
2534 $params = array('id' => 17, 'return' => 'display_name');
2535 $result = $this->callAPIAndDocument('Contact', 'getvalue', $params, __FUNCTION__
, __FILE__
, $description, $subFile);
2536 $this->assertEquals('Test Contact', $result);
2537 $this->callAPISuccess('Contact', 'Delete', $params);
2541 * Test that permissions are respected when creating contacts.
2543 public function testContactCreationPermissions() {
2545 'contact_type' => 'Individual',
2546 'first_name' => 'Foo',
2547 'last_name' => 'Bear',
2548 'check_permissions' => TRUE,
2550 $config = CRM_Core_Config
::singleton();
2551 $config->userPermissionClass
->permissions
= array('access CiviCRM');
2552 $result = $this->callAPIFailure('contact', 'create', $params);
2553 $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');
2555 $config->userPermissionClass
->permissions
= array('access CiviCRM', 'add contacts', 'import contacts');
2556 $this->callAPISuccess('contact', 'create', $params);
2560 * Test that delete with skip undelete respects permissions.
2562 public function testContactDeletePermissions() {
2563 $contactID = $this->individualCreate();
2564 CRM_Core_Config
::singleton()->userPermissionClass
->permissions
= array('access CiviCRM');
2565 $this->callAPIFailure('Contact', 'delete', array(
2567 'check_permissions' => 1,
2568 'skip_undelete' => 1,
2570 $this->callAPISuccess('Contact', 'delete', array(
2572 'check_permissions' => 0,
2573 'skip_undelete' => 1,
2578 * Test update with check permissions set.
2580 public function testContactUpdatePermissions() {
2582 'contact_type' => 'Individual',
2583 'first_name' => 'Foo',
2584 'last_name' => 'Bear',
2585 'check_permissions' => TRUE,
2587 $result = $this->callAPISuccess('contact', 'create', $params);
2588 $config = CRM_Core_Config
::singleton();
2590 'id' => $result['id'],
2591 'contact_type' => 'Individual',
2592 'last_name' => 'Bar',
2593 'check_permissions' => TRUE,
2596 $config->userPermissionClass
->permissions
= array('access CiviCRM');
2597 $result = $this->callAPIFailure('contact', 'update', $params);
2598 $this->assertEquals('Permission denied to modify contact record', $result['error_message']);
2600 $config->userPermissionClass
->permissions
= array(
2603 'view all contacts',
2604 'edit all contacts',
2607 $this->callAPISuccess('contact', 'update', $params);
2611 * Set up helper to create a contact.
2613 public function createContactFromXML() {
2614 // Insert a row in civicrm_contact creating contact 17.
2615 $op = new PHPUnit_Extensions_Database_Operation_Insert();
2616 $op->execute($this->_dbconn
,
2617 $this->createXMLDataSet(
2618 dirname(__FILE__
) . '/dataset/contact_17.xml'
2624 * Test contact proximity api.
2626 public function testContactProximity() {
2627 // first create a contact with a SF location with a specific
2629 $contactID = $this->organizationCreate();
2631 // now create the address
2633 'street_address' => '123 Main Street',
2634 'city' => 'San Francisco',
2636 'country_id' => 1228,
2637 'state_province_id' => 1004,
2638 'geo_code_1' => '37.79',
2639 'geo_code_2' => '-122.40',
2640 'location_type_id' => 1,
2641 'contact_id' => $contactID,
2644 $result = $this->callAPISuccess('address', 'create', $params);
2645 $this->assertEquals(1, $result['count']);
2647 // now do a proximity search with a close enough geocode and hope to match
2648 // that specific contact only!
2649 $proxParams = array(
2651 'longitude' => -122.3,
2655 $result = $this->callAPISuccess('contact', 'proximity', $proxParams);
2656 $this->assertEquals(1, $result['count']);
2660 * Test that Ajax API permission is sufficient to access getquick api.
2662 * (note that getquick api is required for autocomplete & has ACL permissions applied)
2664 public function testGetquickPermissionCRM13744() {
2665 CRM_Core_Config
::singleton()->userPermissionClass
->permissions
= array('access CiviEvent');
2666 $this->callAPIFailure('contact', 'getquick', array('name' => 'b', 'check_permissions' => TRUE));
2667 CRM_Core_Config
::singleton()->userPermissionClass
->permissions
= array('access CiviCRM');
2668 $this->callAPISuccess('contact', 'getquick', array('name' => 'b', 'check_permissions' => TRUE));
2669 CRM_Core_Config
::singleton()->userPermissionClass
->permissions
= array('access AJAX API');
2670 $this->callAPISuccess('contact', 'getquick', array('name' => 'b', 'check_permissions' => TRUE));
2674 * Test that getquick returns contacts with an exact first name match first.
2676 * The search string 'b' & 'bob' both return ordered by sort_name if includeOrderByClause
2677 * is true (default) but if it is false then matches are returned in ID order.
2679 * @dataProvider getSearchSortOptions
2681 public function testGetQuickExactFirst($searchParameters, $settings, $firstContact, $secondContact = NULL) {
2682 $this->getQuickSearchSampleData();
2683 $this->callAPISuccess('Setting', 'create', $settings);
2684 $result = $this->callAPISuccess('contact', 'getquick', $searchParameters);
2685 $this->assertEquals($firstContact, $result['values'][0]['sort_name']);
2686 $this->assertEquals($secondContact, $result['values'][1]['sort_name']);
2687 $this->callAPISuccess('Setting', 'create', array('includeWildCardInName' => TRUE, 'includeOrderByClause' => TRUE));
2690 public function getSearchSortOptions() {
2691 $firstAlphabeticalContactBySortName = 'A Bobby, Bobby';
2692 $secondAlphabeticalContactBySortName = 'Aadvark, Bob';
2693 $secondAlphabeticalContactWithEmailBySortName = 'Bob, Bob';
2694 $firstAlphabeticalContactFirstNameBob = 'Aadvark, Bob';
2695 $secondAlphabeticalContactFirstNameBob = 'Bob, Bob';
2696 $firstByIDContactFirstNameBob = 'Bob, Bob';
2697 $secondByIDContactFirstNameBob = 'K Bobby, Bob';
2698 $firstContactByID = 'Bob, Bob';
2699 $secondContactByID = 'E Bobby, Bobby';
2700 $bobLikeEmail = 'A Bobby, Bobby';
2703 'empty_search_basic' => array(
2704 'search_parameters' => array('name' => '%'),
2705 'settings' => array('includeWildCardInName' => TRUE, 'includeOrderByClause' => TRUE),
2706 'first_contact' => $firstAlphabeticalContactBySortName,
2707 'second_contact' => $secondAlphabeticalContactBySortName,
2709 'empty_search_basic_no_wildcard' => array(
2710 'search_parameters' => array('name' => '%'),
2711 'settings' => array('includeWildCardInName' => FALSE, 'includeOrderByClause' => TRUE),
2712 'first_contact' => $firstAlphabeticalContactBySortName,
2713 'second_contact' => $secondAlphabeticalContactBySortName,
2715 'single_letter_search_basic' => array(
2716 'search_parameters' => array('name' => 'b'),
2717 'settings' => array('includeWildCardInName' => TRUE, 'includeOrderByClause' => TRUE),
2718 'first_contact' => $firstAlphabeticalContactBySortName,
2719 'second_contact' => $secondAlphabeticalContactBySortName,
2721 'bob_search_basic' => array(
2722 'search_parameters' => array('name' => 'bob'),
2723 'settings' => array('includeWildCardInName' => TRUE, 'includeOrderByClause' => TRUE),
2724 'first_contact' => $firstAlphabeticalContactBySortName,
2725 'second_contact' => $secondAlphabeticalContactBySortName,
2727 'bob_search_no_orderby' => array(
2728 'search_parameters' => array('name' => 'bob'),
2729 'settings' => array('includeWildCardInName' => TRUE, 'includeOrderByClause' => FALSE),
2730 'first_contact' => $firstContactByID,
2731 'second_contact' => $secondContactByID,
2733 'bob_search_no_wildcard' => array(
2734 'search_parameters' => array('name' => 'bob'),
2735 'settings' => array('includeWildCardInName' => FALSE, 'includeOrderByClause' => TRUE),
2736 'second_contact' => $bobLikeEmail,
2737 'first_contact' => $secondAlphabeticalContactFirstNameBob,
2739 // This should be the same as just no wildcard as if we had an exactMatch while searching by
2740 // sort name it would rise to the top CRM-19547
2741 'bob_search_no_wildcard_no_orderby' => array(
2742 'search_parameters' => array('name' => 'bob'),
2743 'settings' => array('includeWildCardInName' => FALSE, 'includeOrderByClause' => TRUE),
2744 'second_contact' => $bobLikeEmail,
2745 'first_contact' => $secondAlphabeticalContactFirstNameBob,
2747 'first_name_search_basic' => array(
2748 'search_parameters' => array('name' => 'bob', 'field_name' => 'first_name'),
2749 'settings' => array('includeWildCardInName' => TRUE, 'includeOrderByClause' => TRUE),
2750 'first_contact' => $firstAlphabeticalContactFirstNameBob,
2751 'second_contact' => $secondAlphabeticalContactFirstNameBob,
2753 'first_name_search_no_wildcard' => array(
2754 'search_parameters' => array('name' => 'bob', 'field_name' => 'first_name'),
2755 'settings' => array('includeWildCardInName' => FALSE, 'includeOrderByClause' => TRUE),
2756 'first_contact' => $firstAlphabeticalContactFirstNameBob,
2757 'second_contact' => $secondAlphabeticalContactFirstNameBob,
2759 'first_name_search_no_orderby' => array(
2760 'search_parameters' => array('name' => 'bob', 'field_name' => 'first_name'),
2761 'settings' => array('includeWildCardInName' => TRUE, 'includeOrderByClause' => FALSE),
2762 'first_contact' => $firstByIDContactFirstNameBob,
2763 'second_contact' => $secondByIDContactFirstNameBob,
2765 'email_search_basic' => array(
2766 'search_parameters' => array('name' => 'bob', 'field_name' => 'email', 'table_name' => 'eml'),
2767 'settings' => array('includeWildCardInName' => FALSE, 'includeOrderByClause' => TRUE),
2768 'first_contact' => $firstAlphabeticalContactBySortName,
2769 'second_contact' => $secondAlphabeticalContactWithEmailBySortName,
2775 * Test that getquick returns contacts with an exact first name match first.
2777 public function testGetQuickEmail() {
2778 $this->getQuickSearchSampleData();
2779 $loggedInContactID = $this->createLoggedInUser();
2780 $result = $this->callAPISuccess('contact', 'getquick', array(
2783 $expectedData = array(
2784 'A Bobby, Bobby :: bob@bobby.com',
2785 'Bob, Bob :: bob@bob.com',
2787 'H Bobby, Bobby :: bob@h.com',
2789 $this->callAPISuccessGetValue('Contact', array('id' => $loggedInContactID, 'return' => 'last_name')) . ', Logged In :: anthony_anderson@civicrm.org',
2791 $this->assertEquals(6, $result['count']);
2792 foreach ($expectedData as $index => $value) {
2793 $this->assertEquals($value, $result['values'][$index]['data']);
2795 $result = $this->callAPISuccess('contact', 'getquick', array(
2798 $expectedData = array(
2799 'H Bobby, Bobby :: bob@h.com',
2801 foreach ($expectedData as $index => $value) {
2802 $this->assertEquals($value, $result['values'][$index]['data']);
2804 $this->callAPISuccess('Setting', 'create', array('includeWildCardInName' => FALSE));
2805 $result = $this->callAPISuccess('contact', 'getquick', array(
2808 $this->callAPISuccess('Setting', 'create', array('includeWildCardInName' => TRUE));
2809 $this->assertEquals(0, $result['count']);
2813 * Test that getquick returns contacts with an exact first name match first.
2815 public function testGetQuickEmailACL() {
2816 $this->getQuickSearchSampleData();
2817 $loggedInContactID = $this->createLoggedInUser();
2818 CRM_Core_Config
::singleton()->userPermissionClass
->permissions
= array();
2819 $result = $this->callAPISuccess('contact', 'getquick', array(
2822 $this->assertEquals(0, $result['count']);
2824 $this->hookClass
->setHook('civicrm_aclWhereClause', array($this, 'aclWhereNoBobH'));
2825 CRM_Contact_BAO_Contact_Permission
::cache($loggedInContactID, CRM_Core_Permission
::VIEW
, TRUE);
2826 $result = $this->callAPISuccess('contact', 'getquick', array(
2830 // Without the acl it would be 6 like the previous email getquick test.
2831 $this->assertEquals(5, $result['count']);
2832 $expectedData = array(
2833 'A Bobby, Bobby :: bob@bobby.com',
2834 'Bob, Bob :: bob@bob.com',
2837 $this->callAPISuccessGetValue('Contact', array('id' => $loggedInContactID, 'return' => 'last_name')) . ', Logged In :: anthony_anderson@civicrm.org',
2839 foreach ($expectedData as $index => $value) {
2840 $this->assertEquals($value, $result['values'][$index]['data']);
2845 * Test that getquick returns contacts with an exact first name match first.
2847 public function testGetQuickExternalID() {
2848 $this->getQuickSearchSampleData();
2849 $result = $this->callAPISuccess('contact', 'getquick', array(
2851 'field_name' => 'external_identifier',
2852 'table_name' => 'cc',
2854 $this->assertEquals(0, $result['count']);
2855 $result = $this->callAPISuccess('contact', 'getquick', array(
2857 'field_name' => 'external_identifier',
2858 'table_name' => 'cc',
2860 $this->assertEquals(1, $result['count']);
2861 $this->assertEquals('Bob, Bob', $result['values'][0]['sort_name']);
2865 * Test that getquick returns contacts with an exact first name match first.
2867 public function testGetQuickID() {
2868 $max = CRM_Core_DAO
::singleValueQuery("SELECT max(id) FROM civicrm_contact");
2869 $this->getQuickSearchSampleData();
2870 $result = $this->callAPISuccess('contact', 'getquick', array(
2872 'field_name' => 'id',
2873 'table_name' => 'cc',
2875 $this->assertEquals(1, $result['count']);
2876 $this->assertEquals('E Bobby, Bobby', $result['values'][0]['sort_name']);
2877 $result = $this->callAPISuccess('contact', 'getquick', array(
2879 'field_name' => 'contact_id',
2880 'table_name' => 'cc',
2882 $this->assertEquals(1, $result['count']);
2883 $this->assertEquals('E Bobby, Bobby', $result['values'][0]['sort_name']);
2887 * Test that getquick returns contacts with an exact first name match first.
2889 * Depending on the setting the sort name sort might click in next or not - test!
2891 public function testGetQuickFirstName() {
2892 $this->getQuickSearchSampleData();
2893 $this->callAPISuccess('Setting', 'create', array('includeOrderByClause' => TRUE));
2894 $result = $this->callAPISuccess('contact', 'getquick', array(
2896 'field_name' => 'first_name',
2897 'table_name' => 'cc',
2906 foreach ($expected as $index => $value) {
2907 $this->assertEquals($value, $result['values'][$index]['sort_name']);
2909 $this->callAPISuccess('Setting', 'create', array('includeOrderByClause' => FALSE));
2910 $result = $this->callAPISuccess('contact', 'getquick', array('name' => 'bob'));
2911 $this->assertEquals('Bob, Bob', $result['values'][0]['sort_name']);
2912 $this->assertEquals('E Bobby, Bobby', $result['values'][1]['sort_name']);
2916 * Test that getquick applies ACLs.
2918 public function testGetQuickFirstNameACLs() {
2919 $this->getQuickSearchSampleData();
2920 $userID = $this->createLoggedInUser();
2921 $this->callAPISuccess('Setting', 'create', array('includeOrderByClause' => TRUE, 'search_autocomplete_count' => 15));
2922 CRM_Core_Config
::singleton()->userPermissionClass
->permissions
= array();
2923 $result = $this->callAPISuccess('contact', 'getquick', array(
2925 'field_name' => 'first_name',
2926 'table_name' => 'cc',
2928 $this->assertEquals(0, $result['count']);
2930 $this->hookClass
->setHook('civicrm_aclWhereClause', array($this, 'aclWhereNoBobH'));
2931 CRM_Contact_BAO_Contact_Permission
::cache($userID, CRM_Core_Permission
::VIEW
, TRUE);
2932 $result = $this->callAPISuccess('contact', 'getquick', array(
2934 'field_name' => 'first_name',
2935 'table_name' => 'cc',
2937 $this->assertEquals('K Bobby, Bob', $result['values'][2]['sort_name']);
2938 // Without the ACL 9 would be bob@h.com.
2939 $this->assertEquals('I Bobby, Bobby', $result['values'][10]['sort_name']);
2943 * Full results returned.
2944 * @implements CRM_Utils_Hook::aclWhereClause
2946 * @param string $type
2947 * @param array $tables
2948 * @param array $whereTables
2949 * @param int $contactID
2950 * @param string $where
2952 public function aclWhereNoBobH($type, &$tables, &$whereTables, &$contactID, &$where) {
2953 $where = " (email <> 'bob@h.com' OR email IS NULL) ";
2954 $whereTables['civicrm_email'] = "LEFT JOIN civicrm_email e ON contact_a.id = e.contact_id";
2958 * Test that getquick returns contacts with an exact last name match first.
2960 public function testGetQuickLastName() {
2961 $this->getQuickSearchSampleData();
2962 $this->callAPISuccess('Setting', 'create', array('includeOrderByClause' => TRUE));
2963 $result = $this->callAPISuccess('contact', 'getquick', array(
2965 'field_name' => 'last_name',
2966 'table_name' => 'cc',
2974 foreach ($expected as $index => $value) {
2975 $this->assertEquals($value, $result['values'][$index]['sort_name']);
2977 $this->callAPISuccess('Setting', 'create', array('includeOrderByClause' => FALSE));
2978 $result = $this->callAPISuccess('contact', 'getquick', array('name' => 'bob'));
2979 $this->assertEquals('Bob, Bob :: bob@bob.com', $result['values'][0]['data']);
2983 * Test that getquick returns contacts by city.
2985 public function testGetQuickCity() {
2986 $this->getQuickSearchSampleData();
2987 $result = $this->callAPISuccess('contact', 'getquick', array(
2989 'field_name' => 'city',
2990 'table_name' => 'sts',
2992 $this->assertEquals('B Bobby, Bobby :: Toronto', $result['values'][0]['data']);
2993 $result = $this->callAPISuccess('contact', 'getquick', array(
2995 'field_name' => 'city',
2996 'table_name' => 'sts',
2998 $this->assertEquals('B Bobby, Bobby :: Toronto', $result['values'][0]['data']);
2999 $this->assertEquals('C Bobby, Bobby :: Whanganui', $result['values'][1]['data']);
3003 * Set up some sample data for testing quicksearch.
3005 public function getQuickSearchSampleData() {
3007 array('first_name' => 'Bob', 'last_name' => 'Bob', 'external_identifier' => 'abc', 'email' => 'bob@bob.com'),
3008 array('first_name' => 'Bobby', 'last_name' => 'E Bobby', 'external_identifier' => 'abcd'),
3010 'first_name' => 'Bobby',
3011 'last_name' => 'B Bobby',
3012 'external_identifier' => 'bcd',
3013 'api.address.create' => array(
3014 'street_address' => 'Sesame Street',
3015 'city' => 'Toronto',
3016 'location_type_id' => 1,
3020 'first_name' => 'Bobby',
3021 'last_name' => 'C Bobby',
3022 'external_identifier' => 'bcde',
3023 'api.address.create' => array(
3024 'street_address' => 'Te huarahi',
3025 'city' => 'Whanganui',
3026 'location_type_id' => 1,
3029 array('first_name' => 'Bobby', 'last_name' => 'D Bobby', 'external_identifier' => 'efg'),
3030 array('first_name' => 'Bobby', 'last_name' => 'A Bobby', 'external_identifier' => 'hij', 'email' => 'bob@bobby.com'),
3031 array('first_name' => 'Bobby', 'last_name' => 'F Bobby', 'external_identifier' => 'klm'),
3032 array('first_name' => 'Bobby', 'last_name' => 'G Bobby', 'external_identifier' => 'nop'),
3033 array('first_name' => 'Bobby', 'last_name' => 'H Bobby', 'external_identifier' => 'qrs', 'email' => 'bob@h.com'),
3034 array('first_name' => 'Bobby', 'last_name' => 'I Bobby'),
3035 array('first_name' => 'Bobby', 'last_name' => 'J Bobby'),
3036 array('first_name' => 'Bob', 'last_name' => 'K Bobby', 'external_identifier' => 'bcdef'),
3037 array('first_name' => 'Bob', 'last_name' => 'Aadvark'),
3039 foreach ($contacts as $type => $contact) {
3040 $contact['contact_type'] = 'Individual';
3041 $this->callAPISuccess('Contact', 'create', $contact);
3046 * Test get ref api - gets a list of references to an entity.
3048 public function testGetReferenceCounts() {
3049 $result = $this->callAPISuccess('Contact', 'create', array(
3050 'first_name' => 'Testily',
3051 'last_name' => 'McHaste',
3052 'contact_type' => 'Individual',
3053 'api.Address.replace' => array(
3054 'values' => array(),
3056 'api.Email.replace' => array(
3059 'email' => 'spam@dev.null',
3061 'location_type_id' => 1,
3065 'api.Phone.replace' => array(
3068 'phone' => '234-567-0001',
3070 'location_type_id' => 1,
3073 'phone' => '234-567-0002',
3075 'location_type_id' => 1,
3081 //$dao = new CRM_Contact_BAO_Contact();
3082 //$dao->id = $result['id'];
3083 //$this->assertTrue((bool) $dao->find(TRUE));
3085 //$refCounts = $dao->getReferenceCounts();
3086 //$this->assertTrue(is_array($refCounts));
3087 //$refCountsIdx = CRM_Utils_Array::index(array('name'), $refCounts);
3089 $refCounts = $this->callAPISuccess('Contact', 'getrefcount', array(
3090 'id' => $result['id'],
3092 $refCountsIdx = CRM_Utils_Array
::index(array('name'), $refCounts['values']);
3094 $this->assertEquals(1, $refCountsIdx['sql:civicrm_email:contact_id']['count']);
3095 $this->assertEquals('civicrm_email', $refCountsIdx['sql:civicrm_email:contact_id']['table']);
3096 $this->assertEquals(2, $refCountsIdx['sql:civicrm_phone:contact_id']['count']);
3097 $this->assertEquals('civicrm_phone', $refCountsIdx['sql:civicrm_phone:contact_id']['table']);
3098 $this->assertTrue(!isset($refCountsIdx['sql:civicrm_address:contact_id']));
3102 * Test the use of sql operators.
3104 public function testSQLOperatorsOnContactAPI() {
3105 $this->individualCreate();
3106 $this->organizationCreate();
3107 $this->householdCreate();
3108 $contacts = $this->callAPISuccess('contact', 'get', array('legal_name' => array('IS NOT NULL' => TRUE)));
3109 $this->assertEquals($contacts['count'], CRM_Core_DAO
::singleValueQuery('select count(*) FROM civicrm_contact WHERE legal_name IS NOT NULL'));
3110 $contacts = $this->callAPISuccess('contact', 'get', array('legal_name' => array('IS NULL' => TRUE)));
3111 $this->assertEquals($contacts['count'], CRM_Core_DAO
::singleValueQuery('select count(*) FROM civicrm_contact WHERE legal_name IS NULL'));
3115 * CRM-14743 - test api respects search operators.
3117 public function testGetModifiedDateByOperators() {
3118 $preExistingContactCount = CRM_Core_DAO
::singleValueQuery('select count(*) FROM civicrm_contact');
3119 $contact1 = $this->individualCreate();
3120 $sql = "UPDATE civicrm_contact SET created_date = '2012-01-01', modified_date = '2013-01-01' WHERE id = " . $contact1;
3121 CRM_Core_DAO
::executeQuery($sql);
3122 $contact2 = $this->individualCreate();
3123 $sql = "UPDATE civicrm_contact SET created_date = '2012-02-01', modified_date = '2013-02-01' WHERE id = " . $contact2;
3124 CRM_Core_DAO
::executeQuery($sql);
3125 $contact3 = $this->householdCreate();
3126 $sql = "UPDATE civicrm_contact SET created_date = '2012-03-01', modified_date = '2013-03-01' WHERE id = " . $contact3;
3127 CRM_Core_DAO
::executeQuery($sql);
3128 $contacts = $this->callAPISuccess('contact', 'get', array('modified_date' => array('<' => '2014-01-01')));
3129 $this->assertEquals($contacts['count'], 3);
3130 $contacts = $this->callAPISuccess('contact', 'get', array('modified_date' => array('>' => '2014-01-01')));
3131 $this->assertEquals($contacts['count'], $preExistingContactCount);
3135 * CRM-14743 - test api respects search operators.
3137 public function testGetCreatedDateByOperators() {
3138 $preExistingContactCount = CRM_Core_DAO
::singleValueQuery('select count(*) FROM civicrm_contact');
3139 $contact1 = $this->individualCreate();
3140 $sql = "UPDATE civicrm_contact SET created_date = '2012-01-01' WHERE id = " . $contact1;
3141 CRM_Core_DAO
::executeQuery($sql);
3142 $contact2 = $this->individualCreate();
3143 $sql = "UPDATE civicrm_contact SET created_date = '2012-02-01' WHERE id = " . $contact2;
3144 CRM_Core_DAO
::executeQuery($sql);
3145 $contact3 = $this->householdCreate();
3146 $sql = "UPDATE civicrm_contact SET created_date = '2012-03-01' WHERE id = " . $contact3;
3147 CRM_Core_DAO
::executeQuery($sql);
3148 $contacts = $this->callAPISuccess('contact', 'get', array('created_date' => array('<' => '2014-01-01')));
3149 $this->assertEquals($contacts['count'], 3);
3150 $contacts = $this->callAPISuccess('contact', 'get', array('created_date' => array('>' => '2014-01-01')));
3151 $this->assertEquals($contacts['count'], $preExistingContactCount);
3155 * CRM-14263 check that API is not affected by search profile related bug.
3157 public function testReturnCityProfile() {
3158 $contactID = $this->individualCreate();
3159 CRM_Core_Config
::singleton()->defaultSearchProfileID
= 1;
3160 $this->callAPISuccess('address', 'create', array(
3161 'contact_id' => $contactID,
3162 'city' => 'Cool City',
3163 'location_type_id' => 1,
3165 $result = $this->callAPISuccess('contact', 'get', array('city' => 'Cool City', 'return' => 'contact_type'));
3166 $this->assertEquals(1, $result['count']);
3170 * CRM-15443 - ensure getlist api does not return deleted contacts.
3172 public function testGetlistExcludeConditions() {
3173 $name = md5(time());
3174 $contact = $this->individualCreate(array('last_name' => $name));
3175 $this->individualCreate(array('last_name' => $name, 'is_deceased' => 1));
3176 $this->individualCreate(array('last_name' => $name, 'is_deleted' => 1));
3177 // We should get all but the deleted contact.
3178 $result = $this->callAPISuccess('contact', 'getlist', array('input' => $name));
3179 $this->assertEquals(2, $result['count']);
3180 // Force-exclude the deceased contact.
3181 $result = $this->callAPISuccess('contact', 'getlist', array(
3183 'params' => array('is_deceased' => 0),
3185 $this->assertEquals(1, $result['count']);
3186 $this->assertEquals($contact, $result['values'][0]['id']);
3190 * Test contact getactions.
3192 public function testGetActions() {
3193 $description = "Getting the available actions for an entity.";
3194 $result = $this->callAPIAndDocument($this->_entity
, 'getactions', array(), __FUNCTION__
, __FILE__
, $description);
3214 $deprecated = array(
3218 foreach ($expected as $action) {
3219 $this->assertTrue(in_array($action, $result['values']), "Expected action $action");
3221 foreach ($deprecated as $action) {
3222 $this->assertArrayKeyExists($action, $result['deprecated']);
3227 * Test the duplicate check function.
3229 public function testDuplicateCheck() {
3231 'first_name' => 'Harry',
3232 'last_name' => 'Potter',
3233 'email' => 'harry@hogwarts.edu',
3234 'contact_type' => 'Individual',
3236 $this->callAPISuccess('Contact', 'create', $harry);
3237 $result = $this->callAPISuccess('Contact', 'duplicatecheck', array(
3241 $this->assertEquals(1, $result['count']);
3242 $result = $this->callAPISuccess('Contact', 'duplicatecheck', array(
3244 'first_name' => 'Harry',
3245 'last_name' => 'Potter',
3246 'email' => 'no5@privet.drive',
3247 'contact_type' => 'Individual',
3250 $this->assertEquals(0, $result['count']);
3251 $this->callAPIFailure('Contact', 'create', array_merge($harry, array('dupe_check' => 1)));
3255 * Test the duplicate check function.
3257 public function testDuplicateCheckRuleNotReserved() {
3259 'first_name' => 'Harry',
3260 'last_name' => 'Potter',
3261 'email' => 'harry@hogwarts.edu',
3262 'contact_type' => 'Individual',
3264 $defaultRule = $this->callAPISuccess('RuleGroup', 'getsingle', array('used' => 'Unsupervised', 'is_reserved' => 1));
3265 $this->callAPISuccess('RuleGroup', 'create', array('id' => $defaultRule['id'], 'is_reserved' => 0));
3266 $this->callAPISuccess('Contact', 'create', $harry);
3267 $result = $this->callAPISuccess('Contact', 'duplicatecheck', array(
3271 $this->assertEquals(1, $result['count']);
3272 $this->callAPISuccess('RuleGroup', 'create', array('id' => $defaultRule['id'], 'is_reserved' => 1));
3276 * Test variants on retrieving contact by type.
3278 public function testGetByContactType() {
3279 $individual = $this->callAPISuccess('Contact', 'create', array(
3280 'email' => 'individual@test.com',
3281 'contact_type' => 'Individual',
3283 $household = $this->callAPISuccess('Contact', 'create', array(
3284 'household_name' => 'household@test.com',
3285 'contact_type' => 'Household',
3287 $organization = $this->callAPISuccess('Contact', 'create', array(
3288 'organization_name' => 'organization@test.com',
3289 'contact_type' => 'Organization',
3291 // Test with id - getsingle will throw an exception if not found
3292 $this->callAPISuccess('Contact', 'getsingle', array(
3293 'id' => $individual['id'],
3294 'contact_type' => 'Individual',
3296 $this->callAPISuccess('Contact', 'getsingle', array(
3297 'id' => $individual['id'],
3298 'contact_type' => array('IN' => array('Individual')),
3301 $this->callAPISuccess('Contact', 'getsingle', array(
3302 'id' => $organization['id'],
3303 'contact_type' => array('IN' => array('Individual', 'Organization')),
3306 $result = $this->callAPISuccess('Contact', 'get', array(
3307 'contact_type' => array('IN' => array('Individual', 'Organization')),
3308 'options' => array('limit' => 0),
3311 $this->assertContains($organization['id'], array_keys($result['values']));
3312 $this->assertContains($individual['id'], array_keys($result['values']));
3313 $this->assertNotContains($household['id'], array_keys($result['values']));
3315 $result = $this->callAPISuccess('Contact', 'get', array(
3316 'contact_type' => 'Household',
3317 'options' => array('limit' => 0),
3320 $this->assertNotContains($organization['id'], array_keys($result['values']));
3321 $this->assertNotContains($individual['id'], array_keys($result['values']));
3322 $this->assertContains($household['id'], array_keys($result['values']));
3326 * Test merging 2 contacts.
3328 * Someone kindly bequethed us the legacy of mixed up use of main_id & other_id
3329 * in the params for contact.merge api.
3331 * This test protects that legacy.
3333 public function testMergeBizzareOldParams() {
3334 $this->createLoggedInUser();
3335 $otherContact = $this->callAPISuccess('contact', 'create', $this->_params
);
3336 $mainContact = $this->callAPISuccess('contact', 'create', $this->_params
);
3337 $this->callAPISuccess('contact', 'merge', array(
3338 'main_id' => $mainContact['id'],
3339 'other_id' => $otherContact['id'],
3341 $contacts = $this->callAPISuccess('contact', 'get', $this->_params
);
3342 $this->assertEquals($otherContact['id'], $contacts['id']);
3346 * Test merging 2 contacts.
3348 public function testMerge() {
3349 $this->createLoggedInUser();
3350 $otherContact = $this->callAPISuccess('contact', 'create', $this->_params
);
3351 $retainedContact = $this->callAPISuccess('contact', 'create', $this->_params
);
3352 $this->callAPISuccess('contact', 'merge', array(
3353 'to_keep_id' => $retainedContact['id'],
3354 'to_remove_id' => $otherContact['id'],
3355 'auto_flip' => FALSE,
3358 $contacts = $this->callAPISuccess('contact', 'get', $this->_params
);
3359 $this->assertEquals($retainedContact['id'], $contacts['id']);
3360 $activity = $this->callAPISuccess('Activity', 'getsingle', array(
3361 'target_contact_id' => $retainedContact['id'],
3362 'activity_type_id' => 'Contact Merged',
3364 $this->assertEquals(date('Y-m-d'), date('Y-m-d', strtotime($activity['activity_date_time'])));
3365 $activity2 = $this->callAPISuccess('Activity', 'getsingle', array(
3366 'target_contact_id' => $otherContact['id'],
3367 'activity_type_id' => 'Contact Deleted by Merge',
3369 $this->assertEquals($activity['id'], $activity2['parent_id']);
3370 $this->assertEquals('Normal', civicrm_api3('option_value', 'getvalue', array(
3371 'value' => $activity['priority_id'],
3372 'return' => 'label',
3373 'option_group_id' => 'priority',
3379 * Test merging 2 contacts with delete to trash off.
3381 * We are checking that there is no error due to attempting to add an activity for the
3386 public function testMergeNoTrash() {
3387 $this->createLoggedInUser();
3388 $this->callAPISuccess('Setting', 'create', array('contact_undelete' => FALSE));
3389 $otherContact = $this->callAPISuccess('contact', 'create', $this->_params
);
3390 $retainedContact = $this->callAPISuccess('contact', 'create', $this->_params
);
3391 $this->callAPISuccess('contact', 'merge', array(
3392 'to_keep_id' => $retainedContact['id'],
3393 'to_remove_id' => $otherContact['id'],
3394 'auto_flip' => FALSE,
3396 $this->callAPISuccess('Setting', 'create', array('contact_undelete' => TRUE));
3400 * Ensure format with return=group shows comma-separated group IDs.
3404 public function testContactGetReturnGroup() {
3405 // Set up a contact, asser that they were created.
3406 $contact_params = array(
3407 'contact_type' => 'Individual',
3408 'first_name' => 'Test',
3409 'last_name' => 'Groupmember',
3410 'email' => 'test@example.org',
3412 $create_contact = $this->callApiSuccess('Contact', 'create', $contact_params);
3413 $this->assertEquals(0, $create_contact['is_error']);
3414 $this->assertInternalType('int', $create_contact['id']);
3416 $created_contact_id = $create_contact['id'];
3418 // Set up multiple groups, add the contact to the groups.
3419 $test_groups = array('Test group A', 'Test group B');
3420 foreach ($test_groups as $title) {
3421 // Use this contact as group owner, since we know they exist.
3422 $group_params = array(
3424 'created_id' => $created_contact_id,
3426 $create_group = $this->callApiSuccess('Group', 'create', $group_params);
3427 $this->assertEquals(0, $create_group['is_error']);
3428 $this->assertInternalType('int', $create_group['id']);
3430 $created_group_ids[] = $create_group['id'];
3432 // Add contact to the new group.
3433 $group_contact_params = array(
3434 'contact_id' => $created_contact_id,
3435 'group_id' => $create_group['id'],
3437 $create_group_contact = $this->callApiSuccess('GroupContact', 'create', $group_contact_params);
3438 $this->assertEquals(0, $create_group_contact['is_error']);
3439 $this->assertInternalType('int', $create_group_contact['added']);
3442 // Use the Contact,get API to retrieve the contact
3443 $contact_get_params = array(
3444 'id' => $created_contact_id,
3445 'return' => 'group',
3447 $contact_get = $this->callApiSuccess('Contact', 'get', $contact_get_params);
3448 $this->assertInternalType('array', $contact_get['values'][$created_contact_id]);
3449 $this->assertInternalType('string', $contact_get['values'][$created_contact_id]['groups']);
3451 // Ensure they are shown as being in each created group.
3452 $contact_group_ids = explode(',', $contact_get['values'][$created_contact_id]['groups']);
3453 foreach ($created_group_ids as $created_group_id) {
3454 $this->assertContains($created_group_id, $contact_group_ids);
3459 * CRM-20144 Verify that passing title of group works as well as id
3460 * Tests the following formats
3461 * contact.get group='title1'
3462 * contact.get group=id1
3464 public function testContactGetWithGroupTitle() {
3465 // Set up a contact, asser that they were created.
3466 $contact_params = array(
3467 'contact_type' => 'Individual',
3468 'first_name' => 'Test2',
3469 'last_name' => 'Groupmember',
3470 'email' => 'test@example.org',
3472 $create_contact = $this->callApiSuccess('Contact', 'create', $contact_params);
3473 $created_contact_id = $create_contact['id'];
3474 // Set up multiple groups, add the contact to the groups.
3475 $test_groups = array('Test group C', 'Test group D');
3476 foreach ($test_groups as $title) {
3477 $group_params = array(
3479 'created_id' => $created_contact_id,
3481 $create_group = $this->callApiSuccess('Group', 'create', $group_params);
3482 $created_group_id = $create_group['id'];
3484 // Add contact to the new group.
3485 $group_contact_params = array(
3486 'contact_id' => $created_contact_id,
3487 'group_id' => $create_group['id'],
3489 $this->callApiSuccess('GroupContact', 'create', $group_contact_params);
3490 $contact_get = $this->callAPISuccess('contact', 'get', array('group' => $title, 'return' => 'group'));
3491 $this->assertEquals(1, $contact_get['count']);
3492 $this->assertEquals($created_contact_id, $contact_get['id']);
3493 $contact_groups = explode(',', $contact_get['values'][$created_contact_id]['groups']);
3494 $this->assertContains((string) $create_group['id'], $contact_groups);
3495 $contact_get2 = $this->callAPISuccess('contact', 'get', array('group' => $created_group_id, 'return' => 'group'));
3496 $this->assertEquals($created_contact_id, $contact_get2['id']);
3497 $contact_groups2 = explode(',', $contact_get2['values'][$created_contact_id]['groups']);
3498 $this->assertContains((string) $create_group['id'], $contact_groups2);
3499 $this->callAPISuccess('group', 'delete', array('id' => $created_group_id));
3501 $this->callAPISuccess('contact', 'delete', array('id' => $created_contact_id, 'skip_undelete' => TRUE));
3505 * CRM-20144 Verify that passing title of group works as well as id
3506 * Tests the following formats
3507 * contact.get group=array('title1', title1)
3508 * contact.get group=array('IN' => array('title1', 'title2)
3510 public function testContactGetWithGroupTitleMultipleGroups() {
3511 $description = "Get all from group and display contacts.";
3512 $subFile = "GroupFilterUsingContactAPI";
3513 // Set up a contact, asser that they were created.
3514 $contact_params = array(
3515 'contact_type' => 'Individual',
3516 'first_name' => 'Test2',
3517 'last_name' => 'Groupmember',
3518 'email' => 'test@example.org',
3520 $create_contact = $this->callApiSuccess('Contact', 'create', $contact_params);
3521 $created_contact_id = $create_contact['id'];
3522 $createdGroupsTitles = $createdGroupsIds = array();
3523 // Set up multiple groups, add the contact to the groups.
3524 $test_groups = array('Test group C', 'Test group D');
3525 foreach ($test_groups as $title) {
3526 $group_params = array(
3528 'created_id' => $created_contact_id,
3530 $create_group = $this->callApiSuccess('Group', 'create', $group_params);
3531 $created_group_id = $create_group['id'];
3532 $createdGroupsIds[] = $create_group['id'];
3533 $createdGroupTitles[] = $title;
3534 // Add contact to the new group.
3535 $group_contact_params = array(
3536 'contact_id' => $created_contact_id,
3537 'group_id' => $create_group['id'],
3539 $create_group_contact = $this->callApiSuccess('GroupContact', 'create', $group_contact_params);
3541 $contact_get = $this->callAPISuccess('contact', 'get', array('group' => $createdGroupTitles, 'return' => 'group'));
3542 $this->assertEquals(1, $contact_get['count']);
3543 $this->assertEquals($created_contact_id, $contact_get['id']);
3544 $contact_groups = explode(',', $contact_get['values'][$created_contact_id]['groups']);
3545 foreach ($createdGroupsIds as $id) {
3546 $this->assertContains((string) $id, $contact_groups);
3548 $contact_get2 = $this->callAPIAndDocument('contact', 'get', array('group' => array('IN' => $createdGroupTitles)), __FUNCTION__
, __FILE__
, $description, $subFile);
3549 $contact_get2 = $this->callAPISuccess('contact', 'get', array('group' => array('IN' => $createdGroupTitles), 'return' => 'group'));
3550 $this->assertEquals($created_contact_id, $contact_get2['id']);
3551 $contact_groups2 = explode(',', $contact_get2['values'][$created_contact_id]['groups']);
3552 foreach ($createdGroupsIds as $id) {
3553 $this->assertContains((string) $id, $contact_groups2);
3555 foreach ($createdGroupsIds as $id) {
3556 $this->callAPISuccess('group', 'delete', array('id' => $id));
3558 $this->callAPISuccess('contact', 'delete', array('id' => $created_contact_id, 'skip_undelete' => TRUE));
3562 * CRM-20144 Verify that passing title of group works as well as id
3563 * Tests the following formats
3564 * contact.get group=array('title1' => 1)
3565 * contact.get group=array('titke1' => 1, 'title2' => 1)
3566 * contact.get group=array('id1' => 1)
3567 * contact.get group=array('id1' => 1, id2 => 1)
3569 public function testContactGetWithGroupTitleMultipleGroupsLegacyFormat() {
3570 // Set up a contact, asser that they were created.
3571 $contact_params = array(
3572 'contact_type' => 'Individual',
3573 'first_name' => 'Test2',
3574 'last_name' => 'Groupmember',
3575 'email' => 'test@example.org',
3577 $create_contact = $this->callApiSuccess('Contact', 'create', $contact_params);
3578 $created_contact_id = $create_contact['id'];
3579 $createdGroupsTitles = $createdGroupsIds = array();
3580 // Set up multiple groups, add the contact to the groups.
3581 $test_groups = array('Test group C', 'Test group D');
3582 foreach ($test_groups as $title) {
3583 $group_params = array(
3585 'created_id' => $created_contact_id,
3587 $create_group = $this->callApiSuccess('Group', 'create', $group_params);
3588 $created_group_id = $create_group['id'];
3589 $createdGroupsIds[] = $create_group['id'];
3590 $createdGroupTitles[] = $title;
3591 // Add contact to the new group.
3592 $group_contact_params = array(
3593 'contact_id' => $created_contact_id,
3594 'group_id' => $create_group['id'],
3596 $create_group_contact = $this->callApiSuccess('GroupContact', 'create', $group_contact_params);
3598 $contact_get = $this->callAPISuccess('contact', 'get', array('group' => array($createdGroupTitles[0] => 1), 'return' => 'group'));
3599 $this->assertEquals(1, $contact_get['count']);
3600 $this->assertEquals($created_contact_id, $contact_get['id']);
3601 $contact_groups = explode(',', $contact_get['values'][$created_contact_id]['groups']);
3602 foreach ($createdGroupsIds as $id) {
3603 $this->assertContains((string) $id, $contact_groups);
3605 $contact_get2 = $this->callAPISuccess('contact', 'get', array('group' => array($createdGroupTitles[0] => 1, $createdGroupTitles[1] => 1), 'return' => 'group'));
3606 $this->assertEquals(1, $contact_get2['count']);
3607 $this->assertEquals($created_contact_id, $contact_get2['id']);
3608 $contact_groups2 = explode(',', $contact_get2['values'][$created_contact_id]['groups']);
3609 foreach ($createdGroupsIds as $id) {
3610 $this->assertContains((string) $id, $contact_groups2);
3612 $contact_get3 = $this->callAPISuccess('contact', 'get', array('group' => array($createdGroupsIds[0] => 1), 'return' => 'group'));
3613 $this->assertEquals($created_contact_id, $contact_get3['id']);
3614 $contact_groups3 = explode(',', $contact_get3['values'][$created_contact_id]['groups']);
3615 foreach ($createdGroupsIds as $id) {
3616 $this->assertContains((string) $id, $contact_groups3);
3618 $contact_get4 = $this->callAPISuccess('contact', 'get', array('group' => array($createdGroupsIds[0] => 1, $createdGroupsIds[1] => 1), 'return' => 'group'));
3619 $this->assertEquals($created_contact_id, $contact_get4['id']);
3620 $contact_groups4 = explode(',', $contact_get4['values'][$created_contact_id]['groups']);
3621 foreach ($createdGroupsIds as $id) {
3622 $this->assertContains((string) $id, $contact_groups4);
3624 foreach ($createdGroupsIds as $id) {
3625 $this->callAPISuccess('group', 'delete', array('id' => $id));
3627 $this->callAPISuccess('contact', 'delete', array('id' => $created_contact_id, 'skip_undelete' => TRUE));
3631 * Test the prox_distance functionality works.
3633 * This is primarily testing functionality in the BAO_Query object that 'happens to be'
3634 * accessible via the api.
3636 public function testContactGetProximity() {
3637 CRM_Core_Config
::singleton()->geocodeMethod
= 'CRM_Utils_MockGeocoder';
3638 $this->individualCreate();
3639 $contactID = $this->individualCreate();
3640 $this->callAPISuccess('Address', 'create', [
3641 'contact_id' => $contactID,
3643 'city' => 'Whangarei',
3644 'street_address' => 'Dent St',
3645 'geo_code_1' => '-35.8743325',
3646 'geo_code_2' => '174.4567136',
3647 'location_type_id' => 'Home',
3649 $contact = $this->callAPISuccess('Contact', 'get', [
3650 'prox_distance' => 100,
3651 'prox_geo_code_1' => '-35.72192',
3652 'prox_geo_code_2' => '174.32034',
3654 $this->assertEquals(1, $contact['count']);
3655 $this->assertEquals($contactID, $contact['id']);
3658 public function testLoggedInUserAPISupportToken() {
3659 $description = "Get contact id of the current logged in user";
3660 $subFile = "ContactIDOfLoggedInUserContactAPI";
3661 $cid = $this->createLoggedInUser();
3662 $contact = $this->callAPIAndDocument('contact', 'get', array('id' => 'user_contact_id'), __FUNCTION__
, __FILE__
, $description, $subFile);
3663 $this->assertEquals($cid, $contact['id']);
3670 protected function putGroupContactCacheInClearableState($groupID, $contact) {
3671 // We need to force the situation where there is invalid data in the cache and it
3672 // is due to be cleared.
3673 CRM_Core_DAO
::executeQuery("
3674 INSERT INTO civicrm_group_contact_cache (group_id, contact_id)
3675 VALUES ({$groupID}, {$contact['id']})
3677 CRM_Core_DAO
::executeQuery("UPDATE civicrm_group SET cache_date = '2017-01-01'");
3678 // Reset so it does not skip.
3679 Civi
::$statics['CRM_Contact_BAO_GroupContactCache']['is_refresh_init'] = FALSE;
3683 * CRM-21041 Test if 'communication style' is set to site default if not passed.
3685 public function testCreateCommunicationStyleUnset() {
3686 $this->callAPISuccess('Contact', 'create', array(
3687 'first_name' => 'John',
3688 'last_name' => 'Doe',
3689 'contact_type' => 'Individual')
3691 $result = $this->callAPISuccessGetSingle('Contact', array('last_name' => 'Doe'));
3692 $this->assertEquals(1, $result['communication_style_id']);
3696 * CRM-21041 Test if 'communication style' is set if value is passed.
3698 public function testCreateCommunicationStylePassed() {
3699 $this->callAPISuccess('Contact', 'create', array(
3700 'first_name' => 'John',
3701 'last_name' => 'Doe',
3702 'contact_type' => 'Individual',
3703 'communication_style_id' => 'Familiar',
3705 $result = $this->callAPISuccessGetSingle('Contact', array('last_name' => 'Doe'));
3707 'option_group_id' => 'communication_style',
3708 'label' => 'Familiar',
3709 'return' => 'value',
3711 $optionResult = civicrm_api3('OptionValue', 'get', $params);
3712 $communicationStyle = reset($optionResult['values']);
3713 $this->assertEquals($communicationStyle['value'], $result['communication_style_id']);
3717 * Test that creating a contact with various contact greetings works.
3719 public function testContactGreetingsCreate() {
3720 $contact = $this->callAPISuccess('Contact', 'create', array('first_name' => 'Alan', 'last_name' => 'MouseMouse', 'contact_type' => 'Individual'));
3721 $contact = $this->callAPISuccessGetSingle('Contact', array('id' => $contact['id'], 'return' => 'postal_greeting'));
3722 $this->assertEquals('Dear Alan', $contact['postal_greeting_display']);
3724 $contact = $this->callAPISuccess('Contact', 'create', array('id' => $contact['id'], 'postal_greeting_id' => 2));
3725 $contact = $this->callAPISuccessGetSingle('Contact', array('id' => $contact['id'], 'return' => 'postal_greeting'));
3726 $this->assertEquals('Dear Alan MouseMouse', $contact['postal_greeting_display']);
3728 $contact = $this->callAPISuccess('Contact', 'create', array('organization_name' => 'Alan\'s Show', 'contact_type' => 'Organization'));
3729 $contact = $this->callAPISuccessGetSingle('Contact', array('id' => $contact['id'], 'return' => 'postal_greeting, addressee, email_greeting'));
3730 $this->assertEquals('', $contact['postal_greeting_display']);
3731 $this->assertEquals('', $contact['email_greeting_display']);
3732 $this->assertEquals('Alan\'s Show', $contact['addressee_display']);
3736 * Test that creating a contact with various contact greetings works.
3738 public function testContactGreetingsCreateWithCustomField() {
3739 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__
, __FILE__
);
3740 $contact = $this->callAPISuccess('Contact', 'create', array('first_name' => 'Alan', 'contact_type' => 'Individual', 'custom_' . $ids['custom_field_id'] => 'Mice'));
3742 // Change postal greeting to involve a custom field.
3743 $postalOption = $this->callAPISuccessGetSingle('OptionValue', array('option_group_id' => 'postal_greeting', 'filter' => 1, 'is_default' => 1));
3744 $this->callAPISuccess('OptionValue', 'create', array(
3745 'id' => $postalOption['id'],
3746 'name' => 'Dear {contact.first_name} {contact.custom_' . $ids['custom_field_id'] . '}',
3747 'label' => 'Dear {contact.first_name} {contact.custom_' . $ids['custom_field_id'] . '}',
3750 // Update contact & see if postal greeting now reflects the new string.
3751 $this->callAPISuccess('Contact', 'create', array('id' => $contact['id'], 'last_name' => 'MouseyMousey'));
3752 $contact = $this->callAPISuccessGetSingle('Contact', array('id' => $contact['id'], 'return' => 'postal_greeting'));
3753 $this->assertEquals('Dear Alan Mice', $contact['postal_greeting_display']);
3755 // Set contact to have no postal greeting & check it is correct.
3756 $this->callAPISuccess('Contact', 'create', array('id' => $contact['id'], 'postal_greeting_id' => 'null'));
3757 $contact = $this->callAPISuccessGetSingle('Contact', array('id' => $contact['id'], 'return' => 'postal_greeting'));
3758 $this->assertEquals('', $contact['postal_greeting_display']);
3761 $this->callAPISuccess('OptionValue', 'create', array('id' => $postalOption['id'], 'name' => 'Dear {contact.first_name}'));
3762 $this->customFieldDelete($ids['custom_field_id']);
3763 $this->customGroupDelete($ids['custom_group_id']);
3767 * Test getunique api call for Contact entity
3769 public function testContactGetUnique() {
3770 $result = $this->callAPIAndDocument($this->_entity
, 'getunique', array(), __FUNCTION__
, __FILE__
);
3771 $this->assertEquals(1, $result['count']);
3772 $this->assertEquals(array('external_identifier'), $result['values']['UI_external_identifier']);