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,
1189 'api.website.create' => array(
1190 'url' => "http://civicrm.org",
1192 'api.website.create.2' => array(
1193 'url' => "http://chained.org",
1197 $result = $this->callAPIAndDocument('Contact', 'create', $params, __FUNCTION__
, __FILE__
, $description, $subFile);
1199 // checking child function result not covered in callAPIAndDocument
1200 $this->assertAPISuccess($result['values'][$result['id']]['api.website.create']);
1201 $this->assertEquals("http://chained.org", $result['values'][$result['id']]['api.website.create.2']['values'][0]['url']);
1202 $this->assertEquals("http://civicrm.org", $result['values'][$result['id']]['api.website.create']['values'][0]['url']);
1204 // delete the contact
1205 $this->callAPISuccess('contact', 'delete', $result);
1209 * Verify that attempt to create individual contact with chained contribution and website succeeds.
1211 public function testCreateIndividualWithContributionChainedArrays() {
1213 'first_name' => 'abc3',
1214 'last_name' => 'xyz3',
1215 'contact_type' => 'Individual',
1216 'email' => 'man3@yahoo.com',
1217 'api.contribution.create' => array(
1218 'receive_date' => '2010-01-01',
1219 'total_amount' => 100.00,
1220 'financial_type_id' => $this->_financialTypeId
,
1221 'payment_instrument_id' => 1,
1222 'non_deductible_amount' => 10.00,
1223 'fee_amount' => 50.00,
1224 'net_amount' => 90.00,
1226 'invoice_id' => 67890,
1228 'contribution_status_id' => 1,
1230 'api.website.create' => array(
1232 'url' => "http://civicrm.org",
1235 'url' => "http://chained.org",
1236 'website_type_id' => 2,
1241 $description = "Demonstrates creating two websites as an array.";
1242 $subfile = "ChainTwoWebsitesSyntax2";
1243 $result = $this->callAPIAndDocument('Contact', 'create', $params, __FUNCTION__
, __FILE__
, $description, $subfile);
1245 // the callAndDocument doesn't check the chained call
1246 $this->assertEquals(0, $result['values'][$result['id']]['api.website.create'][0]['is_error']);
1247 $this->assertEquals("http://chained.org", $result['values'][$result['id']]['api.website.create'][1]['values'][0]['url']);
1248 $this->assertEquals("http://civicrm.org", $result['values'][$result['id']]['api.website.create'][0]['values'][0]['url']);
1250 $this->callAPISuccess('contact', 'delete', $result);
1254 * Test for direction when chaining relationships.
1256 * https://issues.civicrm.org/jira/browse/CRM-16084
1258 public function testDirectionChainingRelationshipsCRM16084() {
1259 // Some contact, called Jules.
1260 $create_result_1 = $this->callAPISuccess('contact', 'create', array(
1261 'first_name' => 'Jules',
1262 'last_name' => 'Smos',
1263 'contact_type' => 'Individual',
1266 // Another contact: Jos, child of Jules.
1267 $create_params = array(
1268 'first_name' => 'Jos',
1269 'last_name' => 'Smos',
1270 'contact_type' => 'Individual',
1271 'api.relationship.create' => array(
1273 'contact_id_a' => '$value.id',
1274 'contact_id_b' => $create_result_1['id'],
1276 'relationship_type_id' => 1,
1280 $create_result_2 = $this->callAPISuccess('contact', 'create', $create_params);
1282 // Mia is the child of Jos.
1283 $create_params = array(
1284 'first_name' => 'Mia',
1285 'last_name' => 'Smos',
1286 'contact_type' => 'Individual',
1287 'api.relationship.create' => array(
1289 'contact_id_a' => '$value.id',
1290 'contact_id_b' => $create_result_2['id'],
1292 'relationship_type_id' => 1,
1296 $create_result_3 = $this->callAPISuccess('contact', 'create', $create_params);
1298 // Get Jos and his children.
1299 $get_params = array(
1301 'id' => $create_result_2['id'],
1302 'api.relationship.get' => array(
1303 'contact_id_b' => '$value.id',
1304 'relationship_type_id' => 1,
1307 $get_result = $this->callAPISuccess('contact', 'getsingle', $get_params);
1310 $this->callAPISuccess('contact', 'delete', array(
1311 'id' => $create_result_1['id'],
1313 $this->callAPISuccess('contact', 'delete', array(
1314 'id' => $create_result_2['id'],
1316 $this->callAPISuccess('contact', 'delete', array(
1317 'id' => $create_result_2['id'],
1321 $this->assertEquals(1, $get_result['api.relationship.get']['count']);
1322 $this->assertEquals($create_result_3['id'], $get_result['api.relationship.get']['values'][0]['contact_id_a']);
1326 * Verify that attempt to create individual contact with first, and last names and email succeeds.
1328 public function testCreateIndividualWithNameEmail() {
1330 'first_name' => 'abc3',
1331 'last_name' => 'xyz3',
1332 'contact_type' => 'Individual',
1333 'email' => 'man3@yahoo.com',
1336 $contact = $this->callAPISuccess('contact', 'create', $params);
1338 $this->callAPISuccess('contact', 'delete', $contact);
1342 * Verify that attempt to create individual contact with no data fails.
1344 public function testCreateIndividualWithOutNameEmail() {
1346 'contact_type' => 'Individual',
1348 $this->callAPIFailure('contact', 'create', $params);
1352 * Test create individual contact with first &last names, email and location type succeeds.
1354 public function testCreateIndividualWithNameEmailLocationType() {
1356 'first_name' => 'abc4',
1357 'last_name' => 'xyz4',
1358 'email' => 'man4@yahoo.com',
1359 'contact_type' => 'Individual',
1360 'location_type_id' => 1,
1362 $result = $this->callAPISuccess('contact', 'create', $params);
1364 $this->callAPISuccess('contact', 'delete', array('id' => $result['id']));
1368 * Verify that when changing employers the old employer relationship becomes inactive.
1370 public function testCreateIndividualWithEmployer() {
1371 $employer = $this->organizationCreate();
1372 $employer2 = $this->organizationCreate();
1375 'email' => 'man4@yahoo.com',
1376 'contact_type' => 'Individual',
1377 'employer_id' => $employer,
1380 $result = $this->callAPISuccess('contact', 'create', $params);
1381 $relationships = $this->callAPISuccess('relationship', 'get', array(
1382 'contact_id_a' => $result['id'],
1386 $this->assertEquals($employer, $relationships['values'][0]['contact_id_b']);
1388 // Add more random relationships to make the test more realistic
1389 foreach (array('Employee of', 'Volunteer for') as $relationshipType) {
1390 $relTypeId = CRM_Core_DAO
::getFieldValue('CRM_Contact_DAO_RelationshipType', $relationshipType, 'id', 'name_a_b');
1391 $this->callAPISuccess('relationship', 'create', array(
1392 'contact_id_a' => $result['id'],
1393 'contact_id_b' => $this->organizationCreate(),
1395 'relationship_type_id' => $relTypeId,
1399 // Add second employer
1400 $params['employer_id'] = $employer2;
1401 $params['id'] = $result['id'];
1402 $result = $this->callAPISuccess('contact', 'create', $params);
1404 $relationships = $this->callAPISuccess('relationship', 'get', array(
1405 'contact_id_a' => $result['id'],
1410 $this->assertEquals($employer, $relationships['values'][0]['contact_id_b']);
1414 * Verify that attempt to create household contact with details succeeds.
1416 public function testCreateHouseholdDetails() {
1418 'household_name' => 'abc8\'s House',
1419 'nick_name' => 'x House',
1420 'email' => 'man8@yahoo.com',
1421 'contact_type' => 'Household',
1424 $contact = $this->callAPISuccess('contact', 'create', $params);
1426 $this->callAPISuccess('contact', 'delete', $contact);
1430 * Verify that attempt to create household contact with inadequate details fails.
1432 public function testCreateHouseholdInadequateDetails() {
1434 'nick_name' => 'x House',
1435 'email' => 'man8@yahoo.com',
1436 'contact_type' => 'Household',
1438 $this->callAPIFailure('contact', 'create', $params);
1442 * Verify successful update of individual contact.
1444 public function testUpdateIndividualWithAll() {
1445 // Insert a row in civicrm_contact creating individual contact.
1446 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1447 $op->execute($this->_dbconn
,
1448 $this->createXMLDataSet(
1449 dirname(__FILE__
) . '/dataset/contact_ind.xml'
1455 'first_name' => 'abcd',
1456 'contact_type' => 'Individual',
1457 'nick_name' => 'This is nickname first',
1458 'do_not_email' => '1',
1459 'do_not_phone' => '1',
1460 'do_not_mail' => '1',
1461 'do_not_trade' => '1',
1462 'legal_identifier' => 'ABC23853ZZ2235',
1463 'external_identifier' => '1928837465',
1464 'image_URL' => 'http://some.url.com/image.jpg',
1465 'home_url' => 'http://www.example.org',
1469 $this->callAPISuccess('Contact', 'Update', $params);
1470 $getResult = $this->callAPISuccess('Contact', 'Get', $params);
1471 unset($params['contact_id']);
1472 //Todo - neither API v2 or V3 are testing for home_url - not sure if it is being set.
1473 //reducing this test partially back to api v2 level to get it through
1474 unset($params['home_url']);
1475 foreach ($params as $key => $value) {
1476 $this->assertEquals($value, $getResult['values'][23][$key]);
1478 // Check updated civicrm_contact against expected.
1479 $expected = $this->createXMLDataSet(
1480 dirname(__FILE__
) . '/dataset/contact_ind_upd.xml'
1482 $actual = new PHPUnit_Extensions_Database_DataSet_QueryDataSet(
1485 $actual->addTable('civicrm_contact');
1486 $expected->matches($actual);
1490 * Verify successful update of organization contact.
1492 public function testUpdateOrganizationWithAll() {
1493 // Insert a row in civicrm_contact creating organization contact
1494 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1495 $op->execute($this->_dbconn
,
1496 $this->createXMLDataSet(
1497 dirname(__FILE__
) . '/dataset/contact_org.xml'
1503 'organization_name' => 'WebAccess India Pvt Ltd',
1504 'legal_name' => 'WebAccess',
1505 'sic_code' => 'ABC12DEF',
1506 'contact_type' => 'Organization',
1509 $this->callAPISuccess('Contact', 'Update', $params);
1511 // Check updated civicrm_contact against expected.
1512 $expected = $this->createXMLDataSet(
1513 dirname(__FILE__
) . '/dataset/contact_org_upd.xml'
1515 $actual = new PHPUnit_Extensions_Database_DataSet_QueryDataSet(
1518 $actual->addTable('civicrm_contact');
1519 $expected->matches($actual);
1523 * Verify successful update of household contact.
1525 public function testUpdateHouseholdWithAll() {
1526 // Insert a row in civicrm_contact creating household contact
1527 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1528 $op->execute($this->_dbconn
,
1529 $this->createXMLDataSet(
1530 dirname(__FILE__
) . '/dataset/contact_hld.xml'
1536 'household_name' => 'ABC household',
1537 'nick_name' => 'ABC House',
1538 'contact_type' => 'Household',
1541 $result = $this->callAPISuccess('Contact', 'Update', $params);
1544 'contact_type' => 'Household',
1546 'sort_name' => 'ABC household',
1547 'display_name' => 'ABC household',
1548 'nick_name' => 'ABC House',
1550 $this->getAndCheck($expected, $result['id'], 'contact');
1554 * Test civicrm_update() without contact type.
1556 * Deliberately exclude contact_type as it should still cope using civicrm_api.
1560 public function testUpdateCreateWithID() {
1561 // Insert a row in civicrm_contact creating individual contact.
1562 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1563 $op->execute($this->_dbconn
,
1564 $this->createXMLDataSet(
1565 dirname(__FILE__
) . '/dataset/contact_ind.xml'
1571 'first_name' => 'abcd',
1572 'last_name' => 'wxyz',
1574 $this->callAPISuccess('Contact', 'Update', $params);
1578 * Test civicrm_contact_delete() with no contact ID.
1580 public function testContactDeleteNoID() {
1584 $this->callAPIFailure('contact', 'delete', $params);
1588 * Test civicrm_contact_delete() with error.
1590 public function testContactDeleteError() {
1591 $params = array('contact_id' => 999);
1592 $this->callAPIFailure('contact', 'delete', $params);
1596 * Test civicrm_contact_delete().
1598 public function testContactDelete() {
1599 $contactID = $this->individualCreate();
1603 $this->callAPIAndDocument('contact', 'delete', $params, __FUNCTION__
, __FILE__
);
1607 * Test civicrm_contact_get() return only first name.
1609 public function testContactGetRetFirst() {
1610 $contact = $this->callAPISuccess('contact', 'create', $this->_params
);
1612 'contact_id' => $contact['id'],
1613 'return_first_name' => TRUE,
1614 'sort' => 'first_name',
1616 $result = $this->callAPISuccess('contact', 'get', $params);
1617 $this->assertEquals(1, $result['count']);
1618 $this->assertEquals($contact['id'], $result['id']);
1619 $this->assertEquals('abc1', $result['values'][$contact['id']]['first_name']);
1623 * Test civicrm_contact_get() return only first name & last name.
1625 * Use comma separated string return with a space.
1627 public function testContactGetReturnFirstLast() {
1628 $contact = $this->callAPISuccess('contact', 'create', $this->_params
);
1630 'contact_id' => $contact['id'],
1631 'return' => 'first_name, last_name',
1633 $result = $this->callAPISuccess('contact', 'getsingle', $params);
1634 $this->assertEquals('abc1', $result['first_name']);
1635 $this->assertEquals('xyz1', $result['last_name']);
1636 //check that other defaults not returns
1637 $this->assertArrayNotHasKey('sort_name', $result);
1639 'contact_id' => $contact['id'],
1640 'return' => 'first_name,last_name',
1642 $result = $this->callAPISuccess('contact', 'getsingle', $params);
1643 $this->assertEquals('abc1', $result['first_name']);
1644 $this->assertEquals('xyz1', $result['last_name']);
1645 //check that other defaults not returns
1646 $this->assertArrayNotHasKey('sort_name', $result);
1650 * Test civicrm_contact_get() return only first name & last name.
1652 * Use comma separated string return without a space
1654 public function testContactGetReturnFirstLastNoComma() {
1655 $contact = $this->callAPISuccess('contact', 'create', $this->_params
);
1657 'contact_id' => $contact['id'],
1658 'return' => 'first_name,last_name',
1660 $result = $this->callAPISuccess('contact', 'getsingle', $params);
1661 $this->assertEquals('abc1', $result['first_name']);
1662 $this->assertEquals('xyz1', $result['last_name']);
1663 //check that other defaults not returns
1664 $this->assertArrayNotHasKey('sort_name', $result);
1668 * Test civicrm_contact_get() with default return properties.
1670 public function testContactGetRetDefault() {
1671 $contactID = $this->individualCreate();
1673 'contact_id' => $contactID,
1674 'sort' => 'first_name',
1676 $result = $this->callAPISuccess('contact', 'get', $params);
1677 $this->assertEquals($contactID, $result['values'][$contactID]['contact_id']);
1678 $this->assertEquals('Anthony', $result['values'][$contactID]['first_name']);
1682 * Test civicrm_contact_getquick() with empty name param.
1684 public function testContactGetQuick() {
1685 // Insert a row in civicrm_contact creating individual contact.
1686 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1687 $op->execute($this->_dbconn
,
1688 $this->createXMLDataSet(
1689 dirname(__FILE__
) . '/dataset/contact_17.xml'
1692 $op->execute($this->_dbconn
,
1693 $this->createXMLDataSet(
1694 dirname(__FILE__
) . '/dataset/email_contact_17.xml'
1701 $result = $this->callAPISuccess('contact', 'getquick', $params);
1702 $this->assertEquals(17, $result['values'][0]['id']);
1706 * Test civicrm_contact_get) with empty params.
1708 public function testContactGetEmptyParams() {
1709 $this->callAPISuccess('contact', 'get', array());
1713 * Test civicrm_contact_get(,true) with no matches.
1715 public function testContactGetOldParamsNoMatches() {
1716 // Insert a row in civicrm_contact creating contact 17.
1717 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1718 $op->execute($this->_dbconn
,
1719 $this->createXMLDataSet(
1720 dirname(__FILE__
) . '/dataset/contact_17.xml'
1725 'first_name' => 'Fred',
1727 $result = $this->callAPISuccess('contact', 'get', $params);
1728 $this->assertEquals(0, $result['count']);
1732 * Test civicrm_contact_get(,true) with one match.
1734 public function testContactGetOldParamsOneMatch() {
1735 // Insert a row in civicrm_contact creating contact 17
1736 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1737 $op->execute($this->_dbconn
,
1738 $this->createXMLDataSet(dirname(__FILE__
) . '/dataset/contact_17.xml'
1743 'first_name' => 'Test',
1745 $result = $this->callAPISuccess('contact', 'get', $params);
1746 $this->assertEquals(17, $result['values'][17]['contact_id']);
1747 $this->assertEquals(17, $result['id']);
1751 * Test civicrm_contact_search_count().
1753 public function testContactGetEmail() {
1755 'email' => 'man2@yahoo.com',
1756 'contact_type' => 'Individual',
1757 'location_type_id' => 1,
1760 $contact = $this->callAPISuccess('contact', 'create', $params);
1763 'email' => 'man2@yahoo.com',
1765 $result = $this->callAPIAndDocument('contact', 'get', $params, __FUNCTION__
, __FILE__
);
1766 $this->assertEquals('man2@yahoo.com', $result['values'][$result['id']]['email']);
1768 $this->callAPISuccess('contact', 'delete', $contact);
1772 * Ensure consistent return format for option group fields.
1774 public function testSetPreferredCommunicationNull() {
1775 $contact = $this->callAPISuccess('contact', 'create', array_merge($this->_params
, array(
1776 'preferred_communication_method' => array('Phone', 'SMS'),
1778 $preferredCommunicationMethod = $this->callAPISuccessGetValue('Contact', array(
1779 'id' => $contact['id'],
1780 'return' => 'preferred_communication_method',
1782 $this->assertNotEmpty($preferredCommunicationMethod);
1783 $contact = $this->callAPISuccess('contact', 'create', array_merge($this->_params
, array(
1784 'preferred_communication_method' => 'null',
1785 'id' => $contact['id'],
1787 $preferredCommunicationMethod = $this->callAPISuccessGetValue('Contact', array(
1788 'id' => $contact['id'],
1789 'return' => 'preferred_communication_method',
1791 $this->assertEmpty($preferredCommunicationMethod);
1795 * Ensure consistent return format for option group fields.
1797 public function testPseudoFields() {
1799 'preferred_communication_method' => array('Phone', 'SMS'),
1800 'preferred_language' => 'en_US',
1801 'gender_id' => 'Female',
1802 'prefix_id' => 'Mrs.',
1803 'suffix_id' => 'II',
1804 'communication_style_id' => 'Formal',
1807 $contact = $this->callAPISuccess('contact', 'create', array_merge($this->_params
, $params));
1809 $result = $this->callAPISuccess('contact', 'getsingle', array('id' => $contact['id']));
1810 $this->assertEquals('Both', $result['preferred_mail_format']);
1812 $this->assertEquals('en_US', $result['preferred_language']);
1813 $this->assertEquals(1, $result['communication_style_id']);
1814 $this->assertEquals(1, $result['gender_id']);
1815 $this->assertEquals('Female', $result['gender']);
1816 $this->assertEquals('Mrs.', $result['individual_prefix']);
1817 $this->assertEquals(1, $result['prefix_id']);
1818 $this->assertEquals('II', $result['individual_suffix']);
1819 $this->assertEquals(CRM_Core_PseudoConstant
::getKey("CRM_Contact_BAO_Contact", 'suffix_id', 'II'), $result['suffix_id']);
1820 $this->callAPISuccess('contact', 'delete', $contact);
1821 $this->assertEquals(array(
1822 CRM_Core_PseudoConstant
::getKey("CRM_Contact_BAO_Contact", 'preferred_communication_method', 'Phone'),
1823 CRM_Core_PseudoConstant
::getKey("CRM_Contact_BAO_Contact", 'preferred_communication_method', 'SMS'),
1824 ), $result['preferred_communication_method']);
1829 * Test birth date parameters.
1831 * These include value, array & birth_date_high, birth_date_low
1834 public function testContactGetBirthDate() {
1835 $contact1 = $this->callAPISuccess('contact', 'create', array_merge($this->_params
, array('birth_date' => 'first day of next month - 2 years')));
1836 $contact2 = $this->callAPISuccess('contact', 'create', array_merge($this->_params
, array('birth_date' => 'first day of next month - 5 years')));
1837 $contact3 = $this->callAPISuccess('contact', 'create', array_merge($this->_params
, array('birth_date' => 'first day of next month -20 years')));
1839 $result = $this->callAPISuccess('contact', 'get', array());
1840 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -2 years')), $result['values'][$contact1['id']]['birth_date']);
1841 $result = $this->callAPISuccess('contact', 'get', array('birth_date' => 'first day of next month -5 years'));
1842 $this->assertEquals(1, $result['count']);
1843 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -5 years')), $result['values'][$contact2['id']]['birth_date']);
1844 $result = $this->callAPISuccess('contact', 'get', array('birth_date_high' => date('Y-m-d', strtotime('-6 years'))));
1845 $this->assertEquals(1, $result['count']);
1846 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -20 years')), $result['values'][$contact3['id']]['birth_date']);
1847 $result = $this->callAPISuccess('contact', 'get', array(
1848 'birth_date_low' => date('Y-m-d', strtotime('-6 years')),
1849 'birth_date_high' => date('Y-m-d', strtotime('- 3 years')),
1851 $this->assertEquals(1, $result['count']);
1852 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -5 years')), $result['values'][$contact2['id']]['birth_date']);
1853 $result = $this->callAPISuccess('contact', 'get', array(
1854 'birth_date_low' => '-6 years',
1855 'birth_date_high' => '- 3 years',
1857 $this->assertEquals(1, $result['count']);
1858 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -5 years')), $result['values'][$contact2['id']]['birth_date']);
1862 * Test Address parameters
1864 * This include state_province, state_province_name, country
1866 public function testContactGetWithAddressFields() {
1867 $individuals = array(
1869 'first_name' => 'abc1',
1870 'contact_type' => 'Individual',
1871 'last_name' => 'xyz1',
1872 'api.address.create' => array(
1873 'country' => 'United States',
1874 'state_province_id' => 'Michigan',
1875 'location_type_id' => 1,
1879 'first_name' => 'abc2',
1880 'contact_type' => 'Individual',
1881 'last_name' => 'xyz2',
1882 'api.address.create' => array(
1883 'country' => 'United States',
1884 'state_province_id' => 'Alabama',
1885 'location_type_id' => 1,
1889 foreach ($individuals as $params) {
1890 $contact = $this->callAPISuccess('contact', 'create', $params);
1893 // Check whether Contact get API return successfully with below Address params.
1894 $fieldsToTest = array(
1895 'state_province_name' => 'Michigan',
1896 'state_province' => 'Michigan',
1897 'country' => 'United States',
1898 'state_province_name' => array('IN' => array('Michigan', 'Alabama')),
1899 'state_province' => array('IN' => array('Michigan', 'Alabama')),
1901 foreach ($fieldsToTest as $field => $value) {
1903 'id' => $contact['id'],
1906 $result = $this->callAPISuccess('Contact', 'get', $getParams);
1907 $this->assertEquals(1, $result['count']);
1912 * Test Deceased date parameters.
1914 * These include value, array & Deceased_date_high, Deceased date_low
1917 public function testContactGetDeceasedDate() {
1918 $contact1 = $this->callAPISuccess('contact', 'create', array_merge($this->_params
, array('deceased_date' => 'first day of next month - 2 years')));
1919 $contact2 = $this->callAPISuccess('contact', 'create', array_merge($this->_params
, array('deceased_date' => 'first day of next month - 5 years')));
1920 $contact3 = $this->callAPISuccess('contact', 'create', array_merge($this->_params
, array('deceased_date' => 'first day of next month -20 years')));
1922 $result = $this->callAPISuccess('contact', 'get', array());
1923 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -2 years')), $result['values'][$contact1['id']]['deceased_date']);
1924 $result = $this->callAPISuccess('contact', 'get', array('deceased_date' => 'first day of next month -5 years'));
1925 $this->assertEquals(1, $result['count']);
1926 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -5 years')), $result['values'][$contact2['id']]['deceased_date']);
1927 $result = $this->callAPISuccess('contact', 'get', array('deceased_date_high' => date('Y-m-d', strtotime('-6 years'))));
1928 $this->assertEquals(1, $result['count']);
1929 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -20 years')), $result['values'][$contact3['id']]['deceased_date']);
1930 $result = $this->callAPISuccess('contact', 'get', array(
1931 'deceased_date_low' => '-6 years',
1932 'deceased_date_high' => date('Y-m-d', strtotime('- 3 years')),
1934 $this->assertEquals(1, $result['count']);
1935 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -5 years')), $result['values'][$contact2['id']]['deceased_date']);
1939 * Test for Contact.get id=@user:username.
1941 public function testContactGetByUsername() {
1942 // Setup - create contact with a uf-match.
1943 $cid = $this->individualCreate(array(
1944 'contact_type' => 'Individual',
1945 'first_name' => 'testGetByUsername',
1946 'last_name' => 'testGetByUsername',
1949 $ufMatchParams = array(
1950 'domain_id' => CRM_Core_Config
::domainID(),
1952 'uf_name' => 'the-email-matching-key-is-not-really-the-username',
1953 'contact_id' => $cid,
1955 $ufMatch = CRM_Core_BAO_UFMatch
::create($ufMatchParams);
1956 $this->assertTrue(is_numeric($ufMatch->id
));
1958 // setup - mock the calls to CRM_Utils_System_*::getUfId
1959 $userSystem = $this->getMock('CRM_Utils_System_UnitTests', array('getUfId'));
1960 $userSystem->expects($this->once())
1962 ->with($this->equalTo('exampleUser'))
1963 ->will($this->returnValue(99));
1964 CRM_Core_Config
::singleton()->userSystem
= $userSystem;
1967 $result = $this->callAPISuccess('Contact', 'get', array(
1968 'id' => '@user:exampleUser',
1970 $this->assertEquals('testGetByUsername', $result['values'][$cid]['first_name']);
1974 * Test to check return works OK.
1976 public function testContactGetReturnValues() {
1977 $extraParams = array(
1978 'nick_name' => 'Bob',
1980 'email' => 'e@mail.com',
1982 $contactID = $this->individualCreate($extraParams);
1983 //actually it turns out the above doesn't create a phone
1984 $this->callAPISuccess('phone', 'create', array('contact_id' => $contactID, 'phone' => '456'));
1985 $result = $this->callAPISuccess('contact', 'getsingle', array('id' => $contactID));
1986 foreach ($extraParams as $key => $value) {
1987 $this->assertEquals($result[$key], $value);
1989 //now we check they are still returned with 'return' key
1990 $result = $this->callAPISuccess('contact', 'getsingle', array(
1992 'return' => array_keys($extraParams),
1994 foreach ($extraParams as $key => $value) {
1995 $this->assertEquals($result[$key], $value);
2000 * Test creating multiple phones using chaining.
2002 * @throws \Exception
2004 public function testCRM13252MultipleChainedPhones() {
2005 $contactID = $this->householdCreate();
2006 $this->callAPISuccessGetCount('phone', array('contact_id' => $contactID), 0);
2008 'contact_id' => $contactID,
2009 'household_name' => 'Household 1',
2010 'contact_type' => 'Household',
2011 'api.phone.create' => array(
2013 'phone' => '111-111-1111',
2014 'location_type_id' => 1,
2015 'phone_type_id' => 1,
2018 'phone' => '222-222-2222',
2019 'location_type_id' => 1,
2020 'phone_type_id' => 2,
2024 $this->callAPISuccess('contact', 'create', $params);
2025 $this->callAPISuccessGetCount('phone', array('contact_id' => $contactID), 2);
2030 * Test for Contact.get id=@user:username (with an invalid username).
2032 public function testContactGetByUnknownUsername() {
2033 // setup - mock the calls to CRM_Utils_System_*::getUfId
2034 $userSystem = $this->getMock('CRM_Utils_System_UnitTests', array('getUfId'));
2035 $userSystem->expects($this->once())
2037 ->with($this->equalTo('exampleUser'))
2038 ->will($this->returnValue(NULL));
2039 CRM_Core_Config
::singleton()->userSystem
= $userSystem;
2042 $result = $this->callAPIFailure('Contact', 'get', array(
2043 'id' => '@user:exampleUser',
2045 $this->assertRegExp('/cannot be resolved to a contact ID/', $result['error_message']);
2049 * Verify attempt to create individual with chained arrays and sequential.
2051 public function testGetIndividualWithChainedArraysAndSequential() {
2052 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__
, __FILE__
);
2053 $params['custom_' . $ids['custom_field_id']] = "custom string";
2055 $moreIDs = $this->CustomGroupMultipleCreateWithFields();
2058 'first_name' => 'abc3',
2059 'last_name' => 'xyz3',
2060 'contact_type' => 'Individual',
2061 'email' => 'man3@yahoo.com',
2062 'api.website.create' => array(
2064 'url' => "http://civicrm.org",
2067 'url' => "https://civicrm.org",
2072 $result = $this->callAPISuccess('Contact', 'create', $params);
2074 // delete the contact and custom groups
2075 $this->callAPISuccess('contact', 'delete', array('id' => $result['id']));
2076 $this->customGroupDelete($ids['custom_group_id']);
2077 $this->customGroupDelete($moreIDs['custom_group_id']);
2079 $this->assertEquals($result['id'], $result['values'][0]['id']);
2080 $this->assertArrayKeyExists('api.website.create', $result['values'][0]);
2084 * Verify attempt to create individual with chained arrays.
2086 public function testGetIndividualWithChainedArrays() {
2087 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__
, __FILE__
);
2088 $params['custom_' . $ids['custom_field_id']] = "custom string";
2090 $moreIDs = $this->CustomGroupMultipleCreateWithFields();
2091 $description = "This demonstrates the usage of chained api functions.\nIn this case no notes or custom fields have been created.";
2092 $subfile = "APIChainedArray";
2094 'first_name' => 'abc3',
2095 'last_name' => 'xyz3',
2096 'contact_type' => 'Individual',
2097 'email' => 'man3@yahoo.com',
2098 'api.contribution.create' => array(
2099 'receive_date' => '2010-01-01',
2100 'total_amount' => 100.00,
2101 'financial_type_id' => 1,
2102 'payment_instrument_id' => 1,
2103 'non_deductible_amount' => 10.00,
2104 'fee_amount' => 50.00,
2105 'net_amount' => 90.00,
2107 'invoice_id' => 67890,
2109 'contribution_status_id' => 1,
2111 'api.contribution.create.1' => array(
2112 'receive_date' => '2011-01-01',
2113 'total_amount' => 120.00,
2114 'financial_type_id' => $this->_financialTypeId
= 1,
2115 'payment_instrument_id' => 1,
2116 'non_deductible_amount' => 10.00,
2117 'fee_amount' => 50.00,
2118 'net_amount' => 90.00,
2120 'invoice_id' => 67830,
2122 'contribution_status_id' => 1,
2124 'api.website.create' => array(
2126 'url' => "http://civicrm.org",
2131 $result = $this->callAPISuccess('Contact', 'create', $params);
2133 'id' => $result['id'],
2134 'api.website.get' => array(),
2135 'api.Contribution.get' => array(
2136 'total_amount' => '120.00',
2138 'api.CustomValue.get' => 1,
2139 'api.Note.get' => 1,
2141 $result = $this->callAPIAndDocument('Contact', 'Get', $params, __FUNCTION__
, __FILE__
, $description, $subfile);
2142 // delete the contact
2143 $this->callAPISuccess('contact', 'delete', $result);
2144 $this->customGroupDelete($ids['custom_group_id']);
2145 $this->customGroupDelete($moreIDs['custom_group_id']);
2146 $this->assertEquals(0, $result['values'][$result['id']]['api.website.get']['is_error']);
2147 $this->assertEquals("http://civicrm.org", $result['values'][$result['id']]['api.website.get']['values'][0]['url']);
2151 * Verify attempt to create individual with chained arrays and sequential.
2153 * See https://issues.civicrm.org/jira/browse/CRM-15815
2155 public function testCreateIndividualWithChainedArrayAndSequential() {
2158 'first_name' => 'abc5',
2159 'last_name' => 'xyz5',
2160 'contact_type' => 'Individual',
2161 'email' => 'woman5@yahoo.com',
2162 'api.phone.create' => array(
2163 array('phone' => '03-231 07 95'),
2164 array('phone' => '03-232 51 62'),
2166 'api.website.create' => array(
2167 'url' => 'http://civicrm.org',
2170 $result = $this->callAPISuccess('Contact', 'create', $params);
2172 // I could try to parse the result to see whether the two phone numbers
2173 // and the website are there, but I am not sure about the correct format.
2174 // So I will just fetch it again before checking.
2175 // See also http://forum.civicrm.org/index.php/topic,35393.0.html
2178 'id' => $result['id'],
2179 'api.website.get' => array(),
2180 'api.phone.get' => array(),
2182 $result = $this->callAPISuccess('Contact', 'get', $params);
2184 // delete the contact
2185 $this->callAPISuccess('contact', 'delete', $result);
2187 $this->assertEquals(2, $result['values'][0]['api.phone.get']['count']);
2188 $this->assertEquals(1, $result['values'][0]['api.website.get']['count']);
2192 * Test retrieving an individual with chained array syntax.
2194 public function testGetIndividualWithChainedArraysFormats() {
2195 $description = "This demonstrates the usage of chained api functions.\nIn this case no notes or custom fields have been created.";
2196 $subfile = "APIChainedArrayFormats";
2197 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__
, __FILE__
);
2198 $params['custom_' . $ids['custom_field_id']] = "custom string";
2200 $moreIDs = $this->CustomGroupMultipleCreateWithFields();
2202 'first_name' => 'abc3',
2203 'last_name' => 'xyz3',
2204 'contact_type' => 'Individual',
2205 'email' => 'man3@yahoo.com',
2206 'api.contribution.create' => array(
2207 'receive_date' => '2010-01-01',
2208 'total_amount' => 100.00,
2209 'financial_type_id' => $this->_financialTypeId
,
2210 'payment_instrument_id' => 1,
2211 'non_deductible_amount' => 10.00,
2212 'fee_amount' => 50.00,
2213 'net_amount' => 90.00,
2215 'contribution_status_id' => 1,
2217 'api.contribution.create.1' => array(
2218 'receive_date' => '2011-01-01',
2219 'total_amount' => 120.00,
2220 'financial_type_id' => $this->_financialTypeId
,
2221 'payment_instrument_id' => 1,
2222 'non_deductible_amount' => 10.00,
2223 'fee_amount' => 50.00,
2224 'net_amount' => 90.00,
2226 'contribution_status_id' => 1,
2228 'api.website.create' => array(
2230 'url' => "http://civicrm.org",
2235 $result = $this->callAPISuccess('Contact', 'create', $params);
2237 'id' => $result['id'],
2238 'api.website.getValue' => array('return' => 'url'),
2239 'api.Contribution.getCount' => array(),
2240 'api.CustomValue.get' => 1,
2241 'api.Note.get' => 1,
2242 'api.Membership.getCount' => array(),
2244 $result = $this->callAPIAndDocument('Contact', 'Get', $params, __FUNCTION__
, __FILE__
, $description, $subfile);
2245 $this->assertEquals(2, $result['values'][$result['id']]['api.Contribution.getCount']);
2246 $this->assertEquals(0, $result['values'][$result['id']]['api.Note.get']['is_error']);
2247 $this->assertEquals("http://civicrm.org", $result['values'][$result['id']]['api.website.getValue']);
2249 $this->callAPISuccess('contact', 'delete', $result);
2250 $this->customGroupDelete($ids['custom_group_id']);
2251 $this->customGroupDelete($moreIDs['custom_group_id']);
2255 * Test complex chaining.
2257 public function testGetIndividualWithChainedArraysAndMultipleCustom() {
2258 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__
, __FILE__
);
2259 $params['custom_' . $ids['custom_field_id']] = "custom string";
2260 $moreIDs = $this->CustomGroupMultipleCreateWithFields();
2261 $andMoreIDs = $this->CustomGroupMultipleCreateWithFields(array(
2262 'title' => "another group",
2263 'name' => 'another name',
2265 $description = "This demonstrates the usage of chained api functions with multiple custom fields.";
2266 $subfile = "APIChainedArrayMultipleCustom";
2268 'first_name' => 'abc3',
2269 'last_name' => 'xyz3',
2270 'contact_type' => 'Individual',
2271 'email' => 'man3@yahoo.com',
2272 'api.contribution.create' => array(
2273 'receive_date' => '2010-01-01',
2274 'total_amount' => 100.00,
2275 'financial_type_id' => 1,
2276 'payment_instrument_id' => 1,
2277 'non_deductible_amount' => 10.00,
2278 'fee_amount' => 50.00,
2279 'net_amount' => 90.00,
2281 'invoice_id' => 67890,
2283 'contribution_status_id' => 1,
2285 'api.contribution.create.1' => array(
2286 'receive_date' => '2011-01-01',
2287 'total_amount' => 120.00,
2288 'financial_type_id' => 1,
2289 'payment_instrument_id' => 1,
2290 'non_deductible_amount' => 10.00,
2291 'fee_amount' => 50.00,
2292 'net_amount' => 90.00,
2294 'invoice_id' => 67830,
2296 'contribution_status_id' => 1,
2298 'api.website.create' => array(
2300 'url' => "http://civicrm.org",
2303 'custom_' . $ids['custom_field_id'] => "value 1",
2304 'custom_' . $moreIDs['custom_field_id'][0] => "value 2",
2305 'custom_' . $moreIDs['custom_field_id'][1] => "warm beer",
2306 'custom_' . $andMoreIDs['custom_field_id'][1] => "vegemite",
2309 $result = $this->callAPISuccess('Contact', 'create', $params);
2310 $result = $this->callAPISuccess('Contact', 'create', array(
2311 'contact_type' => 'Individual',
2312 'id' => $result['id'],
2314 $moreIDs['custom_field_id'][0] => "value 3",
2316 $ids['custom_field_id'] => "value 4",
2320 'id' => $result['id'],
2321 'api.website.getValue' => array('return' => 'url'),
2322 'api.Contribution.getCount' => array(),
2323 'api.CustomValue.get' => 1,
2325 $result = $this->callAPIAndDocument('Contact', 'Get', $params, __FUNCTION__
, __FILE__
, $description, $subfile);
2327 $this->customGroupDelete($ids['custom_group_id']);
2328 $this->customGroupDelete($moreIDs['custom_group_id']);
2329 $this->customGroupDelete($andMoreIDs['custom_group_id']);
2330 $this->assertEquals(0, $result['values'][$result['id']]['api.CustomValue.get']['is_error']);
2331 $this->assertEquals('http://civicrm.org', $result['values'][$result['id']]['api.website.getValue']);
2335 * Test checks usage of $values to pick & choose inputs.
2337 public function testChainingValuesCreate() {
2338 $description = "This demonstrates the usage of chained api functions. Specifically it has one 'parent function' &
2339 2 child functions - one receives values from the parent (Contact) and the other child (Tag).";
2340 $subfile = "APIChainedArrayValuesFromSiblingFunction";
2342 'display_name' => 'batman',
2343 'contact_type' => 'Individual',
2344 'api.tag.create' => array(
2345 'name' => '$value.id',
2346 'description' => '$value.display_name',
2347 'format.only_id' => 1,
2349 'api.entity_tag.create' => array('tag_id' => '$value.api.tag.create'),
2351 $result = $this->callAPIAndDocument('Contact', 'Create', $params, __FUNCTION__
, __FILE__
, $description, $subfile);
2352 $this->assertEquals(0, $result['values'][$result['id']]['api.entity_tag.create']['is_error']);
2354 $tablesToTruncate = array(
2357 'civicrm_entity_tag',
2360 $this->quickCleanup($tablesToTruncate, TRUE);
2364 * Test TrueFalse format - I couldn't come up with an easy way to get an error on Get.
2366 public function testContactGetFormatIsSuccessTrue() {
2367 $this->createContactFromXML();
2368 $description = "This demonstrates use of the 'format.is_success' param.
2369 This param causes only the success or otherwise of the function to be returned as BOOLEAN";
2370 $subfile = "FormatIsSuccess_True";
2371 $params = array('id' => 17, 'format.is_success' => 1);
2372 $result = $this->callAPIAndDocument('Contact', 'Get', $params, __FUNCTION__
, __FILE__
, $description, $subfile);
2373 $this->assertEquals(1, $result);
2374 $this->callAPISuccess('Contact', 'Delete', $params);
2378 * Test TrueFalse format.
2380 public function testContactCreateFormatIsSuccessFalse() {
2382 $description = "This demonstrates use of the 'format.is_success' param.
2383 This param causes only the success or otherwise of the function to be returned as BOOLEAN";
2384 $subfile = "FormatIsSuccess_Fail";
2385 $params = array('id' => 500, 'format.is_success' => 1);
2386 $result = $this->callAPIAndDocument('Contact', 'Create', $params, __FUNCTION__
, __FILE__
, $description, $subfile);
2387 $this->assertEquals(0, $result);
2391 * Test long display names.
2395 public function testContactCreateLongDisplayName() {
2396 $result = $this->callAPISuccess('Contact', 'Create', array(
2397 'first_name' => str_pad('a', 64, 'a'),
2398 'last_name' => str_pad('a', 64, 'a'),
2399 'contact_type' => 'Individual',
2401 $this->assertEquals('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', $result['values'][$result['id']]['display_name']);
2402 $this->assertEquals('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', $result['values'][$result['id']]['sort_name']);
2406 * Test Single Entity format.
2408 public function testContactGetSingleEntityArray() {
2409 $this->createContactFromXML();
2410 $description = "This demonstrates use of the 'format.single_entity_array' param.
2411 This param causes the only contact to be returned as an array without the other levels.
2412 It will be ignored if there is not exactly 1 result";
2413 $subfile = "GetSingleContact";
2414 $params = array('id' => 17);
2415 $result = $this->callAPIAndDocument('Contact', 'GetSingle', $params, __FUNCTION__
, __FILE__
, $description, $subfile);
2416 $this->assertEquals('Test Contact', $result['display_name']);
2417 $this->callAPISuccess('Contact', 'Delete', $params);
2421 * Test Single Entity format.
2423 public function testContactGetFormatCountOnly() {
2424 $this->createContactFromXML();
2425 $description = "This demonstrates use of the 'getCount' action.
2426 This param causes the count of the only function to be returned as an integer.";
2427 $params = array('id' => 17);
2428 $result = $this->callAPIAndDocument('Contact', 'GetCount', $params, __FUNCTION__
, __FILE__
, $description,
2430 $this->assertEquals('1', $result);
2431 $this->callAPISuccess('Contact', 'Delete', $params);
2435 * Test id only format.
2437 public function testContactGetFormatIDOnly() {
2438 $this->createContactFromXML();
2439 $description = "This demonstrates use of the 'format.id_only' param.
2440 This param causes the id of the only entity to be returned as an integer.
2441 It will be ignored if there is not exactly 1 result";
2442 $subfile = "FormatOnlyID";
2443 $params = array('id' => 17, 'format.only_id' => 1);
2444 $result = $this->callAPIAndDocument('Contact', 'Get', $params, __FUNCTION__
, __FILE__
, $description, $subfile);
2445 $this->assertEquals('17', $result);
2446 $this->callAPISuccess('Contact', 'Delete', $params);
2450 * Test id only format.
2452 public function testContactGetFormatSingleValue() {
2453 $this->createContactFromXML();
2454 $description = "This demonstrates use of the 'format.single_value' param.
2455 This param causes only a single value of the only entity to be returned as an string.
2456 It will be ignored if there is not exactly 1 result";
2457 $subFile = "FormatSingleValue";
2458 $params = array('id' => 17, 'return' => 'display_name');
2459 $result = $this->callAPIAndDocument('Contact', 'getvalue', $params, __FUNCTION__
, __FILE__
, $description, $subFile);
2460 $this->assertEquals('Test Contact', $result);
2461 $this->callAPISuccess('Contact', 'Delete', $params);
2465 * Test that permissions are respected when creating contacts.
2467 public function testContactCreationPermissions() {
2469 'contact_type' => 'Individual',
2470 'first_name' => 'Foo',
2471 'last_name' => 'Bear',
2472 'check_permissions' => TRUE,
2474 $config = CRM_Core_Config
::singleton();
2475 $config->userPermissionClass
->permissions
= array('access CiviCRM');
2476 $result = $this->callAPIFailure('contact', 'create', $params);
2477 $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');
2479 $config->userPermissionClass
->permissions
= array('access CiviCRM', 'add contacts', 'import contacts');
2480 $this->callAPISuccess('contact', 'create', $params);
2484 * Test that delete with skip undelete respects permissions.
2486 public function testContactDeletePermissions() {
2487 $contactID = $this->individualCreate();
2488 CRM_Core_Config
::singleton()->userPermissionClass
->permissions
= array('access CiviCRM');
2489 $this->callAPIFailure('Contact', 'delete', array(
2491 'check_permissions' => 1,
2492 'skip_undelete' => 1,
2494 $this->callAPISuccess('Contact', 'delete', array(
2496 'check_permissions' => 0,
2497 'skip_undelete' => 1,
2502 * Test update with check permissions set.
2504 public function testContactUpdatePermissions() {
2506 'contact_type' => 'Individual',
2507 'first_name' => 'Foo',
2508 'last_name' => 'Bear',
2509 'check_permissions' => TRUE,
2511 $result = $this->callAPISuccess('contact', 'create', $params);
2512 $config = CRM_Core_Config
::singleton();
2514 'id' => $result['id'],
2515 'contact_type' => 'Individual',
2516 'last_name' => 'Bar',
2517 'check_permissions' => TRUE,
2520 $config->userPermissionClass
->permissions
= array('access CiviCRM');
2521 $result = $this->callAPIFailure('contact', 'update', $params);
2522 $this->assertEquals('Permission denied to modify contact record', $result['error_message']);
2524 $config->userPermissionClass
->permissions
= array(
2527 'view all contacts',
2528 'edit all contacts',
2531 $this->callAPISuccess('contact', 'update', $params);
2535 * Set up helper to create a contact.
2537 public function createContactFromXML() {
2538 // Insert a row in civicrm_contact creating contact 17.
2539 $op = new PHPUnit_Extensions_Database_Operation_Insert();
2540 $op->execute($this->_dbconn
,
2541 $this->createXMLDataSet(
2542 dirname(__FILE__
) . '/dataset/contact_17.xml'
2548 * Test contact proximity api.
2550 public function testContactProximity() {
2551 // first create a contact with a SF location with a specific
2553 $contactID = $this->organizationCreate();
2555 // now create the address
2557 'street_address' => '123 Main Street',
2558 'city' => 'San Francisco',
2560 'country_id' => 1228,
2561 'state_province_id' => 1004,
2562 'geo_code_1' => '37.79',
2563 'geo_code_2' => '-122.40',
2564 'location_type_id' => 1,
2565 'contact_id' => $contactID,
2568 $result = $this->callAPISuccess('address', 'create', $params);
2569 $this->assertEquals(1, $result['count']);
2571 // now do a proximity search with a close enough geocode and hope to match
2572 // that specific contact only!
2573 $proxParams = array(
2575 'longitude' => -122.3,
2579 $result = $this->callAPISuccess('contact', 'proximity', $proxParams);
2580 $this->assertEquals(1, $result['count']);
2584 * Test that Ajax API permission is sufficient to access getquick api.
2586 * (note that getquick api is required for autocomplete & has ACL permissions applied)
2588 public function testGetquickPermissionCRM13744() {
2589 CRM_Core_Config
::singleton()->userPermissionClass
->permissions
= array('access CiviEvent');
2590 $this->callAPIFailure('contact', 'getquick', array('name' => 'b', 'check_permissions' => TRUE));
2591 CRM_Core_Config
::singleton()->userPermissionClass
->permissions
= array('access CiviCRM');
2592 $this->callAPISuccess('contact', 'getquick', array('name' => 'b', 'check_permissions' => TRUE));
2593 CRM_Core_Config
::singleton()->userPermissionClass
->permissions
= array('access AJAX API');
2594 $this->callAPISuccess('contact', 'getquick', array('name' => 'b', 'check_permissions' => TRUE));
2598 * Test that getquick returns contacts with an exact first name match first.
2600 * The search string 'b' & 'bob' both return ordered by sort_name if includeOrderByClause
2601 * is true (default) but if it is false then matches are returned in ID order.
2603 * @dataProvider getSearchSortOptions
2605 public function testGetQuickExactFirst($searchParameters, $settings, $firstContact, $secondContact = NULL) {
2606 $this->getQuickSearchSampleData();
2607 $this->callAPISuccess('Setting', 'create', $settings);
2608 $result = $this->callAPISuccess('contact', 'getquick', $searchParameters);
2609 $this->assertEquals($firstContact, $result['values'][0]['sort_name']);
2610 $this->assertEquals($secondContact, $result['values'][1]['sort_name']);
2611 $this->callAPISuccess('Setting', 'create', array('includeWildCardInName' => TRUE, 'includeOrderByClause' => TRUE));
2614 public function getSearchSortOptions() {
2615 $firstAlphabeticalContactBySortName = 'A Bobby, Bobby';
2616 $secondAlphabeticalContactBySortName = 'Aadvark, Bob';
2617 $secondAlphabeticalContactWithEmailBySortName = 'Bob, Bob';
2618 $firstAlphabeticalContactFirstNameBob = 'Aadvark, Bob';
2619 $secondAlphabeticalContactFirstNameBob = 'Bob, Bob';
2620 $firstByIDContactFirstNameBob = 'Bob, Bob';
2621 $secondByIDContactFirstNameBob = 'K Bobby, Bob';
2622 $firstContactByID = 'Bob, Bob';
2623 $secondContactByID = 'E Bobby, Bobby';
2624 $bobLikeEmail = 'A Bobby, Bobby';
2627 'empty_search_basic' => array(
2628 'search_parameters' => array('name' => '%'),
2629 'settings' => array('includeWildCardInName' => TRUE, 'includeOrderByClause' => TRUE),
2630 'first_contact' => $firstAlphabeticalContactBySortName,
2631 'second_contact' => $secondAlphabeticalContactBySortName,
2633 'empty_search_basic_no_wildcard' => array(
2634 'search_parameters' => array('name' => '%'),
2635 'settings' => array('includeWildCardInName' => FALSE, 'includeOrderByClause' => TRUE),
2636 'first_contact' => $firstAlphabeticalContactBySortName,
2637 'second_contact' => $secondAlphabeticalContactBySortName,
2639 'single_letter_search_basic' => array(
2640 'search_parameters' => array('name' => 'b'),
2641 'settings' => array('includeWildCardInName' => TRUE, 'includeOrderByClause' => TRUE),
2642 'first_contact' => $firstAlphabeticalContactBySortName,
2643 'second_contact' => $secondAlphabeticalContactBySortName,
2645 'bob_search_basic' => array(
2646 'search_parameters' => array('name' => 'bob'),
2647 'settings' => array('includeWildCardInName' => TRUE, 'includeOrderByClause' => TRUE),
2648 'first_contact' => $firstAlphabeticalContactBySortName,
2649 'second_contact' => $secondAlphabeticalContactBySortName,
2651 'bob_search_no_orderby' => array(
2652 'search_parameters' => array('name' => 'bob'),
2653 'settings' => array('includeWildCardInName' => TRUE, 'includeOrderByClause' => FALSE),
2654 'first_contact' => $firstContactByID,
2655 'second_contact' => $secondContactByID,
2657 'bob_search_no_wildcard' => array(
2658 'search_parameters' => array('name' => 'bob'),
2659 'settings' => array('includeWildCardInName' => FALSE, 'includeOrderByClause' => TRUE),
2660 'second_contact' => $bobLikeEmail,
2661 'first_contact' => $secondAlphabeticalContactFirstNameBob,
2663 // This should be the same as just no wildcard as if we had an exactMatch while searching by
2664 // sort name it would rise to the top CRM-19547
2665 'bob_search_no_wildcard_no_orderby' => array(
2666 'search_parameters' => array('name' => 'bob'),
2667 'settings' => array('includeWildCardInName' => FALSE, 'includeOrderByClause' => TRUE),
2668 'second_contact' => $bobLikeEmail,
2669 'first_contact' => $secondAlphabeticalContactFirstNameBob,
2671 'first_name_search_basic' => array(
2672 'search_parameters' => array('name' => 'bob', 'field_name' => 'first_name'),
2673 'settings' => array('includeWildCardInName' => TRUE, 'includeOrderByClause' => TRUE),
2674 'first_contact' => $firstAlphabeticalContactFirstNameBob,
2675 'second_contact' => $secondAlphabeticalContactFirstNameBob,
2677 'first_name_search_no_wildcard' => array(
2678 'search_parameters' => array('name' => 'bob', 'field_name' => 'first_name'),
2679 'settings' => array('includeWildCardInName' => FALSE, 'includeOrderByClause' => TRUE),
2680 'first_contact' => $firstAlphabeticalContactFirstNameBob,
2681 'second_contact' => $secondAlphabeticalContactFirstNameBob,
2683 'first_name_search_no_orderby' => array(
2684 'search_parameters' => array('name' => 'bob', 'field_name' => 'first_name'),
2685 'settings' => array('includeWildCardInName' => TRUE, 'includeOrderByClause' => FALSE),
2686 'first_contact' => $firstByIDContactFirstNameBob,
2687 'second_contact' => $secondByIDContactFirstNameBob,
2689 'email_search_basic' => array(
2690 'search_parameters' => array('name' => 'bob', 'field_name' => 'email', 'table_name' => 'eml'),
2691 'settings' => array('includeWildCardInName' => FALSE, 'includeOrderByClause' => TRUE),
2692 'first_contact' => $firstAlphabeticalContactBySortName,
2693 'second_contact' => $secondAlphabeticalContactWithEmailBySortName,
2699 * Test that getquick returns contacts with an exact first name match first.
2701 public function testGetQuickEmail() {
2702 $this->getQuickSearchSampleData();
2703 $loggedInContactID = $this->createLoggedInUser();
2704 $result = $this->callAPISuccess('contact', 'getquick', array(
2707 $expectedData = array(
2708 'A Bobby, Bobby :: bob@bobby.com',
2709 'Bob, Bob :: bob@bob.com',
2711 'H Bobby, Bobby :: bob@h.com',
2713 $this->callAPISuccessGetValue('Contact', array('id' => $loggedInContactID, 'return' => 'last_name')) . ', Logged In :: anthony_anderson@civicrm.org',
2715 $this->assertEquals(6, $result['count']);
2716 foreach ($expectedData as $index => $value) {
2717 $this->assertEquals($value, $result['values'][$index]['data']);
2719 $result = $this->callAPISuccess('contact', 'getquick', array(
2722 $expectedData = array(
2723 'H Bobby, Bobby :: bob@h.com',
2725 foreach ($expectedData as $index => $value) {
2726 $this->assertEquals($value, $result['values'][$index]['data']);
2728 $this->callAPISuccess('Setting', 'create', array('includeWildCardInName' => FALSE));
2729 $result = $this->callAPISuccess('contact', 'getquick', array(
2732 $this->callAPISuccess('Setting', 'create', array('includeWildCardInName' => TRUE));
2733 $this->assertEquals(0, $result['count']);
2737 * Test that getquick returns contacts with an exact first name match first.
2739 public function testGetQuickEmailACL() {
2740 $this->getQuickSearchSampleData();
2741 $loggedInContactID = $this->createLoggedInUser();
2742 CRM_Core_Config
::singleton()->userPermissionClass
->permissions
= array();
2743 $result = $this->callAPISuccess('contact', 'getquick', array(
2746 $this->assertEquals(0, $result['count']);
2748 $this->hookClass
->setHook('civicrm_aclWhereClause', array($this, 'aclWhereNoBobH'));
2749 CRM_Contact_BAO_Contact_Permission
::cache($loggedInContactID, CRM_Core_Permission
::VIEW
, TRUE);
2750 $result = $this->callAPISuccess('contact', 'getquick', array(
2754 // Without the acl it would be 6 like the previous email getquick test.
2755 $this->assertEquals(5, $result['count']);
2756 $expectedData = array(
2757 'A Bobby, Bobby :: bob@bobby.com',
2758 'Bob, Bob :: bob@bob.com',
2761 $this->callAPISuccessGetValue('Contact', array('id' => $loggedInContactID, 'return' => 'last_name')) . ', Logged In :: anthony_anderson@civicrm.org',
2763 foreach ($expectedData as $index => $value) {
2764 $this->assertEquals($value, $result['values'][$index]['data']);
2769 * Test that getquick returns contacts with an exact first name match first.
2771 public function testGetQuickExternalID() {
2772 $this->getQuickSearchSampleData();
2773 $result = $this->callAPISuccess('contact', 'getquick', array(
2775 'field_name' => 'external_identifier',
2776 'table_name' => 'cc',
2778 $this->assertEquals(0, $result['count']);
2779 $result = $this->callAPISuccess('contact', 'getquick', array(
2781 'field_name' => 'external_identifier',
2782 'table_name' => 'cc',
2784 $this->assertEquals(1, $result['count']);
2785 $this->assertEquals('Bob, Bob', $result['values'][0]['sort_name']);
2789 * Test that getquick returns contacts with an exact first name match first.
2791 public function testGetQuickID() {
2792 $max = CRM_Core_DAO
::singleValueQuery("SELECT max(id) FROM civicrm_contact");
2793 $this->getQuickSearchSampleData();
2794 $result = $this->callAPISuccess('contact', 'getquick', array(
2796 'field_name' => 'id',
2797 'table_name' => 'cc',
2799 $this->assertEquals(1, $result['count']);
2800 $this->assertEquals('E Bobby, Bobby', $result['values'][0]['sort_name']);
2801 $result = $this->callAPISuccess('contact', 'getquick', array(
2803 'field_name' => 'contact_id',
2804 'table_name' => 'cc',
2806 $this->assertEquals(1, $result['count']);
2807 $this->assertEquals('E Bobby, Bobby', $result['values'][0]['sort_name']);
2811 * Test that getquick returns contacts with an exact first name match first.
2813 * Depending on the setting the sort name sort might click in next or not - test!
2815 public function testGetQuickFirstName() {
2816 $this->getQuickSearchSampleData();
2817 $this->callAPISuccess('Setting', 'create', array('includeOrderByClause' => TRUE));
2818 $result = $this->callAPISuccess('contact', 'getquick', array(
2820 'field_name' => 'first_name',
2821 'table_name' => 'cc',
2830 foreach ($expected as $index => $value) {
2831 $this->assertEquals($value, $result['values'][$index]['sort_name']);
2833 $this->callAPISuccess('Setting', 'create', array('includeOrderByClause' => FALSE));
2834 $result = $this->callAPISuccess('contact', 'getquick', array('name' => 'bob'));
2835 $this->assertEquals('Bob, Bob', $result['values'][0]['sort_name']);
2836 $this->assertEquals('E Bobby, Bobby', $result['values'][1]['sort_name']);
2840 * Test that getquick applies ACLs.
2842 public function testGetQuickFirstNameACLs() {
2843 $this->getQuickSearchSampleData();
2844 $userID = $this->createLoggedInUser();
2845 $this->callAPISuccess('Setting', 'create', array('includeOrderByClause' => TRUE, 'search_autocomplete_count' => 15));
2846 CRM_Core_Config
::singleton()->userPermissionClass
->permissions
= array();
2847 $result = $this->callAPISuccess('contact', 'getquick', array(
2849 'field_name' => 'first_name',
2850 'table_name' => 'cc',
2852 $this->assertEquals(0, $result['count']);
2854 $this->hookClass
->setHook('civicrm_aclWhereClause', array($this, 'aclWhereNoBobH'));
2855 CRM_Contact_BAO_Contact_Permission
::cache($userID, CRM_Core_Permission
::VIEW
, TRUE);
2856 $result = $this->callAPISuccess('contact', 'getquick', array(
2858 'field_name' => 'first_name',
2859 'table_name' => 'cc',
2861 $this->assertEquals('K Bobby, Bob', $result['values'][2]['sort_name']);
2862 // Without the ACL 9 would be bob@h.com.
2863 $this->assertEquals('I Bobby, Bobby', $result['values'][10]['sort_name']);
2867 * Full results returned.
2868 * @implements CRM_Utils_Hook::aclWhereClause
2870 * @param string $type
2871 * @param array $tables
2872 * @param array $whereTables
2873 * @param int $contactID
2874 * @param string $where
2876 public function aclWhereNoBobH($type, &$tables, &$whereTables, &$contactID, &$where) {
2877 $where = " (email <> 'bob@h.com' OR email IS NULL) ";
2878 $whereTables['civicrm_email'] = "LEFT JOIN civicrm_email e ON contact_a.id = e.contact_id";
2882 * Test that getquick returns contacts with an exact last name match first.
2884 public function testGetQuickLastName() {
2885 $this->getQuickSearchSampleData();
2886 $this->callAPISuccess('Setting', 'create', array('includeOrderByClause' => TRUE));
2887 $result = $this->callAPISuccess('contact', 'getquick', array(
2889 'field_name' => 'last_name',
2890 'table_name' => 'cc',
2898 foreach ($expected as $index => $value) {
2899 $this->assertEquals($value, $result['values'][$index]['sort_name']);
2901 $this->callAPISuccess('Setting', 'create', array('includeOrderByClause' => FALSE));
2902 $result = $this->callAPISuccess('contact', 'getquick', array('name' => 'bob'));
2903 $this->assertEquals('Bob, Bob :: bob@bob.com', $result['values'][0]['data']);
2907 * Test that getquick returns contacts by city.
2909 public function testGetQuickCity() {
2910 $this->getQuickSearchSampleData();
2911 $result = $this->callAPISuccess('contact', 'getquick', array(
2913 'field_name' => 'city',
2914 'table_name' => 'sts',
2916 $this->assertEquals('B Bobby, Bobby :: Toronto', $result['values'][0]['data']);
2917 $result = $this->callAPISuccess('contact', 'getquick', array(
2919 'field_name' => 'city',
2920 'table_name' => 'sts',
2922 $this->assertEquals('B Bobby, Bobby :: Toronto', $result['values'][0]['data']);
2923 $this->assertEquals('C Bobby, Bobby :: Whanganui', $result['values'][1]['data']);
2927 * Set up some sample data for testing quicksearch.
2929 public function getQuickSearchSampleData() {
2931 array('first_name' => 'Bob', 'last_name' => 'Bob', 'external_identifier' => 'abc', 'email' => 'bob@bob.com'),
2932 array('first_name' => 'Bobby', 'last_name' => 'E Bobby', 'external_identifier' => 'abcd'),
2934 'first_name' => 'Bobby',
2935 'last_name' => 'B Bobby',
2936 'external_identifier' => 'bcd',
2937 'api.address.create' => array(
2938 'street_address' => 'Sesame Street',
2939 'city' => 'Toronto',
2940 'location_type_id' => 1,
2944 'first_name' => 'Bobby',
2945 'last_name' => 'C Bobby',
2946 'external_identifier' => 'bcde',
2947 'api.address.create' => array(
2948 'street_address' => 'Te huarahi',
2949 'city' => 'Whanganui',
2950 'location_type_id' => 1,
2953 array('first_name' => 'Bobby', 'last_name' => 'D Bobby', 'external_identifier' => 'efg'),
2954 array('first_name' => 'Bobby', 'last_name' => 'A Bobby', 'external_identifier' => 'hij', 'email' => 'bob@bobby.com'),
2955 array('first_name' => 'Bobby', 'last_name' => 'F Bobby', 'external_identifier' => 'klm'),
2956 array('first_name' => 'Bobby', 'last_name' => 'G Bobby', 'external_identifier' => 'nop'),
2957 array('first_name' => 'Bobby', 'last_name' => 'H Bobby', 'external_identifier' => 'qrs', 'email' => 'bob@h.com'),
2958 array('first_name' => 'Bobby', 'last_name' => 'I Bobby'),
2959 array('first_name' => 'Bobby', 'last_name' => 'J Bobby'),
2960 array('first_name' => 'Bob', 'last_name' => 'K Bobby', 'external_identifier' => 'bcdef'),
2961 array('first_name' => 'Bob', 'last_name' => 'Aadvark'),
2963 foreach ($contacts as $type => $contact) {
2964 $contact['contact_type'] = 'Individual';
2965 $this->callAPISuccess('Contact', 'create', $contact);
2970 * Test get ref api - gets a list of references to an entity.
2972 public function testGetReferenceCounts() {
2973 $result = $this->callAPISuccess('Contact', 'create', array(
2974 'first_name' => 'Testily',
2975 'last_name' => 'McHaste',
2976 'contact_type' => 'Individual',
2977 'api.Address.replace' => array(
2978 'values' => array(),
2980 'api.Email.replace' => array(
2983 'email' => 'spam@dev.null',
2985 'location_type_id' => 1,
2989 'api.Phone.replace' => array(
2992 'phone' => '234-567-0001',
2994 'location_type_id' => 1,
2997 'phone' => '234-567-0002',
2999 'location_type_id' => 1,
3005 //$dao = new CRM_Contact_BAO_Contact();
3006 //$dao->id = $result['id'];
3007 //$this->assertTrue((bool) $dao->find(TRUE));
3009 //$refCounts = $dao->getReferenceCounts();
3010 //$this->assertTrue(is_array($refCounts));
3011 //$refCountsIdx = CRM_Utils_Array::index(array('name'), $refCounts);
3013 $refCounts = $this->callAPISuccess('Contact', 'getrefcount', array(
3014 'id' => $result['id'],
3016 $refCountsIdx = CRM_Utils_Array
::index(array('name'), $refCounts['values']);
3018 $this->assertEquals(1, $refCountsIdx['sql:civicrm_email:contact_id']['count']);
3019 $this->assertEquals('civicrm_email', $refCountsIdx['sql:civicrm_email:contact_id']['table']);
3020 $this->assertEquals(2, $refCountsIdx['sql:civicrm_phone:contact_id']['count']);
3021 $this->assertEquals('civicrm_phone', $refCountsIdx['sql:civicrm_phone:contact_id']['table']);
3022 $this->assertTrue(!isset($refCountsIdx['sql:civicrm_address:contact_id']));
3026 * Test the use of sql operators.
3028 public function testSQLOperatorsOnContactAPI() {
3029 $this->individualCreate();
3030 $this->organizationCreate();
3031 $this->householdCreate();
3032 $contacts = $this->callAPISuccess('contact', 'get', array('legal_name' => array('IS NOT NULL' => TRUE)));
3033 $this->assertEquals($contacts['count'], CRM_Core_DAO
::singleValueQuery('select count(*) FROM civicrm_contact WHERE legal_name IS NOT NULL'));
3034 $contacts = $this->callAPISuccess('contact', 'get', array('legal_name' => array('IS NULL' => TRUE)));
3035 $this->assertEquals($contacts['count'], CRM_Core_DAO
::singleValueQuery('select count(*) FROM civicrm_contact WHERE legal_name IS NULL'));
3039 * CRM-14743 - test api respects search operators.
3041 public function testGetModifiedDateByOperators() {
3042 $preExistingContactCount = CRM_Core_DAO
::singleValueQuery('select count(*) FROM civicrm_contact');
3043 $contact1 = $this->individualCreate();
3044 $sql = "UPDATE civicrm_contact SET created_date = '2012-01-01', modified_date = '2013-01-01' WHERE id = " . $contact1;
3045 CRM_Core_DAO
::executeQuery($sql);
3046 $contact2 = $this->individualCreate();
3047 $sql = "UPDATE civicrm_contact SET created_date = '2012-02-01', modified_date = '2013-02-01' WHERE id = " . $contact2;
3048 CRM_Core_DAO
::executeQuery($sql);
3049 $contact3 = $this->householdCreate();
3050 $sql = "UPDATE civicrm_contact SET created_date = '2012-03-01', modified_date = '2013-03-01' WHERE id = " . $contact3;
3051 CRM_Core_DAO
::executeQuery($sql);
3052 $contacts = $this->callAPISuccess('contact', 'get', array('modified_date' => array('<' => '2014-01-01')));
3053 $this->assertEquals($contacts['count'], 3);
3054 $contacts = $this->callAPISuccess('contact', 'get', array('modified_date' => array('>' => '2014-01-01')));
3055 $this->assertEquals($contacts['count'], $preExistingContactCount);
3059 * CRM-14743 - test api respects search operators.
3061 public function testGetCreatedDateByOperators() {
3062 $preExistingContactCount = CRM_Core_DAO
::singleValueQuery('select count(*) FROM civicrm_contact');
3063 $contact1 = $this->individualCreate();
3064 $sql = "UPDATE civicrm_contact SET created_date = '2012-01-01' WHERE id = " . $contact1;
3065 CRM_Core_DAO
::executeQuery($sql);
3066 $contact2 = $this->individualCreate();
3067 $sql = "UPDATE civicrm_contact SET created_date = '2012-02-01' WHERE id = " . $contact2;
3068 CRM_Core_DAO
::executeQuery($sql);
3069 $contact3 = $this->householdCreate();
3070 $sql = "UPDATE civicrm_contact SET created_date = '2012-03-01' WHERE id = " . $contact3;
3071 CRM_Core_DAO
::executeQuery($sql);
3072 $contacts = $this->callAPISuccess('contact', 'get', array('created_date' => array('<' => '2014-01-01')));
3073 $this->assertEquals($contacts['count'], 3);
3074 $contacts = $this->callAPISuccess('contact', 'get', array('created_date' => array('>' => '2014-01-01')));
3075 $this->assertEquals($contacts['count'], $preExistingContactCount);
3079 * CRM-14263 check that API is not affected by search profile related bug.
3081 public function testReturnCityProfile() {
3082 $contactID = $this->individualCreate();
3083 CRM_Core_Config
::singleton()->defaultSearchProfileID
= 1;
3084 $this->callAPISuccess('address', 'create', array(
3085 'contact_id' => $contactID,
3086 'city' => 'Cool City',
3087 'location_type_id' => 1,
3089 $result = $this->callAPISuccess('contact', 'get', array('city' => 'Cool City', 'return' => 'contact_type'));
3090 $this->assertEquals(1, $result['count']);
3094 * CRM-15443 - ensure getlist api does not return deleted contacts.
3096 public function testGetlistExcludeConditions() {
3097 $name = md5(time());
3098 $contact = $this->individualCreate(array('last_name' => $name));
3099 $this->individualCreate(array('last_name' => $name, 'is_deceased' => 1));
3100 $this->individualCreate(array('last_name' => $name, 'is_deleted' => 1));
3101 // We should get all but the deleted contact.
3102 $result = $this->callAPISuccess('contact', 'getlist', array('input' => $name));
3103 $this->assertEquals(2, $result['count']);
3104 // Force-exclude the deceased contact.
3105 $result = $this->callAPISuccess('contact', 'getlist', array(
3107 'params' => array('is_deceased' => 0),
3109 $this->assertEquals(1, $result['count']);
3110 $this->assertEquals($contact, $result['values'][0]['id']);
3114 * Test contact getactions.
3116 public function testGetActions() {
3117 $description = "Getting the available actions for an entity.";
3118 $result = $this->callAPIAndDocument($this->_entity
, 'getactions', array(), __FUNCTION__
, __FILE__
, $description);
3138 $deprecated = array(
3142 foreach ($expected as $action) {
3143 $this->assertTrue(in_array($action, $result['values']), "Expected action $action");
3145 foreach ($deprecated as $action) {
3146 $this->assertArrayKeyExists($action, $result['deprecated']);
3151 * Test the duplicate check function.
3153 public function testDuplicateCheck() {
3155 'first_name' => 'Harry',
3156 'last_name' => 'Potter',
3157 'email' => 'harry@hogwarts.edu',
3158 'contact_type' => 'Individual',
3160 $this->callAPISuccess('Contact', 'create', $harry);
3161 $result = $this->callAPISuccess('Contact', 'duplicatecheck', array(
3165 $this->assertEquals(1, $result['count']);
3166 $result = $this->callAPISuccess('Contact', 'duplicatecheck', array(
3168 'first_name' => 'Harry',
3169 'last_name' => 'Potter',
3170 'email' => 'no5@privet.drive',
3171 'contact_type' => 'Individual',
3174 $this->assertEquals(0, $result['count']);
3175 $this->callAPIFailure('Contact', 'create', array_merge($harry, array('dupe_check' => 1)));
3179 * Test the duplicate check function.
3181 public function testDuplicateCheckRuleNotReserved() {
3183 'first_name' => 'Harry',
3184 'last_name' => 'Potter',
3185 'email' => 'harry@hogwarts.edu',
3186 'contact_type' => 'Individual',
3188 $defaultRule = $this->callAPISuccess('RuleGroup', 'getsingle', array('used' => 'Unsupervised', 'is_reserved' => 1));
3189 $this->callAPISuccess('RuleGroup', 'create', array('id' => $defaultRule['id'], 'is_reserved' => 0));
3190 $this->callAPISuccess('Contact', 'create', $harry);
3191 $result = $this->callAPISuccess('Contact', 'duplicatecheck', array(
3195 $this->assertEquals(1, $result['count']);
3196 $this->callAPISuccess('RuleGroup', 'create', array('id' => $defaultRule['id'], 'is_reserved' => 1));
3200 * Test variants on retrieving contact by type.
3202 public function testGetByContactType() {
3203 $individual = $this->callAPISuccess('Contact', 'create', array(
3204 'email' => 'individual@test.com',
3205 'contact_type' => 'Individual',
3207 $household = $this->callAPISuccess('Contact', 'create', array(
3208 'household_name' => 'household@test.com',
3209 'contact_type' => 'Household',
3211 $organization = $this->callAPISuccess('Contact', 'create', array(
3212 'organization_name' => 'organization@test.com',
3213 'contact_type' => 'Organization',
3215 // Test with id - getsingle will throw an exception if not found
3216 $this->callAPISuccess('Contact', 'getsingle', array(
3217 'id' => $individual['id'],
3218 'contact_type' => 'Individual',
3220 $this->callAPISuccess('Contact', 'getsingle', array(
3221 'id' => $individual['id'],
3222 'contact_type' => array('IN' => array('Individual')),
3225 $this->callAPISuccess('Contact', 'getsingle', array(
3226 'id' => $organization['id'],
3227 'contact_type' => array('IN' => array('Individual', 'Organization')),
3230 $result = $this->callAPISuccess('Contact', 'get', array(
3231 'contact_type' => array('IN' => array('Individual', 'Organization')),
3232 'options' => array('limit' => 0),
3235 $this->assertContains($organization['id'], array_keys($result['values']));
3236 $this->assertContains($individual['id'], array_keys($result['values']));
3237 $this->assertNotContains($household['id'], array_keys($result['values']));
3239 $result = $this->callAPISuccess('Contact', 'get', array(
3240 'contact_type' => 'Household',
3241 'options' => array('limit' => 0),
3244 $this->assertNotContains($organization['id'], array_keys($result['values']));
3245 $this->assertNotContains($individual['id'], array_keys($result['values']));
3246 $this->assertContains($household['id'], array_keys($result['values']));
3250 * Test merging 2 contacts.
3252 * Someone kindly bequethed us the legacy of mixed up use of main_id & other_id
3253 * in the params for contact.merge api.
3255 * This test protects that legacy.
3257 public function testMergeBizzareOldParams() {
3258 $this->createLoggedInUser();
3259 $otherContact = $this->callAPISuccess('contact', 'create', $this->_params
);
3260 $mainContact = $this->callAPISuccess('contact', 'create', $this->_params
);
3261 $this->callAPISuccess('contact', 'merge', array(
3262 'main_id' => $mainContact['id'],
3263 'other_id' => $otherContact['id'],
3265 $contacts = $this->callAPISuccess('contact', 'get', $this->_params
);
3266 $this->assertEquals($otherContact['id'], $contacts['id']);
3270 * Test merging 2 contacts.
3272 public function testMerge() {
3273 $this->createLoggedInUser();
3274 $otherContact = $this->callAPISuccess('contact', 'create', $this->_params
);
3275 $retainedContact = $this->callAPISuccess('contact', 'create', $this->_params
);
3276 $this->callAPISuccess('contact', 'merge', array(
3277 'to_keep_id' => $retainedContact['id'],
3278 'to_remove_id' => $otherContact['id'],
3279 'auto_flip' => FALSE,
3282 $contacts = $this->callAPISuccess('contact', 'get', $this->_params
);
3283 $this->assertEquals($retainedContact['id'], $contacts['id']);
3284 $activity = $this->callAPISuccess('Activity', 'getsingle', array(
3285 'target_contact_id' => $retainedContact['id'],
3286 'activity_type_id' => 'Contact Merged',
3288 $this->assertEquals(date('Y-m-d'), date('Y-m-d', strtotime($activity['activity_date_time'])));
3289 $activity2 = $this->callAPISuccess('Activity', 'getsingle', array(
3290 'target_contact_id' => $otherContact['id'],
3291 'activity_type_id' => 'Contact Deleted by Merge',
3293 $this->assertEquals($activity['id'], $activity2['parent_id']);
3294 $this->assertEquals('Normal', civicrm_api3('option_value', 'getvalue', array(
3295 'value' => $activity['priority_id'],
3296 'return' => 'label',
3297 'option_group_id' => 'priority',
3303 * Test merging 2 contacts with delete to trash off.
3305 * We are checking that there is no error due to attempting to add an activity for the
3310 public function testMergeNoTrash() {
3311 $this->createLoggedInUser();
3312 $this->callAPISuccess('Setting', 'create', array('contact_undelete' => FALSE));
3313 $otherContact = $this->callAPISuccess('contact', 'create', $this->_params
);
3314 $retainedContact = $this->callAPISuccess('contact', 'create', $this->_params
);
3315 $this->callAPISuccess('contact', 'merge', array(
3316 'to_keep_id' => $retainedContact['id'],
3317 'to_remove_id' => $otherContact['id'],
3318 'auto_flip' => FALSE,
3320 $this->callAPISuccess('Setting', 'create', array('contact_undelete' => TRUE));
3324 * Ensure format with return=group shows comma-separated group IDs.
3328 public function testContactGetReturnGroup() {
3329 // Set up a contact, asser that they were created.
3330 $contact_params = array(
3331 'contact_type' => 'Individual',
3332 'first_name' => 'Test',
3333 'last_name' => 'Groupmember',
3334 'email' => 'test@example.org',
3336 $create_contact = $this->callApiSuccess('Contact', 'create', $contact_params);
3337 $this->assertEquals(0, $create_contact['is_error']);
3338 $this->assertInternalType('int', $create_contact['id']);
3340 $created_contact_id = $create_contact['id'];
3342 // Set up multiple groups, add the contact to the groups.
3343 $test_groups = array('Test group A', 'Test group B');
3344 foreach ($test_groups as $title) {
3345 // Use this contact as group owner, since we know they exist.
3346 $group_params = array(
3348 'created_id' => $created_contact_id,
3350 $create_group = $this->callApiSuccess('Group', 'create', $group_params);
3351 $this->assertEquals(0, $create_group['is_error']);
3352 $this->assertInternalType('int', $create_group['id']);
3354 $created_group_ids[] = $create_group['id'];
3356 // Add contact to the new group.
3357 $group_contact_params = array(
3358 'contact_id' => $created_contact_id,
3359 'group_id' => $create_group['id'],
3361 $create_group_contact = $this->callApiSuccess('GroupContact', 'create', $group_contact_params);
3362 $this->assertEquals(0, $create_group_contact['is_error']);
3363 $this->assertInternalType('int', $create_group_contact['added']);
3366 // Use the Contact,get API to retrieve the contact
3367 $contact_get_params = array(
3368 'id' => $created_contact_id,
3369 'return' => 'group',
3371 $contact_get = $this->callApiSuccess('Contact', 'get', $contact_get_params);
3372 $this->assertInternalType('array', $contact_get['values'][$created_contact_id]);
3373 $this->assertInternalType('string', $contact_get['values'][$created_contact_id]['groups']);
3375 // Ensure they are shown as being in each created group.
3376 $contact_group_ids = explode(',', $contact_get['values'][$created_contact_id]['groups']);
3377 foreach ($created_group_ids as $created_group_id) {
3378 $this->assertContains($created_group_id, $contact_group_ids);
3383 * CRM-20144 Verify that passing title of group works as well as id
3384 * Tests the following formats
3385 * contact.get group='title1'
3386 * contact.get group=id1
3388 public function testContactGetWithGroupTitle() {
3389 // Set up a contact, asser that they were created.
3390 $contact_params = array(
3391 'contact_type' => 'Individual',
3392 'first_name' => 'Test2',
3393 'last_name' => 'Groupmember',
3394 'email' => 'test@example.org',
3396 $create_contact = $this->callApiSuccess('Contact', 'create', $contact_params);
3397 $created_contact_id = $create_contact['id'];
3398 // Set up multiple groups, add the contact to the groups.
3399 $test_groups = array('Test group C', 'Test group D');
3400 foreach ($test_groups as $title) {
3401 $group_params = array(
3403 'created_id' => $created_contact_id,
3405 $create_group = $this->callApiSuccess('Group', 'create', $group_params);
3406 $created_group_id = $create_group['id'];
3408 // Add contact to the new group.
3409 $group_contact_params = array(
3410 'contact_id' => $created_contact_id,
3411 'group_id' => $create_group['id'],
3413 $this->callApiSuccess('GroupContact', 'create', $group_contact_params);
3414 $contact_get = $this->callAPISuccess('contact', 'get', array('group' => $title, 'return' => 'group'));
3415 $this->assertEquals(1, $contact_get['count']);
3416 $this->assertEquals($created_contact_id, $contact_get['id']);
3417 $contact_groups = explode(',', $contact_get['values'][$created_contact_id]['groups']);
3418 $this->assertContains((string) $create_group['id'], $contact_groups);
3419 $contact_get2 = $this->callAPISuccess('contact', 'get', array('group' => $created_group_id, 'return' => 'group'));
3420 $this->assertEquals($created_contact_id, $contact_get2['id']);
3421 $contact_groups2 = explode(',', $contact_get2['values'][$created_contact_id]['groups']);
3422 $this->assertContains((string) $create_group['id'], $contact_groups2);
3423 $this->callAPISuccess('group', 'delete', array('id' => $created_group_id));
3425 $this->callAPISuccess('contact', 'delete', array('id' => $created_contact_id, 'skip_undelete' => TRUE));
3429 * CRM-20144 Verify that passing title of group works as well as id
3430 * Tests the following formats
3431 * contact.get group=array('title1', title1)
3432 * contact.get group=array('IN' => array('title1', 'title2)
3434 public function testContactGetWithGroupTitleMultipleGroups() {
3435 $description = "Get all from group and display contacts.";
3436 $subFile = "GroupFilterUsingContactAPI";
3437 // Set up a contact, asser that they were created.
3438 $contact_params = array(
3439 'contact_type' => 'Individual',
3440 'first_name' => 'Test2',
3441 'last_name' => 'Groupmember',
3442 'email' => 'test@example.org',
3444 $create_contact = $this->callApiSuccess('Contact', 'create', $contact_params);
3445 $created_contact_id = $create_contact['id'];
3446 $createdGroupsTitles = $createdGroupsIds = array();
3447 // Set up multiple groups, add the contact to the groups.
3448 $test_groups = array('Test group C', 'Test group D');
3449 foreach ($test_groups as $title) {
3450 $group_params = array(
3452 'created_id' => $created_contact_id,
3454 $create_group = $this->callApiSuccess('Group', 'create', $group_params);
3455 $created_group_id = $create_group['id'];
3456 $createdGroupsIds[] = $create_group['id'];
3457 $createdGroupTitles[] = $title;
3458 // Add contact to the new group.
3459 $group_contact_params = array(
3460 'contact_id' => $created_contact_id,
3461 'group_id' => $create_group['id'],
3463 $create_group_contact = $this->callApiSuccess('GroupContact', 'create', $group_contact_params);
3465 $contact_get = $this->callAPISuccess('contact', 'get', array('group' => $createdGroupTitles, 'return' => 'group'));
3466 $this->assertEquals(1, $contact_get['count']);
3467 $this->assertEquals($created_contact_id, $contact_get['id']);
3468 $contact_groups = explode(',', $contact_get['values'][$created_contact_id]['groups']);
3469 foreach ($createdGroupsIds as $id) {
3470 $this->assertContains((string) $id, $contact_groups);
3472 $contact_get2 = $this->callAPIAndDocument('contact', 'get', array('group' => array('IN' => $createdGroupTitles)), __FUNCTION__
, __FILE__
, $description, $subFile);
3473 $contact_get2 = $this->callAPISuccess('contact', 'get', array('group' => array('IN' => $createdGroupTitles), 'return' => 'group'));
3474 $this->assertEquals($created_contact_id, $contact_get2['id']);
3475 $contact_groups2 = explode(',', $contact_get2['values'][$created_contact_id]['groups']);
3476 foreach ($createdGroupsIds as $id) {
3477 $this->assertContains((string) $id, $contact_groups2);
3479 foreach ($createdGroupsIds as $id) {
3480 $this->callAPISuccess('group', 'delete', array('id' => $id));
3482 $this->callAPISuccess('contact', 'delete', array('id' => $created_contact_id, 'skip_undelete' => TRUE));
3486 * CRM-20144 Verify that passing title of group works as well as id
3487 * Tests the following formats
3488 * contact.get group=array('title1' => 1)
3489 * contact.get group=array('titke1' => 1, 'title2' => 1)
3490 * contact.get group=array('id1' => 1)
3491 * contact.get group=array('id1' => 1, id2 => 1)
3493 public function testContactGetWithGroupTitleMultipleGroupsLegacyFormat() {
3494 // Set up a contact, asser that they were created.
3495 $contact_params = array(
3496 'contact_type' => 'Individual',
3497 'first_name' => 'Test2',
3498 'last_name' => 'Groupmember',
3499 'email' => 'test@example.org',
3501 $create_contact = $this->callApiSuccess('Contact', 'create', $contact_params);
3502 $created_contact_id = $create_contact['id'];
3503 $createdGroupsTitles = $createdGroupsIds = array();
3504 // Set up multiple groups, add the contact to the groups.
3505 $test_groups = array('Test group C', 'Test group D');
3506 foreach ($test_groups as $title) {
3507 $group_params = array(
3509 'created_id' => $created_contact_id,
3511 $create_group = $this->callApiSuccess('Group', 'create', $group_params);
3512 $created_group_id = $create_group['id'];
3513 $createdGroupsIds[] = $create_group['id'];
3514 $createdGroupTitles[] = $title;
3515 // Add contact to the new group.
3516 $group_contact_params = array(
3517 'contact_id' => $created_contact_id,
3518 'group_id' => $create_group['id'],
3520 $create_group_contact = $this->callApiSuccess('GroupContact', 'create', $group_contact_params);
3522 $contact_get = $this->callAPISuccess('contact', 'get', array('group' => array($createdGroupTitles[0] => 1), 'return' => 'group'));
3523 $this->assertEquals(1, $contact_get['count']);
3524 $this->assertEquals($created_contact_id, $contact_get['id']);
3525 $contact_groups = explode(',', $contact_get['values'][$created_contact_id]['groups']);
3526 foreach ($createdGroupsIds as $id) {
3527 $this->assertContains((string) $id, $contact_groups);
3529 $contact_get2 = $this->callAPISuccess('contact', 'get', array('group' => array($createdGroupTitles[0] => 1, $createdGroupTitles[1] => 1), 'return' => 'group'));
3530 $this->assertEquals(1, $contact_get2['count']);
3531 $this->assertEquals($created_contact_id, $contact_get2['id']);
3532 $contact_groups2 = explode(',', $contact_get2['values'][$created_contact_id]['groups']);
3533 foreach ($createdGroupsIds as $id) {
3534 $this->assertContains((string) $id, $contact_groups2);
3536 $contact_get3 = $this->callAPISuccess('contact', 'get', array('group' => array($createdGroupsIds[0] => 1), 'return' => 'group'));
3537 $this->assertEquals($created_contact_id, $contact_get3['id']);
3538 $contact_groups3 = explode(',', $contact_get3['values'][$created_contact_id]['groups']);
3539 foreach ($createdGroupsIds as $id) {
3540 $this->assertContains((string) $id, $contact_groups3);
3542 $contact_get4 = $this->callAPISuccess('contact', 'get', array('group' => array($createdGroupsIds[0] => 1, $createdGroupsIds[1] => 1), 'return' => 'group'));
3543 $this->assertEquals($created_contact_id, $contact_get4['id']);
3544 $contact_groups4 = explode(',', $contact_get4['values'][$created_contact_id]['groups']);
3545 foreach ($createdGroupsIds as $id) {
3546 $this->assertContains((string) $id, $contact_groups4);
3548 foreach ($createdGroupsIds as $id) {
3549 $this->callAPISuccess('group', 'delete', array('id' => $id));
3551 $this->callAPISuccess('contact', 'delete', array('id' => $created_contact_id, 'skip_undelete' => TRUE));
3555 * Test the prox_distance functionality works.
3557 * This is primarily testing functionality in the BAO_Query object that 'happens to be'
3558 * accessible via the api.
3560 public function testContactGetProximity() {
3561 CRM_Core_Config
::singleton()->geocodeMethod
= 'CRM_Utils_MockGeocoder';
3562 $this->individualCreate();
3563 $contactID = $this->individualCreate();
3564 $this->callAPISuccess('Address', 'create', [
3565 'contact_id' => $contactID,
3567 'city' => 'Whangarei',
3568 'street_address' => 'Dent St',
3569 'geo_code_1' => '-35.8743325',
3570 'geo_code_2' => '174.4567136',
3571 'location_type_id' => 'Home',
3573 $contact = $this->callAPISuccess('Contact', 'get', [
3574 'prox_distance' => 100,
3575 'prox_geo_code_1' => '-35.72192',
3576 'prox_geo_code_2' => '174.32034',
3578 $this->assertEquals(1, $contact['count']);
3579 $this->assertEquals($contactID, $contact['id']);
3582 public function testLoggedInUserAPISupportToken() {
3583 $description = "Get contact id of the current logged in user";
3584 $subFile = "ContactIDOfLoggedInUserContactAPI";
3585 $cid = $this->createLoggedInUser();
3586 $contact = $this->callAPIAndDocument('contact', 'get', array('id' => 'user_contact_id'), __FUNCTION__
, __FILE__
, $description, $subFile);
3587 $this->assertEquals($cid, $contact['id']);
3594 protected function putGroupContactCacheInClearableState($groupID, $contact) {
3595 // We need to force the situation where there is invalid data in the cache and it
3596 // is due to be cleared.
3597 CRM_Core_DAO
::executeQuery("
3598 INSERT INTO civicrm_group_contact_cache (group_id, contact_id)
3599 VALUES ({$groupID}, {$contact['id']})
3601 CRM_Core_DAO
::executeQuery("UPDATE civicrm_group SET cache_date = '2017-01-01'");
3602 // Reset so it does not skip.
3603 Civi
::$statics['CRM_Contact_BAO_GroupContactCache']['is_refresh_init'] = FALSE;
3607 * CRM-21041 Test if 'communication style' is set to site default if not passed.
3609 public function testCreateCommunicationStyleUnset() {
3610 $this->callAPISuccess('Contact', 'create', array(
3611 'first_name' => 'John',
3612 'last_name' => 'Doe',
3613 'contact_type' => 'Individual')
3615 $result = $this->callAPISuccessGetSingle('Contact', array('last_name' => 'Doe'));
3616 $this->assertEquals(1, $result['communication_style_id']);
3620 * CRM-21041 Test if 'communication style' is set if value is passed.
3622 public function testCreateCommunicationStylePassed() {
3623 $this->callAPISuccess('Contact', 'create', array(
3624 'first_name' => 'John',
3625 'last_name' => 'Doe',
3626 'contact_type' => 'Individual',
3627 'communication_style_id' => 'Familiar',
3629 $result = $this->callAPISuccessGetSingle('Contact', array('last_name' => 'Doe'));
3631 'option_group_id' => 'communication_style',
3632 'label' => 'Familiar',
3633 'return' => 'value',
3635 $optionResult = civicrm_api3('OptionValue', 'get', $params);
3636 $communicationStyle = reset($optionResult['values']);
3637 $this->assertEquals($communicationStyle['value'], $result['communication_style_id']);
3641 * Test that creating a contact with various contact greetings works.
3643 public function testContactGreetingsCreate() {
3644 $contact = $this->callAPISuccess('Contact', 'create', array('first_name' => 'Alan', 'last_name' => 'MouseMouse', 'contact_type' => 'Individual'));
3645 $contact = $this->callAPISuccessGetSingle('Contact', array('id' => $contact['id'], 'return' => 'postal_greeting'));
3646 $this->assertEquals('Dear Alan', $contact['postal_greeting_display']);
3648 $contact = $this->callAPISuccess('Contact', 'create', array('id' => $contact['id'], 'postal_greeting_id' => 2));
3649 $contact = $this->callAPISuccessGetSingle('Contact', array('id' => $contact['id'], 'return' => 'postal_greeting'));
3650 $this->assertEquals('Dear Alan MouseMouse', $contact['postal_greeting_display']);
3652 $contact = $this->callAPISuccess('Contact', 'create', array('organization_name' => 'Alan\'s Show', 'contact_type' => 'Organization'));
3653 $contact = $this->callAPISuccessGetSingle('Contact', array('id' => $contact['id'], 'return' => 'postal_greeting, addressee, email_greeting'));
3654 $this->assertEquals('', $contact['postal_greeting_display']);
3655 $this->assertEquals('', $contact['email_greeting_display']);
3656 $this->assertEquals('Alan\'s Show', $contact['addressee_display']);
3660 * Test that creating a contact with various contact greetings works.
3662 public function testContactGreetingsCreateWithCustomField() {
3663 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__
, __FILE__
);
3664 $contact = $this->callAPISuccess('Contact', 'create', array('first_name' => 'Alan', 'contact_type' => 'Individual', 'custom_' . $ids['custom_field_id'] => 'Mice'));
3666 // Change postal greeting to involve a custom field.
3667 $postalOption = $this->callAPISuccessGetSingle('OptionValue', array('option_group_id' => 'postal_greeting', 'filter' => 1, 'is_default' => 1));
3668 $this->callAPISuccess('OptionValue', 'create', array(
3669 'id' => $postalOption['id'],
3670 'name' => 'Dear {contact.first_name} {contact.custom_' . $ids['custom_field_id'] . '}',
3671 'label' => 'Dear {contact.first_name} {contact.custom_' . $ids['custom_field_id'] . '}',
3674 // Update contact & see if postal greeting now reflects the new string.
3675 $this->callAPISuccess('Contact', 'create', array('id' => $contact['id'], 'last_name' => 'MouseyMousey'));
3676 $contact = $this->callAPISuccessGetSingle('Contact', array('id' => $contact['id'], 'return' => 'postal_greeting'));
3677 $this->assertEquals('Dear Alan Mice', $contact['postal_greeting_display']);
3679 // Set contact to have no postal greeting & check it is correct.
3680 $this->callAPISuccess('Contact', 'create', array('id' => $contact['id'], 'postal_greeting_id' => 'null'));
3681 $contact = $this->callAPISuccessGetSingle('Contact', array('id' => $contact['id'], 'return' => 'postal_greeting'));
3682 $this->assertEquals('', $contact['postal_greeting_display']);
3685 $this->callAPISuccess('OptionValue', 'create', array('id' => $postalOption['id'], 'name' => 'Dear {contact.first_name}'));
3686 $this->customFieldDelete($ids['custom_field_id']);
3687 $this->customGroupDelete($ids['custom_group_id']);