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',
88 $this->quickCleanup($tablesToTruncate, TRUE);
93 * Test civicrm_contact_create.
95 * Verify that attempt to create individual contact with only
96 * first and last names succeeds
98 public function testAddCreateIndividual() {
99 $oldCount = CRM_Core_DAO
::singleValueQuery('select count(*) from civicrm_contact');
101 'first_name' => 'abc1',
102 'contact_type' => 'Individual',
103 'last_name' => 'xyz1',
106 $contact = $this->callAPISuccess('contact', 'create', $params);
107 $this->assertTrue(is_numeric($contact['id']));
108 $this->assertTrue($contact['id'] > 0);
109 $newCount = CRM_Core_DAO
::singleValueQuery('select count(*) from civicrm_contact');
110 $this->assertEquals($oldCount +
1, $newCount);
112 $this->assertDBState('CRM_Contact_DAO_Contact',
119 * Test for international string acceptance (CRM-10210).
121 * @dataProvider getInternationalStrings
123 * @param string $string
124 * String to be tested.
128 public function testInternationalStrings($string) {
129 $this->callAPISuccess('Contact', 'create', array_merge(
131 array('first_name' => $string)
133 $result = $this->callAPISuccessGetSingle('Contact', array('first_name' => $string));
134 $this->assertEquals($string, $result['first_name']);
136 $organizationParams = array(
137 'organization_name' => $string,
138 'contact_type' => 'Organization',
141 $this->callAPISuccess('Contact', 'create', $organizationParams);
142 $result = $this->callAPISuccessGetSingle('Contact', $organizationParams);
143 $this->assertEquals($string, $result['organization_name']);
147 * Get international string data for testing against api calls.
149 public function getInternationalStrings() {
150 $invocations = array();
151 $invocations[] = array('Scarabée');
152 $invocations[] = array('Iñtërnâtiônàlizætiøn');
153 $invocations[] = array('これは日本語のテキストです。読めますか');
154 $invocations[] = array('देखें हिन्दी कैसी नजर आती है। अरे वाह ये तो नजर आती है।');
159 * Test civicrm_contact_create.
161 * Verify that preferred language can be set.
163 public function testAddCreateIndividualWithPreferredLanguage() {
165 'first_name' => 'abc1',
166 'contact_type' => 'Individual',
167 'last_name' => 'xyz1',
168 'preferred_language' => 'es_ES',
171 $contact = $this->callAPISuccess('contact', 'create', $params);
172 $this->getAndCheck($params, $contact['id'], 'Contact');
176 * Test civicrm_contact_create with sub-types.
178 * Verify that sub-types are created successfully and not deleted by subsequent updates.
180 public function testIndividualSubType() {
182 'first_name' => 'test abc',
183 'contact_type' => 'Individual',
184 'last_name' => 'test xyz',
185 'contact_sub_type' => array('Student', 'Staff'),
187 $contact = $this->callAPISuccess('contact', 'create', $params);
188 $cid = $contact['id'];
192 'middle_name' => 'foo',
194 $this->callAPISuccess('contact', 'create', $params);
195 unset($params['middle_name']);
197 $contact = $this->callAPISuccess('contact', 'get', $params);
199 $this->assertEquals(array('Student', 'Staff'), $contact['values'][$cid]['contact_sub_type']);
203 * Verify that we can retreive contacts of different sub types
205 public function testGetMultipleContactSubTypes() {
207 // This test presumes that there are no parents or students in the dataset
210 $student = $this->callAPISuccess('contact', 'create', array(
211 'email' => 'student@example.com',
212 'contact_type' => 'Individual',
213 'contact_sub_type' => 'Student',
217 $parent = $this->callAPISuccess('contact', 'create', array(
218 'email' => 'parent@example.com',
219 'contact_type' => 'Individual',
220 'contact_sub_type' => 'Parent',
224 $contact = $this->callAPISuccess('contact', 'create', array(
225 'email' => 'parent@example.com',
226 'contact_type' => 'Individual',
229 // get all students and parents
230 $getParams = array('contact_sub_type' => array('IN' => array('Parent', 'Student')));
231 $result = civicrm_api3('contact', 'get', $getParams);
233 // check that we retrieved the student and the parent
234 $this->assertArrayHasKey($student['id'], $result['values']);
235 $this->assertArrayHasKey($parent['id'], $result['values']);
236 $this->assertEquals(2, $result['count']);
242 * Verify that attempt to create contact with empty params fails.
244 public function testCreateEmptyContact() {
245 $this->callAPIFailure('contact', 'create', array());
249 * Verify that attempt to create contact with bad contact type fails.
251 public function testCreateBadTypeContact() {
253 'email' => 'man1@yahoo.com',
254 'contact_type' => 'Does not Exist',
256 $this->callAPIFailure('contact', 'create', $params, "'Does not Exist' is not a valid option for field contact_type");
260 * Verify that attempt to create individual contact without required fields fails.
262 public function testCreateBadRequiredFieldsIndividual() {
264 'middle_name' => 'This field is not required',
265 'contact_type' => 'Individual',
267 $this->callAPIFailure('contact', 'create', $params);
271 * Verify that attempt to create household contact without required fields fails.
273 public function testCreateBadRequiredFieldsHousehold() {
275 'middle_name' => 'This field is not required',
276 'contact_type' => 'Household',
278 $this->callAPIFailure('contact', 'create', $params);
282 * Test required field check.
284 * Verify that attempt to create organization contact without required fields fails.
286 public function testCreateBadRequiredFieldsOrganization() {
288 'middle_name' => 'This field is not required',
289 'contact_type' => 'Organization',
292 $this->callAPIFailure('contact', 'create', $params);
296 * Verify that attempt to create individual contact with only an email succeeds.
298 public function testCreateEmailIndividual() {
299 $primaryEmail = 'man3@yahoo.com';
300 $notPrimaryEmail = 'man4@yahoo.com';
302 'email' => $primaryEmail,
303 'contact_type' => 'Individual',
304 'location_type_id' => 1,
307 $contact1 = $this->callAPISuccess('contact', 'create', $params);
309 $this->assertEquals(3, $contact1['id']);
310 $email1 = $this->callAPISuccess('email', 'get', array('contact_id' => $contact1['id']));
311 $this->assertEquals(1, $email1['count']);
312 $this->assertEquals($primaryEmail, $email1['values'][$email1['id']]['email']);
314 $email2 = $this->callAPISuccess('email', 'create', array('contact_id' => $contact1['id'], 'is_primary' => 0, 'email' => $notPrimaryEmail));
316 // Case 1: Check with criteria primary 'email' => array('IS NOT NULL' => 1)
317 $result = $this->callAPISuccess('contact', 'get', array('email' => array('IS NOT NULL' => 1)));
318 $primaryEmailContactIds = array_keys($result['values']);
319 $this->assertEquals($primaryEmail, $email1['values'][$email1['id']]['email']);
321 // Case 2: Check with criteria primary 'email' => array('<>' => '')
322 $result = $this->callAPISuccess('contact', 'get', array('email' => array('<>' => '')));
323 $primaryEmailContactIds = array_keys($result['values']);
324 $this->assertEquals($primaryEmail, $email1['values'][$email1['id']]['email']);
326 // Case 3: Check with email_id='primary email id'
327 $result = $this->callAPISuccess('contact', 'get', array('email_id' => $email1['id']));
328 $this->assertEquals(1, $result['count']);
329 $this->assertEquals($contact1['id'], $result['id']);
331 $this->callAPISuccess('contact', 'delete', $contact1);
335 * Test creating individual by name.
337 * Verify create individual contact with only first and last names succeeds.
339 public function testCreateNameIndividual() {
341 'first_name' => 'abc1',
342 'contact_type' => 'Individual',
343 'last_name' => 'xyz1',
346 $this->callAPISuccess('contact', 'create', $params);
350 * Test creating individual by display_name.
352 * Display name & sort name should be set.
354 public function testCreateDisplayNameIndividual() {
356 'display_name' => 'abc1',
357 'contact_type' => 'Individual',
360 $contact = $this->callAPISuccess('contact', 'create', $params);
361 $params['sort_name'] = 'abc1';
362 $this->getAndCheck($params, $contact['id'], 'contact');
366 * Test old keys still work.
368 * Verify that attempt to create individual contact with
369 * first and last names and old key values works
371 public function testCreateNameIndividualOldKeys() {
373 'individual_prefix' => 'Dr.',
374 'first_name' => 'abc1',
375 'contact_type' => 'Individual',
376 'last_name' => 'xyz1',
377 'individual_suffix' => 'Jr.',
380 $contact = $this->callAPISuccess('contact', 'create', $params);
381 $result = $this->callAPISuccess('contact', 'getsingle', array('id' => $contact['id']));
383 $this->assertArrayKeyExists('prefix_id', $result);
384 $this->assertArrayKeyExists('suffix_id', $result);
385 $this->assertArrayKeyExists('gender_id', $result);
386 $this->assertEquals(4, $result['prefix_id']);
387 $this->assertEquals(1, $result['suffix_id']);
391 * Test preferred keys work.
393 * Verify that attempt to create individual contact with
394 * first and last names and old key values works
396 public function testCreateNameIndividualRecommendedKeys2() {
398 'prefix_id' => 'Dr.',
399 'first_name' => 'abc1',
400 'contact_type' => 'Individual',
401 'last_name' => 'xyz1',
402 'suffix_id' => 'Jr.',
403 'gender_id' => 'Male',
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 household name is sufficient for create.
419 * Verify that attempt to create household contact with only
420 * household name succeeds
422 public function testCreateNameHousehold() {
424 'household_name' => 'The abc Household',
425 'contact_type' => 'Household',
427 $this->callAPISuccess('contact', 'create', $params);
431 * Test organization name is sufficient for create.
433 * Verify that attempt to create organization contact with only
434 * organization name succeeds.
436 public function testCreateNameOrganization() {
438 'organization_name' => 'The abc Organization',
439 'contact_type' => 'Organization',
441 $this->callAPISuccess('contact', 'create', $params);
445 * Verify that attempt to create organization contact without organization name fails.
447 public function testCreateNoNameOrganization() {
449 'first_name' => 'The abc Organization',
450 'contact_type' => 'Organization',
452 $this->callAPIFailure('contact', 'create', $params);
456 * Check with complete array + custom field.
458 * Note that the test is written on purpose without any
459 * variables specific to participant so it can be replicated into other entities
460 * and / or moved to the automated test suite
462 public function testCreateWithCustom() {
463 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__
, __FILE__
);
465 $params = $this->_params
;
466 $params['custom_' . $ids['custom_field_id']] = "custom string";
467 $description = "This demonstrates setting a custom field through the API.";
468 $result = $this->callAPIAndDocument($this->_entity
, 'create', $params, __FUNCTION__
, __FILE__
, $description);
470 $check = $this->callAPISuccess($this->_entity
, 'get', array(
471 'return.custom_' . $ids['custom_field_id'] => 1,
472 'id' => $result['id'],
474 $this->assertEquals("custom string", $check['values'][$check['id']]['custom_' . $ids['custom_field_id']]);
476 $this->customFieldDelete($ids['custom_field_id']);
477 $this->customGroupDelete($ids['custom_group_id']);
481 * CRM-12773 - expectation is that civicrm quietly ignores fields without values.
483 public function testCreateWithNULLCustomCRM12773() {
484 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__
, __FILE__
);
485 $params = $this->_params
;
486 $params['custom_' . $ids['custom_field_id']] = NULL;
487 $this->callAPISuccess('contact', 'create', $params);
488 $this->customFieldDelete($ids['custom_field_id']);
489 $this->customGroupDelete($ids['custom_group_id']);
493 * CRM-14232 test preferred language set to site default if not passed.
495 public function testCreatePreferredLanguageUnset() {
496 $this->callAPISuccess('Contact', 'create', array(
497 'first_name' => 'Snoop',
498 'last_name' => 'Dog',
499 'contact_type' => 'Individual')
501 $result = $this->callAPISuccessGetSingle('Contact', array('last_name' => 'Dog'));
502 $this->assertEquals('en_US', $result['preferred_language']);
506 * CRM-14232 test preferred language returns setting if not passed.
508 public function testCreatePreferredLanguageSet() {
509 $this->callAPISuccess('Setting', 'create', array('contact_default_language' => 'fr_FR'));
510 $this->callAPISuccess('Contact', 'create', array(
511 'first_name' => 'Snoop',
512 'last_name' => 'Dog',
513 'contact_type' => 'Individual',
515 $result = $this->callAPISuccessGetSingle('Contact', array('last_name' => 'Dog'));
516 $this->assertEquals('fr_FR', $result['preferred_language']);
520 * CRM-14232 test preferred language returns setting if not passed where setting is NULL.
522 public function testCreatePreferredLanguageNull() {
523 $this->callAPISuccess('Setting', 'create', array('contact_default_language' => 'null'));
524 $this->callAPISuccess('Contact', 'create', array(
525 'first_name' => 'Snoop',
526 'last_name' => 'Dog',
527 'contact_type' => 'Individual',
530 $result = $this->callAPISuccessGetSingle('Contact', array('last_name' => 'Dog'));
531 $this->assertEquals(NULL, $result['preferred_language']);
535 * CRM-14232 test preferred language returns setting if not passed where setting is NULL.
537 public function testCreatePreferredLanguagePassed() {
538 $this->callAPISuccess('Setting', 'create', array('contact_default_language' => 'null'));
539 $this->callAPISuccess('Contact', 'create', array(
540 'first_name' => 'Snoop',
541 'last_name' => 'Dog',
542 'contact_type' => 'Individual',
543 'preferred_language' => 'en_AU',
545 $result = $this->callAPISuccessGetSingle('Contact', array('last_name' => 'Dog'));
546 $this->assertEquals('en_AU', $result['preferred_language']);
550 * CRM-15792 - create/update datetime field for contact.
552 public function testCreateContactCustomFldDateTime() {
553 $customGroup = $this->customGroupCreate(array('extends' => 'Individual', 'title' => 'datetime_test_group'));
554 $dateTime = CRM_Utils_Date
::currentDBDate();
555 //check date custom field is saved along with time when time_format is set
557 'first_name' => 'abc3',
558 'last_name' => 'xyz3',
559 'contact_type' => 'Individual',
560 'email' => 'man3@yahoo.com',
561 'api.CustomField.create' => array(
562 'custom_group_id' => $customGroup['id'],
563 'name' => 'test_datetime',
564 'label' => 'Demo Date',
565 'html_type' => 'Select Date',
566 'data_type' => 'Date',
570 'is_searchable' => 0,
575 $result = $this->callAPISuccess('Contact', 'create', $params);
576 $customFldId = $result['values'][$result['id']]['api.CustomField.create']['id'];
577 $this->assertNotNull($result['id']);
578 $this->assertNotNull($customFldId);
581 'id' => $result['id'],
582 "custom_{$customFldId}" => $dateTime,
583 'api.CustomValue.get' => 1,
586 $result = $this->callAPISuccess('Contact', 'create', $params);
587 $this->assertNotNull($result['id']);
588 $customFldDate = date("YmdHis", strtotime($result['values'][$result['id']]['api.CustomValue.get']['values'][0]['latest']));
589 $this->assertNotNull($customFldDate);
590 $this->assertEquals($dateTime, $customFldDate);
591 $customValueId = $result['values'][$result['id']]['api.CustomValue.get']['values'][0]['id'];
592 $dateTime = date('Ymd');
593 //date custom field should not contain time part when time_format is null
595 'id' => $result['id'],
596 'api.CustomField.create' => array(
597 'id' => $customFldId,
598 'html_type' => 'Select Date',
599 'data_type' => 'Date',
602 'api.CustomValue.create' => array(
603 'id' => $customValueId,
604 'entity_id' => $result['id'],
605 "custom_{$customFldId}" => $dateTime,
607 'api.CustomValue.get' => 1,
609 $result = $this->callAPISuccess('Contact', 'create', $params);
610 $this->assertNotNull($result['id']);
611 $customFldDate = date("Ymd", strtotime($result['values'][$result['id']]['api.CustomValue.get']['values'][0]['latest']));
612 $customFldTime = date("His", strtotime($result['values'][$result['id']]['api.CustomValue.get']['values'][0]['latest']));
613 $this->assertNotNull($customFldDate);
614 $this->assertEquals($dateTime, $customFldDate);
615 $this->assertEquals(000000, $customFldTime);
616 $this->callAPISuccess('Contact', 'create', $params);
621 * Test creating a current employer through API.
623 public function testContactCreateCurrentEmployer() {
624 // Here we will just do the get for set-up purposes.
625 $count = $this->callAPISuccess('contact', 'getcount', array(
626 'organization_name' => 'new employer org',
627 'contact_type' => 'Organization',
629 $this->assertEquals(0, $count);
630 $employerResult = $this->callAPISuccess('contact', 'create', array_merge($this->_params
, array(
631 'current_employer' => 'new employer org',
634 // do it again as an update to check it doesn't cause an error
635 $employerResult = $this->callAPISuccess('contact', 'create', array_merge($this->_params
, array(
636 'current_employer' => 'new employer org',
637 'id' => $employerResult['id'],
641 $this->callAPISuccess('contact', 'getcount', array(
642 'organization_name' => 'new employer org',
643 'contact_type' => 'Organization',
647 $result = $this->callAPISuccess('contact', 'getsingle', array(
648 'id' => $employerResult['id'],
651 $this->assertEquals('new employer org', $result['current_employer']);
656 * Test creating a current employer through API.
658 * Check it will re-activate a de-activated employer
660 public function testContactCreateDuplicateCurrentEmployerEnables() {
661 // Set up - create employer relationship.
662 $employerResult = $this->callAPISuccess('contact', 'create', array_merge($this->_params
, array(
663 'current_employer' => 'new employer org',
666 $relationship = $this->callAPISuccess('relationship', 'get', array(
667 'contact_id_a' => $employerResult['id'],
670 //disable & check it is disabled
671 $this->callAPISuccess('relationship', 'create', array('id' => $relationship['id'], 'is_active' => 0));
672 $this->callAPISuccess('relationship', 'getvalue', array(
673 'id' => $relationship['id'],
674 'return' => 'is_active',
677 // Re-set the current employer - thus enabling the relationship.
678 $this->callAPISuccess('contact', 'create', array_merge($this->_params
, array(
679 'current_employer' => 'new employer org',
680 'id' => $employerResult['id'],
683 //check is_active is now 1
684 $relationship = $this->callAPISuccess('relationship', 'getsingle', array(
685 'return' => 'is_active',
687 $this->assertEquals(1, $relationship['is_active']);
691 * Check deceased contacts are not retrieved.
693 * Note at time of writing the default is to return default. This should possibly be changed & test added.
695 public function testGetDeceasedRetrieved() {
696 $this->callAPISuccess($this->_entity
, 'create', $this->_params
);
697 $c2 = $this->callAPISuccess($this->_entity
, 'create', array(
698 'first_name' => 'bb',
699 'last_name' => 'ccc',
700 'contact_type' => 'Individual',
703 $result = $this->callAPISuccess($this->_entity
, 'get', array('is_deceased' => 0));
704 $this->assertFalse(array_key_exists($c2['id'], $result['values']));
708 * Test that sort works - old syntax.
710 public function testGetSort() {
711 $c1 = $this->callAPISuccess($this->_entity
, 'create', $this->_params
);
712 $c2 = $this->callAPISuccess($this->_entity
, 'create', array(
713 'first_name' => 'bb',
714 'last_name' => 'ccc',
715 'contact_type' => 'Individual',
717 $result = $this->callAPISuccess($this->_entity
, 'get', array(
718 'sort' => 'first_name ASC',
719 'return.first_name' => 1,
722 'contact_type' => 'Individual',
725 $this->assertEquals('abc1', $result['values'][0]['first_name']);
726 $result = $this->callAPISuccess($this->_entity
, 'get', array(
727 'sort' => 'first_name DESC',
728 'return.first_name' => 1,
732 $this->assertEquals('bb', $result['values'][0]['first_name']);
734 $this->callAPISuccess($this->_entity
, 'delete', array('id' => $c1['id']));
735 $this->callAPISuccess($this->_entity
, 'delete', array('id' => $c2['id']));
739 * Test that we can retrieve contacts using array syntax.
741 * I.e 'id' => array('IN' => array('3,4')).
743 public function testGetINIDArray() {
744 $c1 = $this->callAPISuccess($this->_entity
, 'create', $this->_params
);
745 $c2 = $this->callAPISuccess($this->_entity
, 'create', array(
746 'first_name' => 'bb',
747 'last_name' => 'ccc',
748 'contact_type' => 'Individual',
750 $c3 = $this->callAPISuccess($this->_entity
, 'create', array(
751 'first_name' => 'hh',
753 'contact_type' => 'Individual',
755 $result = $this->callAPISuccess($this->_entity
, 'get', array('id' => array('IN' => array($c1['id'], $c3['id']))));
756 $this->assertEquals(2, $result['count']);
757 $this->assertEquals(array($c1['id'], $c3['id']), array_keys($result['values']));
758 $this->callAPISuccess($this->_entity
, 'delete', array('id' => $c1['id']));
759 $this->callAPISuccess($this->_entity
, 'delete', array('id' => $c2['id']));
760 $this->callAPISuccess($this->_entity
, 'delete', array('id' => $c3['id']));
764 * Test variants on deleted behaviour.
766 public function testGetDeleted() {
767 $params = $this->_params
;
768 $contact1 = $this->callAPISuccess('contact', 'create', $params);
769 $params['is_deleted'] = 1;
770 $params['last_name'] = 'bcd';
771 $contact2 = $this->callAPISuccess('contact', 'create', $params);
772 $countActive = $this->callAPISuccess('contact', 'getcount', array(
773 'showAll' => 'active',
774 'contact_type' => 'Individual',
776 $countAll = $this->callAPISuccess('contact', 'getcount', array('showAll' => 'all', 'contact_type' => 'Individual'));
777 $countTrash = $this->callAPISuccess('contact', 'getcount', array('showAll' => 'trash', 'contact_type' => 'Individual'));
778 $countDefault = $this->callAPISuccess('contact', 'getcount', array('contact_type' => 'Individual'));
779 $countDeleted = $this->callAPISuccess('contact', 'getcount', array(
780 'contact_type' => 'Individual',
781 'contact_is_deleted' => 1,
783 $countNotDeleted = $this->callAPISuccess('contact', 'getcount', array(
784 'contact_is_deleted' => 0,
785 'contact_type' => 'Individual',
787 $this->callAPISuccess('contact', 'delete', array('id' => $contact1['id']));
788 $this->callAPISuccess('contact', 'delete', array('id' => $contact2['id']));
789 $this->assertEquals(1, $countNotDeleted, 'contact_is_deleted => 0 is respected');
790 $this->assertEquals(1, $countActive);
791 $this->assertEquals(1, $countTrash);
792 $this->assertEquals(2, $countAll);
793 $this->assertEquals(1, $countDeleted);
794 $this->assertEquals(1, $countDefault, 'Only active by default in line');
798 * Test that sort works - new syntax.
800 public function testGetSortNewSyntax() {
801 $c1 = $this->callAPISuccess($this->_entity
, 'create', $this->_params
);
802 $c2 = $this->callAPISuccess($this->_entity
, 'create', array(
803 'first_name' => 'bb',
804 'last_name' => 'ccc',
805 'contact_type' => 'Individual',
807 $result = $this->callAPISuccess($this->_entity
, 'getvalue', array(
808 'return' => 'first_name',
809 'contact_type' => 'Individual',
812 'sort' => 'first_name',
815 $this->assertEquals('abc1', $result);
817 $result = $this->callAPISuccess($this->_entity
, 'getvalue', array(
818 'return' => 'first_name',
819 'contact_type' => 'Individual',
822 'sort' => 'first_name DESC',
825 $this->assertEquals('bb', $result);
827 $this->callAPISuccess($this->_entity
, 'delete', array('id' => $c1['id']));
828 $this->callAPISuccess($this->_entity
, 'delete', array('id' => $c2['id']));
832 * Test sort and limit for chained relationship get.
834 * https://issues.civicrm.org/jira/browse/CRM-15983
836 public function testSortLimitChainedRelationshipGetCRM15983() {
838 $create_result_1 = $this->callAPISuccess('contact', 'create', array(
839 'first_name' => 'Jules',
840 'last_name' => 'Smos',
841 'contact_type' => 'Individual',
844 // Create another contact with two relationships.
845 $create_params = array(
846 'first_name' => 'Jos',
847 'last_name' => 'Smos',
848 'contact_type' => 'Individual',
849 'api.relationship.create' => array(
851 'contact_id_a' => '$value.id',
852 'contact_id_b' => $create_result_1['id'],
854 'relationship_type_id' => 2,
855 'start_date' => '2005-01-12',
856 'end_date' => '2006-01-11',
857 'description' => 'old',
860 'contact_id_a' => '$value.id',
861 'contact_id_b' => $create_result_1['id'],
862 // spouse of (was married twice :))
863 'relationship_type_id' => 2,
864 'start_date' => '2006-07-01',
865 'end_date' => '2010-07-01',
866 'description' => 'new',
870 $create_result = $this->callAPISuccess('contact', 'create', $create_params);
872 // Try to retrieve the contact and the most recent relationship.
875 'id' => $create_result['id'],
876 'api.relationship.get' => array(
877 'contact_id_a' => '$value.id',
880 'sort' => 'start_date DESC',
883 $get_result = $this->callAPISuccess('contact', 'getsingle', $get_params);
886 $this->callAPISuccess('contact', 'delete', array(
887 'id' => $create_result['id'],
891 $this->assertEquals(1, $get_result['api.relationship.get']['count']);
892 $this->assertEquals('new', $get_result['api.relationship.get']['values'][0]['description']);
896 * Test apostrophe works in get & create.
898 public function testGetApostropheCRM10857() {
899 $params = array_merge($this->_params
, array('last_name' => "O'Connor"));
900 $this->callAPISuccess($this->_entity
, 'create', $params);
901 $result = $this->callAPISuccess($this->_entity
, 'getsingle', array(
902 'last_name' => "O'Connor",
905 $this->assertEquals("O'Connor", $result['last_name'], 'in line' . __LINE__
);
909 * Check with complete array + custom field.
911 * Note that the test is written on purpose without any
912 * variables specific to participant so it can be replicated into other entities
913 * and / or moved to the automated test suite
915 public function testGetWithCustom() {
916 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__
, __FILE__
);
918 $params = $this->_params
;
919 $params['custom_' . $ids['custom_field_id']] = "custom string";
920 $description = "This demonstrates setting a custom field through the API.";
921 $subfile = "CustomFieldGet";
922 $result = $this->callAPISuccess($this->_entity
, 'create', $params);
924 $check = $this->callAPIAndDocument($this->_entity
, 'get', array(
925 'return.custom_' . $ids['custom_field_id'] => 1,
926 'id' => $result['id'],
927 ), __FUNCTION__
, __FILE__
, $description, $subfile);
929 $this->assertEquals("custom string", $check['values'][$check['id']]['custom_' . $ids['custom_field_id']]);
930 $fields = ($this->callAPISuccess('contact', 'getfields', $params));
931 $this->assertTrue(is_array($fields['values']['custom_' . $ids['custom_field_id']]));
932 $this->customFieldDelete($ids['custom_field_id']);
933 $this->customGroupDelete($ids['custom_group_id']);
937 * Check with complete array + custom field.
939 * Note that the test is written on purpose without any
940 * variables specific to participant so it can be replicated into other entities
941 * and / or moved to the automated test suite
943 public function testGetWithCustomReturnSyntax() {
944 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__
, __FILE__
);
946 $params = $this->_params
;
947 $params['custom_' . $ids['custom_field_id']] = "custom string";
948 $description = "This demonstrates setting a custom field through the API.";
949 $subfile = "CustomFieldGetReturnSyntaxVariation";
950 $result = $this->callAPISuccess($this->_entity
, 'create', $params);
951 $params = array('return' => 'custom_' . $ids['custom_field_id'], 'id' => $result['id']);
952 $check = $this->callAPIAndDocument($this->_entity
, 'get', $params, __FUNCTION__
, __FILE__
, $description, $subfile);
954 $this->assertEquals("custom string", $check['values'][$check['id']]['custom_' . $ids['custom_field_id']]);
955 $this->customFieldDelete($ids['custom_field_id']);
956 $this->customGroupDelete($ids['custom_group_id']);
960 * Check that address name, ID is returned if required.
962 public function testGetReturnAddress() {
963 $contactID = $this->individualCreate();
964 $result = $this->callAPISuccess('address', 'create', array(
965 'contact_id' => $contactID,
966 'address_name' => 'My house',
967 'location_type_id' => 'Home',
968 'street_address' => '1 my road',
970 $addressID = $result['id'];
972 $result = $this->callAPISuccessGetSingle('contact', array(
973 'return' => 'address_name, street_address, address_id',
976 $this->assertEquals($addressID, $result['address_id']);
977 $this->assertEquals('1 my road', $result['street_address']);
978 $this->assertEquals('My house', $result['address_name']);
983 * Test group filter syntaxes.
985 public function testGetGroupIDFromContact() {
986 $groupId = $this->groupCreate();
988 'email' => 'man2@yahoo.com',
989 'contact_type' => 'Individual',
990 'location_type_id' => 1,
991 'api.group_contact.create' => array('group_id' => $groupId),
994 $this->callAPISuccess('contact', 'create', $params);
995 // testing as integer
997 'filter.group_id' => $groupId,
998 'contact_type' => 'Individual',
1000 $result = $this->callAPISuccess('contact', 'get', $params);
1001 $this->assertEquals(1, $result['count']);
1002 // group 26 doesn't exist, but we can still search contacts in it.
1004 'filter.group_id' => 26,
1005 'contact_type' => 'Individual',
1007 $this->callAPISuccess('contact', 'get', $params);
1008 // testing as string
1010 'filter.group_id' => "$groupId, 26",
1011 'contact_type' => 'Individual',
1013 $result = $this->callAPISuccess('contact', 'get', $params);
1014 $this->assertEquals(1, $result['count']);
1016 'filter.group_id' => "26,27",
1017 'contact_type' => 'Individual',
1019 $this->callAPISuccess('contact', 'get', $params);
1021 // testing as string
1023 'filter.group_id' => array($groupId, 26),
1024 'contact_type' => 'Individual',
1026 $result = $this->callAPISuccess('contact', 'get', $params);
1027 $this->assertEquals(1, $result['count']);
1029 //test in conjunction with other criteria
1031 'filter.group_id' => array($groupId, 26),
1032 'contact_type' => 'Organization',
1034 $this->callAPISuccess('contact', 'get', $params);
1036 'filter.group_id' => array(26, 27),
1037 'contact_type' => 'Individual',
1039 $result = $this->callAPISuccess('contact', 'get', $params);
1040 $this->assertEquals(0, $result['count']);
1044 * Verify that attempt to create individual contact with two chained websites succeeds.
1046 public function testCreateIndividualWithContributionDottedSyntax() {
1047 $description = "This demonstrates the syntax to create 2 chained entities.";
1048 $subFile = "ChainTwoWebsites";
1050 'first_name' => 'abc3',
1051 'last_name' => 'xyz3',
1052 'contact_type' => 'Individual',
1053 'email' => 'man3@yahoo.com',
1054 'api.contribution.create' => array(
1055 'receive_date' => '2010-01-01',
1056 'total_amount' => 100.00,
1057 'financial_type_id' => $this->_financialTypeId
,
1058 'payment_instrument_id' => 1,
1059 'non_deductible_amount' => 10.00,
1060 'fee_amount' => 50.00,
1061 'net_amount' => 90.00,
1063 'invoice_id' => 67990,
1065 'contribution_status_id' => 1,
1067 'api.website.create' => array(
1068 'url' => "http://civicrm.org",
1070 'api.website.create.2' => array(
1071 'url' => "http://chained.org",
1075 $result = $this->callAPIAndDocument('Contact', 'create', $params, __FUNCTION__
, __FILE__
, $description, $subFile);
1077 // checking child function result not covered in callAPIAndDocument
1078 $this->assertAPISuccess($result['values'][$result['id']]['api.website.create']);
1079 $this->assertEquals("http://chained.org", $result['values'][$result['id']]['api.website.create.2']['values'][0]['url']);
1080 $this->assertEquals("http://civicrm.org", $result['values'][$result['id']]['api.website.create']['values'][0]['url']);
1082 // delete the contact
1083 $this->callAPISuccess('contact', 'delete', $result);
1087 * Verify that attempt to create individual contact with chained contribution and website succeeds.
1089 public function testCreateIndividualWithContributionChainedArrays() {
1091 'first_name' => 'abc3',
1092 'last_name' => 'xyz3',
1093 'contact_type' => 'Individual',
1094 'email' => 'man3@yahoo.com',
1095 'api.contribution.create' => array(
1096 'receive_date' => '2010-01-01',
1097 'total_amount' => 100.00,
1098 'financial_type_id' => $this->_financialTypeId
,
1099 'payment_instrument_id' => 1,
1100 'non_deductible_amount' => 10.00,
1101 'fee_amount' => 50.00,
1102 'net_amount' => 90.00,
1104 'invoice_id' => 67890,
1106 'contribution_status_id' => 1,
1108 'api.website.create' => array(
1110 'url' => "http://civicrm.org",
1113 'url' => "http://chained.org",
1114 'website_type_id' => 2,
1119 $description = "Demonstrates creating two websites as an array.";
1120 $subfile = "ChainTwoWebsitesSyntax2";
1121 $result = $this->callAPIAndDocument('Contact', 'create', $params, __FUNCTION__
, __FILE__
, $description, $subfile);
1123 // the callAndDocument doesn't check the chained call
1124 $this->assertEquals(0, $result['values'][$result['id']]['api.website.create'][0]['is_error']);
1125 $this->assertEquals("http://chained.org", $result['values'][$result['id']]['api.website.create'][1]['values'][0]['url']);
1126 $this->assertEquals("http://civicrm.org", $result['values'][$result['id']]['api.website.create'][0]['values'][0]['url']);
1128 $this->callAPISuccess('contact', 'delete', $result);
1132 * Test for direction when chaining relationships.
1134 * https://issues.civicrm.org/jira/browse/CRM-16084
1136 public function testDirectionChainingRelationshipsCRM16084() {
1137 // Some contact, called Jules.
1138 $create_result_1 = $this->callAPISuccess('contact', 'create', array(
1139 'first_name' => 'Jules',
1140 'last_name' => 'Smos',
1141 'contact_type' => 'Individual',
1144 // Another contact: Jos, child of Jules.
1145 $create_params = array(
1146 'first_name' => 'Jos',
1147 'last_name' => 'Smos',
1148 'contact_type' => 'Individual',
1149 'api.relationship.create' => array(
1151 'contact_id_a' => '$value.id',
1152 'contact_id_b' => $create_result_1['id'],
1154 'relationship_type_id' => 1,
1158 $create_result_2 = $this->callAPISuccess('contact', 'create', $create_params);
1160 // Mia is the child of Jos.
1161 $create_params = array(
1162 'first_name' => 'Mia',
1163 'last_name' => 'Smos',
1164 'contact_type' => 'Individual',
1165 'api.relationship.create' => array(
1167 'contact_id_a' => '$value.id',
1168 'contact_id_b' => $create_result_2['id'],
1170 'relationship_type_id' => 1,
1174 $create_result_3 = $this->callAPISuccess('contact', 'create', $create_params);
1176 // Get Jos and his children.
1177 $get_params = array(
1179 'id' => $create_result_2['id'],
1180 'api.relationship.get' => array(
1181 'contact_id_b' => '$value.id',
1182 'relationship_type_id' => 1,
1185 $get_result = $this->callAPISuccess('contact', 'getsingle', $get_params);
1188 $this->callAPISuccess('contact', 'delete', array(
1189 'id' => $create_result_1['id'],
1191 $this->callAPISuccess('contact', 'delete', array(
1192 'id' => $create_result_2['id'],
1194 $this->callAPISuccess('contact', 'delete', array(
1195 'id' => $create_result_2['id'],
1199 $this->assertEquals(1, $get_result['api.relationship.get']['count']);
1200 $this->assertEquals($create_result_3['id'], $get_result['api.relationship.get']['values'][0]['contact_id_a']);
1204 * Verify that attempt to create individual contact with first, and last names and email succeeds.
1206 public function testCreateIndividualWithNameEmail() {
1208 'first_name' => 'abc3',
1209 'last_name' => 'xyz3',
1210 'contact_type' => 'Individual',
1211 'email' => 'man3@yahoo.com',
1214 $contact = $this->callAPISuccess('contact', 'create', $params);
1216 $this->callAPISuccess('contact', 'delete', $contact);
1220 * Verify that attempt to create individual contact with no data fails.
1222 public function testCreateIndividualWithOutNameEmail() {
1224 'contact_type' => 'Individual',
1226 $this->callAPIFailure('contact', 'create', $params);
1230 * Test create individual contact with first &last names, email and location type succeeds.
1232 public function testCreateIndividualWithNameEmailLocationType() {
1234 'first_name' => 'abc4',
1235 'last_name' => 'xyz4',
1236 'email' => 'man4@yahoo.com',
1237 'contact_type' => 'Individual',
1238 'location_type_id' => 1,
1240 $result = $this->callAPISuccess('contact', 'create', $params);
1242 $this->callAPISuccess('contact', 'delete', array('id' => $result['id']));
1246 * Verify that when changing employers the old employer relationship becomes inactive.
1248 public function testCreateIndividualWithEmployer() {
1249 $employer = $this->organizationCreate();
1250 $employer2 = $this->organizationCreate();
1253 'email' => 'man4@yahoo.com',
1254 'contact_type' => 'Individual',
1255 'employer_id' => $employer,
1258 $result = $this->callAPISuccess('contact', 'create', $params);
1259 $relationships = $this->callAPISuccess('relationship', 'get', array(
1260 'contact_id_a' => $result['id'],
1264 $this->assertEquals($employer, $relationships['values'][0]['contact_id_b']);
1266 // Add more random relationships to make the test more realistic
1267 foreach (array('Employee of', 'Volunteer for') as $relationshipType) {
1268 $relTypeId = CRM_Core_DAO
::getFieldValue('CRM_Contact_DAO_RelationshipType', $relationshipType, 'id', 'name_a_b');
1269 $this->callAPISuccess('relationship', 'create', array(
1270 'contact_id_a' => $result['id'],
1271 'contact_id_b' => $this->organizationCreate(),
1273 'relationship_type_id' => $relTypeId,
1277 // Add second employer
1278 $params['employer_id'] = $employer2;
1279 $params['id'] = $result['id'];
1280 $result = $this->callAPISuccess('contact', 'create', $params);
1282 $relationships = $this->callAPISuccess('relationship', 'get', array(
1283 'contact_id_a' => $result['id'],
1288 $this->assertEquals($employer, $relationships['values'][0]['contact_id_b']);
1292 * Verify that attempt to create household contact with details succeeds.
1294 public function testCreateHouseholdDetails() {
1296 'household_name' => 'abc8\'s House',
1297 'nick_name' => 'x House',
1298 'email' => 'man8@yahoo.com',
1299 'contact_type' => 'Household',
1302 $contact = $this->callAPISuccess('contact', 'create', $params);
1304 $this->callAPISuccess('contact', 'delete', $contact);
1308 * Verify that attempt to create household contact with inadequate details fails.
1310 public function testCreateHouseholdInadequateDetails() {
1312 'nick_name' => 'x House',
1313 'email' => 'man8@yahoo.com',
1314 'contact_type' => 'Household',
1316 $this->callAPIFailure('contact', 'create', $params);
1320 * Verify successful update of individual contact.
1322 public function testUpdateIndividualWithAll() {
1323 // Insert a row in civicrm_contact creating individual contact.
1324 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1325 $op->execute($this->_dbconn
,
1326 $this->createXMLDataSet(
1327 dirname(__FILE__
) . '/dataset/contact_ind.xml'
1333 'first_name' => 'abcd',
1334 'contact_type' => 'Individual',
1335 'nick_name' => 'This is nickname first',
1336 'do_not_email' => '1',
1337 'do_not_phone' => '1',
1338 'do_not_mail' => '1',
1339 'do_not_trade' => '1',
1340 'legal_identifier' => 'ABC23853ZZ2235',
1341 'external_identifier' => '1928837465',
1342 'image_URL' => 'http://some.url.com/image.jpg',
1343 'home_url' => 'http://www.example.org',
1347 $this->callAPISuccess('Contact', 'Update', $params);
1348 $getResult = $this->callAPISuccess('Contact', 'Get', $params);
1349 unset($params['contact_id']);
1350 //Todo - neither API v2 or V3 are testing for home_url - not sure if it is being set.
1351 //reducing this test partially back to api v2 level to get it through
1352 unset($params['home_url']);
1353 foreach ($params as $key => $value) {
1354 $this->assertEquals($value, $getResult['values'][23][$key]);
1356 // Check updated civicrm_contact against expected.
1357 $expected = $this->createXMLDataSet(
1358 dirname(__FILE__
) . '/dataset/contact_ind_upd.xml'
1360 $actual = new PHPUnit_Extensions_Database_DataSet_QueryDataSet(
1363 $actual->addTable('civicrm_contact');
1364 $expected->matches($actual);
1368 * Verify successful update of organization contact.
1370 public function testUpdateOrganizationWithAll() {
1371 // Insert a row in civicrm_contact creating organization contact
1372 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1373 $op->execute($this->_dbconn
,
1374 $this->createXMLDataSet(
1375 dirname(__FILE__
) . '/dataset/contact_org.xml'
1381 'organization_name' => 'WebAccess India Pvt Ltd',
1382 'legal_name' => 'WebAccess',
1383 'sic_code' => 'ABC12DEF',
1384 'contact_type' => 'Organization',
1387 $this->callAPISuccess('Contact', 'Update', $params);
1389 // Check updated civicrm_contact against expected.
1390 $expected = $this->createXMLDataSet(
1391 dirname(__FILE__
) . '/dataset/contact_org_upd.xml'
1393 $actual = new PHPUnit_Extensions_Database_DataSet_QueryDataSet(
1396 $actual->addTable('civicrm_contact');
1397 $expected->matches($actual);
1401 * Verify successful update of household contact.
1403 public function testUpdateHouseholdWithAll() {
1404 // Insert a row in civicrm_contact creating household contact
1405 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1406 $op->execute($this->_dbconn
,
1407 $this->createXMLDataSet(
1408 dirname(__FILE__
) . '/dataset/contact_hld.xml'
1414 'household_name' => 'ABC household',
1415 'nick_name' => 'ABC House',
1416 'contact_type' => 'Household',
1419 $result = $this->callAPISuccess('Contact', 'Update', $params);
1422 'contact_type' => 'Household',
1424 'sort_name' => 'ABC household',
1425 'display_name' => 'ABC household',
1426 'nick_name' => 'ABC House',
1428 $this->getAndCheck($expected, $result['id'], 'contact');
1432 * Test civicrm_update() without contact type.
1434 * Deliberately exclude contact_type as it should still cope using civicrm_api.
1438 public function testUpdateCreateWithID() {
1439 // Insert a row in civicrm_contact creating individual contact.
1440 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1441 $op->execute($this->_dbconn
,
1442 $this->createXMLDataSet(
1443 dirname(__FILE__
) . '/dataset/contact_ind.xml'
1449 'first_name' => 'abcd',
1450 'last_name' => 'wxyz',
1452 $this->callAPISuccess('Contact', 'Update', $params);
1456 * Test civicrm_contact_delete() with no contact ID.
1458 public function testContactDeleteNoID() {
1462 $this->callAPIFailure('contact', 'delete', $params);
1466 * Test civicrm_contact_delete() with error.
1468 public function testContactDeleteError() {
1469 $params = array('contact_id' => 999);
1470 $this->callAPIFailure('contact', 'delete', $params);
1474 * Test civicrm_contact_delete().
1476 public function testContactDelete() {
1477 $contactID = $this->individualCreate();
1481 $this->callAPIAndDocument('contact', 'delete', $params, __FUNCTION__
, __FILE__
);
1485 * Test civicrm_contact_get() return only first name.
1487 public function testContactGetRetFirst() {
1488 $contact = $this->callAPISuccess('contact', 'create', $this->_params
);
1490 'contact_id' => $contact['id'],
1491 'return_first_name' => TRUE,
1492 'sort' => 'first_name',
1494 $result = $this->callAPISuccess('contact', 'get', $params);
1495 $this->assertEquals(1, $result['count']);
1496 $this->assertEquals($contact['id'], $result['id']);
1497 $this->assertEquals('abc1', $result['values'][$contact['id']]['first_name']);
1501 * Test civicrm_contact_get() return only first name & last name.
1503 * Use comma separated string return with a space.
1505 public function testContactGetReturnFirstLast() {
1506 $contact = $this->callAPISuccess('contact', 'create', $this->_params
);
1508 'contact_id' => $contact['id'],
1509 'return' => 'first_name, last_name',
1511 $result = $this->callAPISuccess('contact', 'getsingle', $params);
1512 $this->assertEquals('abc1', $result['first_name']);
1513 $this->assertEquals('xyz1', $result['last_name']);
1514 //check that other defaults not returns
1515 $this->assertArrayNotHasKey('sort_name', $result);
1517 'contact_id' => $contact['id'],
1518 'return' => 'first_name,last_name',
1520 $result = $this->callAPISuccess('contact', 'getsingle', $params);
1521 $this->assertEquals('abc1', $result['first_name']);
1522 $this->assertEquals('xyz1', $result['last_name']);
1523 //check that other defaults not returns
1524 $this->assertArrayNotHasKey('sort_name', $result);
1528 * Test civicrm_contact_get() return only first name & last name.
1530 * Use comma separated string return without a space
1532 public function testContactGetReturnFirstLastNoComma() {
1533 $contact = $this->callAPISuccess('contact', 'create', $this->_params
);
1535 'contact_id' => $contact['id'],
1536 'return' => 'first_name,last_name',
1538 $result = $this->callAPISuccess('contact', 'getsingle', $params);
1539 $this->assertEquals('abc1', $result['first_name']);
1540 $this->assertEquals('xyz1', $result['last_name']);
1541 //check that other defaults not returns
1542 $this->assertArrayNotHasKey('sort_name', $result);
1546 * Test civicrm_contact_get() with default return properties.
1548 public function testContactGetRetDefault() {
1549 $contactID = $this->individualCreate();
1551 'contact_id' => $contactID,
1552 'sort' => 'first_name',
1554 $result = $this->callAPISuccess('contact', 'get', $params);
1555 $this->assertEquals($contactID, $result['values'][$contactID]['contact_id']);
1556 $this->assertEquals('Anthony', $result['values'][$contactID]['first_name']);
1560 * Test civicrm_contact_getquick() with empty name param.
1562 public function testContactGetQuick() {
1563 // Insert a row in civicrm_contact creating individual contact.
1564 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1565 $op->execute($this->_dbconn
,
1566 $this->createXMLDataSet(
1567 dirname(__FILE__
) . '/dataset/contact_17.xml'
1570 $op->execute($this->_dbconn
,
1571 $this->createXMLDataSet(
1572 dirname(__FILE__
) . '/dataset/email_contact_17.xml'
1579 $result = $this->callAPISuccess('contact', 'getquick', $params);
1580 $this->assertEquals(17, $result['values'][0]['id']);
1584 * Test civicrm_contact_get) with empty params.
1586 public function testContactGetEmptyParams() {
1587 $this->callAPISuccess('contact', 'get', array());
1591 * Test civicrm_contact_get(,true) with no matches.
1593 public function testContactGetOldParamsNoMatches() {
1594 // Insert a row in civicrm_contact creating contact 17.
1595 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1596 $op->execute($this->_dbconn
,
1597 $this->createXMLDataSet(
1598 dirname(__FILE__
) . '/dataset/contact_17.xml'
1603 'first_name' => 'Fred',
1605 $result = $this->callAPISuccess('contact', 'get', $params);
1606 $this->assertEquals(0, $result['count']);
1610 * Test civicrm_contact_get(,true) with one match.
1612 public function testContactGetOldParamsOneMatch() {
1613 // Insert a row in civicrm_contact creating contact 17
1614 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1615 $op->execute($this->_dbconn
,
1616 $this->createXMLDataSet(dirname(__FILE__
) . '/dataset/contact_17.xml'
1621 'first_name' => 'Test',
1623 $result = $this->callAPISuccess('contact', 'get', $params);
1624 $this->assertEquals(17, $result['values'][17]['contact_id']);
1625 $this->assertEquals(17, $result['id']);
1629 * Test civicrm_contact_search_count().
1631 public function testContactGetEmail() {
1633 'email' => 'man2@yahoo.com',
1634 'contact_type' => 'Individual',
1635 'location_type_id' => 1,
1638 $contact = $this->callAPISuccess('contact', 'create', $params);
1641 'email' => 'man2@yahoo.com',
1643 $result = $this->callAPIAndDocument('contact', 'get', $params, __FUNCTION__
, __FILE__
);
1644 $this->assertEquals('man2@yahoo.com', $result['values'][$result['id']]['email']);
1646 $this->callAPISuccess('contact', 'delete', $contact);
1650 * Ensure consistent return format for option group fields.
1652 public function testPseudoFields() {
1654 'preferred_communication_method' => array('Phone', 'SMS'),
1655 'preferred_language' => 'en_US',
1656 'gender_id' => 'Female',
1657 'prefix_id' => 'Mrs.',
1658 'suffix_id' => 'II',
1659 'communication_style_id' => 'Formal',
1662 $contact = $this->callAPISuccess('contact', 'create', array_merge($this->_params
, $params));
1664 $result = $this->callAPISuccess('contact', 'getsingle', array('id' => $contact['id']));
1665 $this->assertEquals('Both', $result['preferred_mail_format']);
1667 $this->assertEquals('en_US', $result['preferred_language']);
1668 $this->assertEquals(1, $result['communication_style_id']);
1669 $this->assertEquals(1, $result['gender_id']);
1670 $this->assertEquals('Female', $result['gender']);
1671 $this->assertEquals('Mrs.', $result['individual_prefix']);
1672 $this->assertEquals(1, $result['prefix_id']);
1673 $this->assertEquals('II', $result['individual_suffix']);
1674 $this->assertEquals(CRM_Core_PseudoConstant
::getKey("CRM_Contact_BAO_Contact", 'suffix_id', 'II'), $result['suffix_id']);
1675 $this->callAPISuccess('contact', 'delete', $contact);
1676 $this->assertEquals(array(
1677 CRM_Core_PseudoConstant
::getKey("CRM_Contact_BAO_Contact", 'preferred_communication_method', 'Phone'),
1678 CRM_Core_PseudoConstant
::getKey("CRM_Contact_BAO_Contact", 'preferred_communication_method', 'SMS'),
1679 ), $result['preferred_communication_method']);
1684 * Test birth date parameters.
1686 * These include value, array & birth_date_high, birth_date_low
1689 public function testContactGetBirthDate() {
1690 $contact1 = $this->callAPISuccess('contact', 'create', array_merge($this->_params
, array('birth_date' => 'first day of next month - 2 years')));
1691 $contact2 = $this->callAPISuccess('contact', 'create', array_merge($this->_params
, array('birth_date' => 'first day of next month - 5 years')));
1692 $contact3 = $this->callAPISuccess('contact', 'create', array_merge($this->_params
, array('birth_date' => 'first day of next month -20 years')));
1694 $result = $this->callAPISuccess('contact', 'get', array());
1695 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -2 years')), $result['values'][$contact1['id']]['birth_date']);
1696 $result = $this->callAPISuccess('contact', 'get', array('birth_date' => 'first day of next month -5 years'));
1697 $this->assertEquals(1, $result['count']);
1698 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -5 years')), $result['values'][$contact2['id']]['birth_date']);
1699 $result = $this->callAPISuccess('contact', 'get', array('birth_date_high' => date('Y-m-d', strtotime('-6 years'))));
1700 $this->assertEquals(1, $result['count']);
1701 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -20 years')), $result['values'][$contact3['id']]['birth_date']);
1702 $result = $this->callAPISuccess('contact', 'get', array(
1703 'birth_date_low' => date('Y-m-d', strtotime('-6 years')),
1704 'birth_date_high' => date('Y-m-d', strtotime('- 3 years')),
1706 $this->assertEquals(1, $result['count']);
1707 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -5 years')), $result['values'][$contact2['id']]['birth_date']);
1708 $result = $this->callAPISuccess('contact', 'get', array(
1709 'birth_date_low' => '-6 years',
1710 'birth_date_high' => '- 3 years',
1712 $this->assertEquals(1, $result['count']);
1713 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -5 years')), $result['values'][$contact2['id']]['birth_date']);
1717 * Test Address parameters
1719 * This include state_province, state_province_name, country
1721 public function testContactGetWithAddressFields() {
1722 $individuals = array(
1724 'first_name' => 'abc1',
1725 'contact_type' => 'Individual',
1726 'last_name' => 'xyz1',
1727 'api.address.create' => array(
1728 'country' => 'United States',
1729 'state_province_id' => 'Michigan',
1730 'location_type_id' => 1,
1734 'first_name' => 'abc2',
1735 'contact_type' => 'Individual',
1736 'last_name' => 'xyz2',
1737 'api.address.create' => array(
1738 'country' => 'United States',
1739 'state_province_id' => 'Alabama',
1740 'location_type_id' => 1,
1744 foreach ($individuals as $params) {
1745 $contact = $this->callAPISuccess('contact', 'create', $params);
1748 // Check whether Contact get API return successfully with below Address params.
1749 $fieldsToTest = array(
1750 'state_province_name' => 'Michigan',
1751 'state_province' => 'Michigan',
1752 'country' => 'United States',
1753 'state_province_name' => array('IN' => array('Michigan', 'Alabama')),
1754 'state_province' => array('IN' => array('Michigan', 'Alabama')),
1756 foreach ($fieldsToTest as $field => $value) {
1758 'id' => $contact['id'],
1761 $result = $this->callAPISuccess('Contact', 'get', $getParams);
1762 $this->assertEquals(1, $result['count']);
1767 * Test Deceased date parameters.
1769 * These include value, array & Deceased_date_high, Deceased date_low
1772 public function testContactGetDeceasedDate() {
1773 $contact1 = $this->callAPISuccess('contact', 'create', array_merge($this->_params
, array('deceased_date' => 'first day of next month - 2 years')));
1774 $contact2 = $this->callAPISuccess('contact', 'create', array_merge($this->_params
, array('deceased_date' => 'first day of next month - 5 years')));
1775 $contact3 = $this->callAPISuccess('contact', 'create', array_merge($this->_params
, array('deceased_date' => 'first day of next month -20 years')));
1777 $result = $this->callAPISuccess('contact', 'get', array());
1778 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -2 years')), $result['values'][$contact1['id']]['deceased_date']);
1779 $result = $this->callAPISuccess('contact', 'get', array('deceased_date' => 'first day of next month -5 years'));
1780 $this->assertEquals(1, $result['count']);
1781 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -5 years')), $result['values'][$contact2['id']]['deceased_date']);
1782 $result = $this->callAPISuccess('contact', 'get', array('deceased_date_high' => date('Y-m-d', strtotime('-6 years'))));
1783 $this->assertEquals(1, $result['count']);
1784 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -20 years')), $result['values'][$contact3['id']]['deceased_date']);
1785 $result = $this->callAPISuccess('contact', 'get', array(
1786 'deceased_date_low' => '-6 years',
1787 'deceased_date_high' => date('Y-m-d', strtotime('- 3 years')),
1789 $this->assertEquals(1, $result['count']);
1790 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -5 years')), $result['values'][$contact2['id']]['deceased_date']);
1794 * Test for Contact.get id=@user:username.
1796 public function testContactGetByUsername() {
1797 // Setup - create contact with a uf-match.
1798 $cid = $this->individualCreate(array(
1799 'contact_type' => 'Individual',
1800 'first_name' => 'testGetByUsername',
1801 'last_name' => 'testGetByUsername',
1804 $ufMatchParams = array(
1805 'domain_id' => CRM_Core_Config
::domainID(),
1807 'uf_name' => 'the-email-matching-key-is-not-really-the-username',
1808 'contact_id' => $cid,
1810 $ufMatch = CRM_Core_BAO_UFMatch
::create($ufMatchParams);
1811 $this->assertTrue(is_numeric($ufMatch->id
));
1813 // setup - mock the calls to CRM_Utils_System_*::getUfId
1814 $userSystem = $this->getMock('CRM_Utils_System_UnitTests', array('getUfId'));
1815 $userSystem->expects($this->once())
1817 ->with($this->equalTo('exampleUser'))
1818 ->will($this->returnValue(99));
1819 CRM_Core_Config
::singleton()->userSystem
= $userSystem;
1822 $result = $this->callAPISuccess('Contact', 'get', array(
1823 'id' => '@user:exampleUser',
1825 $this->assertEquals('testGetByUsername', $result['values'][$cid]['first_name']);
1829 * Test to check return works OK.
1831 public function testContactGetReturnValues() {
1832 $extraParams = array(
1833 'nick_name' => 'Bob',
1835 'email' => 'e@mail.com',
1837 $contactID = $this->individualCreate($extraParams);
1838 //actually it turns out the above doesn't create a phone
1839 $this->callAPISuccess('phone', 'create', array('contact_id' => $contactID, 'phone' => '456'));
1840 $result = $this->callAPISuccess('contact', 'getsingle', array('id' => $contactID));
1841 foreach ($extraParams as $key => $value) {
1842 $this->assertEquals($result[$key], $value);
1844 //now we check they are still returned with 'return' key
1845 $result = $this->callAPISuccess('contact', 'getsingle', array(
1847 'return' => array_keys($extraParams),
1849 foreach ($extraParams as $key => $value) {
1850 $this->assertEquals($result[$key], $value);
1855 * Test creating multiple phones using chaining.
1857 * @throws \Exception
1859 public function testCRM13252MultipleChainedPhones() {
1860 $contactID = $this->householdCreate();
1861 $this->callAPISuccessGetCount('phone', array('contact_id' => $contactID), 0);
1863 'contact_id' => $contactID,
1864 'household_name' => 'Household 1',
1865 'contact_type' => 'Household',
1866 'api.phone.create' => array(
1868 'phone' => '111-111-1111',
1869 'location_type_id' => 1,
1870 'phone_type_id' => 1,
1873 'phone' => '222-222-2222',
1874 'location_type_id' => 1,
1875 'phone_type_id' => 2,
1879 $this->callAPISuccess('contact', 'create', $params);
1880 $this->callAPISuccessGetCount('phone', array('contact_id' => $contactID), 2);
1885 * Test for Contact.get id=@user:username (with an invalid username).
1887 public function testContactGetByUnknownUsername() {
1888 // setup - mock the calls to CRM_Utils_System_*::getUfId
1889 $userSystem = $this->getMock('CRM_Utils_System_UnitTests', array('getUfId'));
1890 $userSystem->expects($this->once())
1892 ->with($this->equalTo('exampleUser'))
1893 ->will($this->returnValue(NULL));
1894 CRM_Core_Config
::singleton()->userSystem
= $userSystem;
1897 $result = $this->callAPIFailure('Contact', 'get', array(
1898 'id' => '@user:exampleUser',
1900 $this->assertRegExp('/cannot be resolved to a contact ID/', $result['error_message']);
1904 * Verify attempt to create individual with chained arrays and sequential.
1906 public function testGetIndividualWithChainedArraysAndSequential() {
1907 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__
, __FILE__
);
1908 $params['custom_' . $ids['custom_field_id']] = "custom string";
1910 $moreIDs = $this->CustomGroupMultipleCreateWithFields();
1913 'first_name' => 'abc3',
1914 'last_name' => 'xyz3',
1915 'contact_type' => 'Individual',
1916 'email' => 'man3@yahoo.com',
1917 'api.website.create' => array(
1919 'url' => "http://civicrm.org",
1922 'url' => "https://civicrm.org",
1927 $result = $this->callAPISuccess('Contact', 'create', $params);
1929 // delete the contact and custom groups
1930 $this->callAPISuccess('contact', 'delete', array('id' => $result['id']));
1931 $this->customGroupDelete($ids['custom_group_id']);
1932 $this->customGroupDelete($moreIDs['custom_group_id']);
1934 $this->assertEquals($result['id'], $result['values'][0]['id']);
1935 $this->assertArrayKeyExists('api.website.create', $result['values'][0]);
1939 * Verify attempt to create individual with chained arrays.
1941 public function testGetIndividualWithChainedArrays() {
1942 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__
, __FILE__
);
1943 $params['custom_' . $ids['custom_field_id']] = "custom string";
1945 $moreIDs = $this->CustomGroupMultipleCreateWithFields();
1946 $description = "This demonstrates the usage of chained api functions.\nIn this case no notes or custom fields have been created.";
1947 $subfile = "APIChainedArray";
1949 'first_name' => 'abc3',
1950 'last_name' => 'xyz3',
1951 'contact_type' => 'Individual',
1952 'email' => 'man3@yahoo.com',
1953 'api.contribution.create' => array(
1954 'receive_date' => '2010-01-01',
1955 'total_amount' => 100.00,
1956 'financial_type_id' => 1,
1957 'payment_instrument_id' => 1,
1958 'non_deductible_amount' => 10.00,
1959 'fee_amount' => 50.00,
1960 'net_amount' => 90.00,
1962 'invoice_id' => 67890,
1964 'contribution_status_id' => 1,
1966 'api.contribution.create.1' => array(
1967 'receive_date' => '2011-01-01',
1968 'total_amount' => 120.00,
1969 'financial_type_id' => $this->_financialTypeId
= 1,
1970 'payment_instrument_id' => 1,
1971 'non_deductible_amount' => 10.00,
1972 'fee_amount' => 50.00,
1973 'net_amount' => 90.00,
1975 'invoice_id' => 67830,
1977 'contribution_status_id' => 1,
1979 'api.website.create' => array(
1981 'url' => "http://civicrm.org",
1986 $result = $this->callAPISuccess('Contact', 'create', $params);
1988 'id' => $result['id'],
1989 'api.website.get' => array(),
1990 'api.Contribution.get' => array(
1991 'total_amount' => '120.00',
1993 'api.CustomValue.get' => 1,
1994 'api.Note.get' => 1,
1996 $result = $this->callAPIAndDocument('Contact', 'Get', $params, __FUNCTION__
, __FILE__
, $description, $subfile);
1997 // delete the contact
1998 $this->callAPISuccess('contact', 'delete', $result);
1999 $this->customGroupDelete($ids['custom_group_id']);
2000 $this->customGroupDelete($moreIDs['custom_group_id']);
2001 $this->assertEquals(0, $result['values'][$result['id']]['api.website.get']['is_error']);
2002 $this->assertEquals("http://civicrm.org", $result['values'][$result['id']]['api.website.get']['values'][0]['url']);
2006 * Verify attempt to create individual with chained arrays and sequential.
2008 * See https://issues.civicrm.org/jira/browse/CRM-15815
2010 public function testCreateIndividualWithChainedArrayAndSequential() {
2013 'first_name' => 'abc5',
2014 'last_name' => 'xyz5',
2015 'contact_type' => 'Individual',
2016 'email' => 'woman5@yahoo.com',
2017 'api.phone.create' => array(
2018 array('phone' => '03-231 07 95'),
2019 array('phone' => '03-232 51 62'),
2021 'api.website.create' => array(
2022 'url' => 'http://civicrm.org',
2025 $result = $this->callAPISuccess('Contact', 'create', $params);
2027 // I could try to parse the result to see whether the two phone numbers
2028 // and the website are there, but I am not sure about the correct format.
2029 // So I will just fetch it again before checking.
2030 // See also http://forum.civicrm.org/index.php/topic,35393.0.html
2033 'id' => $result['id'],
2034 'api.website.get' => array(),
2035 'api.phone.get' => array(),
2037 $result = $this->callAPISuccess('Contact', 'get', $params);
2039 // delete the contact
2040 $this->callAPISuccess('contact', 'delete', $result);
2042 $this->assertEquals(2, $result['values'][0]['api.phone.get']['count']);
2043 $this->assertEquals(1, $result['values'][0]['api.website.get']['count']);
2047 * Test retrieving an individual with chained array syntax.
2049 public function testGetIndividualWithChainedArraysFormats() {
2050 $description = "This demonstrates the usage of chained api functions.\nIn this case no notes or custom fields have been created.";
2051 $subfile = "APIChainedArrayFormats";
2052 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__
, __FILE__
);
2053 $params['custom_' . $ids['custom_field_id']] = "custom string";
2055 $moreIDs = $this->CustomGroupMultipleCreateWithFields();
2057 'first_name' => 'abc3',
2058 'last_name' => 'xyz3',
2059 'contact_type' => 'Individual',
2060 'email' => 'man3@yahoo.com',
2061 'api.contribution.create' => array(
2062 'receive_date' => '2010-01-01',
2063 'total_amount' => 100.00,
2064 'financial_type_id' => $this->_financialTypeId
,
2065 'payment_instrument_id' => 1,
2066 'non_deductible_amount' => 10.00,
2067 'fee_amount' => 50.00,
2068 'net_amount' => 90.00,
2070 'contribution_status_id' => 1,
2072 'api.contribution.create.1' => array(
2073 'receive_date' => '2011-01-01',
2074 'total_amount' => 120.00,
2075 'financial_type_id' => $this->_financialTypeId
,
2076 'payment_instrument_id' => 1,
2077 'non_deductible_amount' => 10.00,
2078 'fee_amount' => 50.00,
2079 'net_amount' => 90.00,
2081 'contribution_status_id' => 1,
2083 'api.website.create' => array(
2085 'url' => "http://civicrm.org",
2090 $result = $this->callAPISuccess('Contact', 'create', $params);
2092 'id' => $result['id'],
2093 'api.website.getValue' => array('return' => 'url'),
2094 'api.Contribution.getCount' => array(),
2095 'api.CustomValue.get' => 1,
2096 'api.Note.get' => 1,
2097 'api.Membership.getCount' => array(),
2099 $result = $this->callAPIAndDocument('Contact', 'Get', $params, __FUNCTION__
, __FILE__
, $description, $subfile);
2100 $this->assertEquals(2, $result['values'][$result['id']]['api.Contribution.getCount']);
2101 $this->assertEquals(0, $result['values'][$result['id']]['api.Note.get']['is_error']);
2102 $this->assertEquals("http://civicrm.org", $result['values'][$result['id']]['api.website.getValue']);
2104 $this->callAPISuccess('contact', 'delete', $result);
2105 $this->customGroupDelete($ids['custom_group_id']);
2106 $this->customGroupDelete($moreIDs['custom_group_id']);
2110 * Test complex chaining.
2112 public function testGetIndividualWithChainedArraysAndMultipleCustom() {
2113 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__
, __FILE__
);
2114 $params['custom_' . $ids['custom_field_id']] = "custom string";
2115 $moreIDs = $this->CustomGroupMultipleCreateWithFields();
2116 $andMoreIDs = $this->CustomGroupMultipleCreateWithFields(array(
2117 'title' => "another group",
2118 'name' => 'another name',
2120 $description = "This demonstrates the usage of chained api functions with multiple custom fields.";
2121 $subfile = "APIChainedArrayMultipleCustom";
2123 'first_name' => 'abc3',
2124 'last_name' => 'xyz3',
2125 'contact_type' => 'Individual',
2126 'email' => 'man3@yahoo.com',
2127 'api.contribution.create' => array(
2128 'receive_date' => '2010-01-01',
2129 'total_amount' => 100.00,
2130 'financial_type_id' => 1,
2131 'payment_instrument_id' => 1,
2132 'non_deductible_amount' => 10.00,
2133 'fee_amount' => 50.00,
2134 'net_amount' => 90.00,
2136 'invoice_id' => 67890,
2138 'contribution_status_id' => 1,
2140 'api.contribution.create.1' => array(
2141 'receive_date' => '2011-01-01',
2142 'total_amount' => 120.00,
2143 'financial_type_id' => 1,
2144 'payment_instrument_id' => 1,
2145 'non_deductible_amount' => 10.00,
2146 'fee_amount' => 50.00,
2147 'net_amount' => 90.00,
2149 'invoice_id' => 67830,
2151 'contribution_status_id' => 1,
2153 'api.website.create' => array(
2155 'url' => "http://civicrm.org",
2158 'custom_' . $ids['custom_field_id'] => "value 1",
2159 'custom_' . $moreIDs['custom_field_id'][0] => "value 2",
2160 'custom_' . $moreIDs['custom_field_id'][1] => "warm beer",
2161 'custom_' . $andMoreIDs['custom_field_id'][1] => "vegemite",
2164 $result = $this->callAPISuccess('Contact', 'create', $params);
2165 $result = $this->callAPISuccess('Contact', 'create', array(
2166 'contact_type' => 'Individual',
2167 'id' => $result['id'],
2169 $moreIDs['custom_field_id'][0] => "value 3",
2171 $ids['custom_field_id'] => "value 4",
2175 'id' => $result['id'],
2176 'api.website.getValue' => array('return' => 'url'),
2177 'api.Contribution.getCount' => array(),
2178 'api.CustomValue.get' => 1,
2180 $result = $this->callAPIAndDocument('Contact', 'Get', $params, __FUNCTION__
, __FILE__
, $description, $subfile);
2182 $this->customGroupDelete($ids['custom_group_id']);
2183 $this->customGroupDelete($moreIDs['custom_group_id']);
2184 $this->customGroupDelete($andMoreIDs['custom_group_id']);
2185 $this->assertEquals(0, $result['values'][$result['id']]['api.CustomValue.get']['is_error']);
2186 $this->assertEquals('http://civicrm.org', $result['values'][$result['id']]['api.website.getValue']);
2190 * Test checks usage of $values to pick & choose inputs.
2192 public function testChainingValuesCreate() {
2193 $description = "This demonstrates the usage of chained api functions. Specifically it has one 'parent function' &
2194 2 child functions - one receives values from the parent (Contact) and the other child (Tag).";
2195 $subfile = "APIChainedArrayValuesFromSiblingFunction";
2197 'display_name' => 'batman',
2198 'contact_type' => 'Individual',
2199 'api.tag.create' => array(
2200 'name' => '$value.id',
2201 'description' => '$value.display_name',
2202 'format.only_id' => 1,
2204 'api.entity_tag.create' => array('tag_id' => '$value.api.tag.create'),
2206 $result = $this->callAPIAndDocument('Contact', 'Create', $params, __FUNCTION__
, __FILE__
, $description, $subfile);
2207 $this->assertEquals(0, $result['values'][$result['id']]['api.entity_tag.create']['is_error']);
2209 $tablesToTruncate = array(
2212 'civicrm_entity_tag',
2215 $this->quickCleanup($tablesToTruncate, TRUE);
2219 * Test TrueFalse format - I couldn't come up with an easy way to get an error on Get.
2221 public function testContactGetFormatIsSuccessTrue() {
2222 $this->createContactFromXML();
2223 $description = "This demonstrates use of the 'format.is_success' param.
2224 This param causes only the success or otherwise of the function to be returned as BOOLEAN";
2225 $subfile = "FormatIsSuccess_True";
2226 $params = array('id' => 17, 'format.is_success' => 1);
2227 $result = $this->callAPIAndDocument('Contact', 'Get', $params, __FUNCTION__
, __FILE__
, $description, $subfile);
2228 $this->assertEquals(1, $result);
2229 $this->callAPISuccess('Contact', 'Delete', $params);
2233 * Test TrueFalse format.
2235 public function testContactCreateFormatIsSuccessFalse() {
2237 $description = "This demonstrates use of the 'format.is_success' param.
2238 This param causes only the success or otherwise of the function to be returned as BOOLEAN";
2239 $subfile = "FormatIsSuccess_Fail";
2240 $params = array('id' => 500, 'format.is_success' => 1);
2241 $result = $this->callAPIAndDocument('Contact', 'Create', $params, __FUNCTION__
, __FILE__
, $description, $subfile);
2242 $this->assertEquals(0, $result);
2246 * Test Single Entity format.
2248 public function testContactGetSingleEntityArray() {
2249 $this->createContactFromXML();
2250 $description = "This demonstrates use of the 'format.single_entity_array' param.
2251 This param causes the only contact to be returned as an array without the other levels.
2252 It will be ignored if there is not exactly 1 result";
2253 $subfile = "GetSingleContact";
2254 $params = array('id' => 17);
2255 $result = $this->callAPIAndDocument('Contact', 'GetSingle', $params, __FUNCTION__
, __FILE__
, $description, $subfile);
2256 $this->assertEquals('Test Contact', $result['display_name']);
2257 $this->callAPISuccess('Contact', 'Delete', $params);
2261 * Test Single Entity format.
2263 public function testContactGetFormatCountOnly() {
2264 $this->createContactFromXML();
2265 $description = "This demonstrates use of the 'getCount' action.
2266 This param causes the count of the only function to be returned as an integer.";
2267 $params = array('id' => 17);
2268 $result = $this->callAPIAndDocument('Contact', 'GetCount', $params, __FUNCTION__
, __FILE__
, $description,
2270 $this->assertEquals('1', $result);
2271 $this->callAPISuccess('Contact', 'Delete', $params);
2275 * Test id only format.
2277 public function testContactGetFormatIDOnly() {
2278 $this->createContactFromXML();
2279 $description = "This demonstrates use of the 'format.id_only' param.
2280 This param causes the id of the only entity to be returned as an integer.
2281 It will be ignored if there is not exactly 1 result";
2282 $subfile = "FormatOnlyID";
2283 $params = array('id' => 17, 'format.only_id' => 1);
2284 $result = $this->callAPIAndDocument('Contact', 'Get', $params, __FUNCTION__
, __FILE__
, $description, $subfile);
2285 $this->assertEquals('17', $result);
2286 $this->callAPISuccess('Contact', 'Delete', $params);
2290 * Test id only format.
2292 public function testContactGetFormatSingleValue() {
2293 $this->createContactFromXML();
2294 $description = "This demonstrates use of the 'format.single_value' param.
2295 This param causes only a single value of the only entity to be returned as an string.
2296 It will be ignored if there is not exactly 1 result";
2297 $subFile = "FormatSingleValue";
2298 $params = array('id' => 17, 'return' => 'display_name');
2299 $result = $this->callAPIAndDocument('Contact', 'getvalue', $params, __FUNCTION__
, __FILE__
, $description, $subFile);
2300 $this->assertEquals('Test Contact', $result);
2301 $this->callAPISuccess('Contact', 'Delete', $params);
2305 * Test that permissions are respected when creating contacts.
2307 public function testContactCreationPermissions() {
2309 'contact_type' => 'Individual',
2310 'first_name' => 'Foo',
2311 'last_name' => 'Bear',
2312 'check_permissions' => TRUE,
2314 $config = CRM_Core_Config
::singleton();
2315 $config->userPermissionClass
->permissions
= array('access CiviCRM');
2316 $result = $this->callAPIFailure('contact', 'create', $params);
2317 $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');
2319 $config->userPermissionClass
->permissions
= array('access CiviCRM', 'add contacts', 'import contacts');
2320 $this->callAPISuccess('contact', 'create', $params);
2324 * Test that delete with skip undelete respects permissions.
2326 public function testContactDeletePermissions() {
2327 $contactID = $this->individualCreate();
2328 CRM_Core_Config
::singleton()->userPermissionClass
->permissions
= array('access CiviCRM');
2329 $this->callAPIFailure('Contact', 'delete', array(
2331 'check_permissions' => 1,
2332 'skip_undelete' => 1,
2334 $this->callAPISuccess('Contact', 'delete', array(
2336 'check_permissions' => 0,
2337 'skip_undelete' => 1,
2342 * Test update with check permissions set.
2344 public function testContactUpdatePermissions() {
2346 'contact_type' => 'Individual',
2347 'first_name' => 'Foo',
2348 'last_name' => 'Bear',
2349 'check_permissions' => TRUE,
2351 $result = $this->callAPISuccess('contact', 'create', $params);
2352 $config = CRM_Core_Config
::singleton();
2354 'id' => $result['id'],
2355 'contact_type' => 'Individual',
2356 'last_name' => 'Bar',
2357 'check_permissions' => TRUE,
2360 $config->userPermissionClass
->permissions
= array('access CiviCRM');
2361 $result = $this->callAPIFailure('contact', 'update', $params);
2362 $this->assertEquals('Permission denied to modify contact record', $result['error_message']);
2364 $config->userPermissionClass
->permissions
= array(
2367 'view all contacts',
2368 'edit all contacts',
2371 $this->callAPISuccess('contact', 'update', $params);
2375 * Set up helper to create a contact.
2377 public function createContactFromXML() {
2378 // Insert a row in civicrm_contact creating contact 17.
2379 $op = new PHPUnit_Extensions_Database_Operation_Insert();
2380 $op->execute($this->_dbconn
,
2381 $this->createXMLDataSet(
2382 dirname(__FILE__
) . '/dataset/contact_17.xml'
2388 * Test contact proximity api.
2390 public function testContactProximity() {
2391 // first create a contact with a SF location with a specific
2393 $contactID = $this->organizationCreate();
2395 // now create the address
2397 'street_address' => '123 Main Street',
2398 'city' => 'San Francisco',
2400 'country_id' => 1228,
2401 'state_province_id' => 1004,
2402 'geo_code_1' => '37.79',
2403 'geo_code_2' => '-122.40',
2404 'location_type_id' => 1,
2405 'contact_id' => $contactID,
2408 $result = $this->callAPISuccess('address', 'create', $params);
2409 $this->assertEquals(1, $result['count']);
2411 // now do a proximity search with a close enough geocode and hope to match
2412 // that specific contact only!
2413 $proxParams = array(
2415 'longitude' => -122.3,
2419 $result = $this->callAPISuccess('contact', 'proximity', $proxParams);
2420 $this->assertEquals(1, $result['count']);
2424 * Test that Ajax API permission is sufficient to access getquick api.
2426 * (note that getquick api is required for autocomplete & has ACL permissions applied)
2428 public function testGetquickPermissionCRM13744() {
2429 CRM_Core_Config
::singleton()->userPermissionClass
->permissions
= array('access CiviEvent');
2430 $this->callAPIFailure('contact', 'getquick', array('name' => 'b', 'check_permissions' => TRUE));
2431 CRM_Core_Config
::singleton()->userPermissionClass
->permissions
= array('access CiviCRM');
2432 $this->callAPISuccess('contact', 'getquick', array('name' => 'b', 'check_permissions' => TRUE));
2433 CRM_Core_Config
::singleton()->userPermissionClass
->permissions
= array('access AJAX API');
2434 $this->callAPISuccess('contact', 'getquick', array('name' => 'b', 'check_permissions' => TRUE));
2438 * Test that getquick returns contacts with an exact first name match first.
2440 * The search string 'b' & 'bob' both return ordered by sort_name if includeOrderByClause
2441 * is true (default) but if it is false then matches are returned in ID order.
2443 * @dataProvider getSearchSortOptions
2445 public function testGetQuickExactFirst($searchParameters, $settings, $firstContact, $secondContact = NULL) {
2446 $this->getQuickSearchSampleData();
2447 $this->callAPISuccess('Setting', 'create', $settings);
2448 $result = $this->callAPISuccess('contact', 'getquick', $searchParameters);
2449 $this->assertEquals($firstContact, $result['values'][0]['sort_name']);
2450 $this->assertEquals($secondContact, $result['values'][1]['sort_name']);
2451 $this->callAPISuccess('Setting', 'create', array('includeWildCardInName' => TRUE, 'includeOrderByClause' => TRUE));
2454 public function getSearchSortOptions() {
2455 $firstAlphabeticalContactBySortName = 'A Bobby, Bobby';
2456 $secondAlphabeticalContactBySortName = 'Aadvark, Bob';
2457 $secondAlphabeticalContactWithEmailBySortName = 'Bob, Bob';
2458 $firstAlphabeticalContactFirstNameBob = 'Aadvark, Bob';
2459 $secondAlphabeticalContactFirstNameBob = 'Bob, Bob';
2460 $firstByIDContactFirstNameBob = 'Bob, Bob';
2461 $secondByIDContactFirstNameBob = 'K Bobby, Bob';
2462 $firstContactByID = 'Bob, Bob';
2463 $secondContactByID = 'E Bobby, Bobby';
2464 $bobLikeEmail = 'A Bobby, Bobby';
2467 'empty_search_basic' => array(
2468 'search_parameters' => array('name' => '%'),
2469 'settings' => array('includeWildCardInName' => TRUE, 'includeOrderByClause' => TRUE),
2470 'first_contact' => $firstAlphabeticalContactBySortName,
2471 'second_contact' => $secondAlphabeticalContactBySortName,
2473 'empty_search_basic_no_wildcard' => array(
2474 'search_parameters' => array('name' => '%'),
2475 'settings' => array('includeWildCardInName' => FALSE, 'includeOrderByClause' => TRUE),
2476 'first_contact' => $firstAlphabeticalContactBySortName,
2477 'second_contact' => $secondAlphabeticalContactBySortName,
2479 'single_letter_search_basic' => array(
2480 'search_parameters' => array('name' => 'b'),
2481 'settings' => array('includeWildCardInName' => TRUE, 'includeOrderByClause' => TRUE),
2482 'first_contact' => $firstAlphabeticalContactBySortName,
2483 'second_contact' => $secondAlphabeticalContactBySortName,
2485 'bob_search_basic' => array(
2486 'search_parameters' => array('name' => 'bob'),
2487 'settings' => array('includeWildCardInName' => TRUE, 'includeOrderByClause' => TRUE),
2488 'first_contact' => $firstAlphabeticalContactBySortName,
2489 'second_contact' => $secondAlphabeticalContactBySortName,
2491 'bob_search_no_orderby' => array(
2492 'search_parameters' => array('name' => 'bob'),
2493 'settings' => array('includeWildCardInName' => TRUE, 'includeOrderByClause' => FALSE),
2494 'first_contact' => $firstContactByID,
2495 'second_contact' => $secondContactByID,
2497 'bob_search_no_wildcard' => array(
2498 'search_parameters' => array('name' => 'bob'),
2499 'settings' => array('includeWildCardInName' => FALSE, 'includeOrderByClause' => TRUE),
2500 'second_contact' => $bobLikeEmail,
2501 'first_contact' => $secondAlphabeticalContactFirstNameBob,
2503 // This should be the same as just no wildcard as if we had an exactMatch while searching by
2504 // sort name it would rise to the top CRM-19547
2505 'bob_search_no_wildcard_no_orderby' => array(
2506 'search_parameters' => array('name' => 'bob'),
2507 'settings' => array('includeWildCardInName' => FALSE, 'includeOrderByClause' => TRUE),
2508 'second_contact' => $bobLikeEmail,
2509 'first_contact' => $secondAlphabeticalContactFirstNameBob,
2511 'first_name_search_basic' => array(
2512 'search_parameters' => array('name' => 'bob', 'field_name' => 'first_name'),
2513 'settings' => array('includeWildCardInName' => TRUE, 'includeOrderByClause' => TRUE),
2514 'first_contact' => $firstAlphabeticalContactFirstNameBob,
2515 'second_contact' => $secondAlphabeticalContactFirstNameBob,
2517 'first_name_search_no_wildcard' => array(
2518 'search_parameters' => array('name' => 'bob', 'field_name' => 'first_name'),
2519 'settings' => array('includeWildCardInName' => FALSE, 'includeOrderByClause' => TRUE),
2520 'first_contact' => $firstAlphabeticalContactFirstNameBob,
2521 'second_contact' => $secondAlphabeticalContactFirstNameBob,
2523 'first_name_search_no_orderby' => array(
2524 'search_parameters' => array('name' => 'bob', 'field_name' => 'first_name'),
2525 'settings' => array('includeWildCardInName' => TRUE, 'includeOrderByClause' => FALSE),
2526 'first_contact' => $firstByIDContactFirstNameBob,
2527 'second_contact' => $secondByIDContactFirstNameBob,
2529 'email_search_basic' => array(
2530 'search_parameters' => array('name' => 'bob', 'field_name' => 'email', 'table_name' => 'eml'),
2531 'settings' => array('includeWildCardInName' => FALSE, 'includeOrderByClause' => TRUE),
2532 'first_contact' => $firstAlphabeticalContactBySortName,
2533 'second_contact' => $secondAlphabeticalContactWithEmailBySortName,
2539 * Test that getquick returns contacts with an exact first name match first.
2541 public function testGetQuickEmail() {
2542 $this->getQuickSearchSampleData();
2543 $loggedInContactID = $this->createLoggedInUser();
2544 $result = $this->callAPISuccess('contact', 'getquick', array(
2547 $expectedData = array(
2548 'A Bobby, Bobby :: bob@bobby.com',
2549 'Bob, Bob :: bob@bob.com',
2551 'H Bobby, Bobby :: bob@h.com',
2553 $this->callAPISuccessGetValue('Contact', array('id' => $loggedInContactID, 'return' => 'last_name')) . ', Logged In :: anthony_anderson@civicrm.org',
2555 $this->assertEquals(6, $result['count']);
2556 foreach ($expectedData as $index => $value) {
2557 $this->assertEquals($value, $result['values'][$index]['data']);
2559 $result = $this->callAPISuccess('contact', 'getquick', array(
2562 $expectedData = array(
2563 'H Bobby, Bobby :: bob@h.com',
2565 foreach ($expectedData as $index => $value) {
2566 $this->assertEquals($value, $result['values'][$index]['data']);
2568 $this->callAPISuccess('Setting', 'create', array('includeWildCardInName' => FALSE));
2569 $result = $this->callAPISuccess('contact', 'getquick', array(
2572 $this->callAPISuccess('Setting', 'create', array('includeWildCardInName' => TRUE));
2573 $this->assertEquals(0, $result['count']);
2577 * Test that getquick returns contacts with an exact first name match first.
2579 public function testGetQuickEmailACL() {
2580 $this->getQuickSearchSampleData();
2581 $loggedInContactID = $this->createLoggedInUser();
2582 CRM_Core_Config
::singleton()->userPermissionClass
->permissions
= array();
2583 $result = $this->callAPISuccess('contact', 'getquick', array(
2586 $this->assertEquals(0, $result['count']);
2588 $this->hookClass
->setHook('civicrm_aclWhereClause', array($this, 'aclWhereNoBobH'));
2589 CRM_Contact_BAO_Contact_Permission
::cache($loggedInContactID, CRM_Core_Permission
::VIEW
, TRUE);
2590 $result = $this->callAPISuccess('contact', 'getquick', array(
2594 // Without the acl it would be 6 like the previous email getquick test.
2595 $this->assertEquals(5, $result['count']);
2596 $expectedData = array(
2597 'A Bobby, Bobby :: bob@bobby.com',
2598 'Bob, Bob :: bob@bob.com',
2601 $this->callAPISuccessGetValue('Contact', array('id' => $loggedInContactID, 'return' => 'last_name')) . ', Logged In :: anthony_anderson@civicrm.org',
2603 foreach ($expectedData as $index => $value) {
2604 $this->assertEquals($value, $result['values'][$index]['data']);
2609 * Test that getquick returns contacts with an exact first name match first.
2611 public function testGetQuickExternalID() {
2612 $this->getQuickSearchSampleData();
2613 $result = $this->callAPISuccess('contact', 'getquick', array(
2615 'field_name' => 'external_identifier',
2616 'table_name' => 'cc',
2618 $this->assertEquals(0, $result['count']);
2619 $result = $this->callAPISuccess('contact', 'getquick', array(
2621 'field_name' => 'external_identifier',
2622 'table_name' => 'cc',
2624 $this->assertEquals(1, $result['count']);
2625 $this->assertEquals('Bob, Bob', $result['values'][0]['sort_name']);
2629 * Test that getquick returns contacts with an exact first name match first.
2631 public function testGetQuickID() {
2632 $max = CRM_Core_DAO
::singleValueQuery("SELECT max(id) FROM civicrm_contact");
2633 $this->getQuickSearchSampleData();
2634 $result = $this->callAPISuccess('contact', 'getquick', array(
2636 'field_name' => 'id',
2637 'table_name' => 'cc',
2639 $this->assertEquals(1, $result['count']);
2640 $this->assertEquals('E Bobby, Bobby', $result['values'][0]['sort_name']);
2641 $result = $this->callAPISuccess('contact', 'getquick', array(
2643 'field_name' => 'contact_id',
2644 'table_name' => 'cc',
2646 $this->assertEquals(1, $result['count']);
2647 $this->assertEquals('E Bobby, Bobby', $result['values'][0]['sort_name']);
2651 * Test that getquick returns contacts with an exact first name match first.
2653 * Depending on the setting the sort name sort might click in next or not - test!
2655 public function testGetQuickFirstName() {
2656 $this->getQuickSearchSampleData();
2657 $this->callAPISuccess('Setting', 'create', array('includeOrderByClause' => TRUE));
2658 $result = $this->callAPISuccess('contact', 'getquick', array(
2660 'field_name' => 'first_name',
2661 'table_name' => 'cc',
2670 foreach ($expected as $index => $value) {
2671 $this->assertEquals($value, $result['values'][$index]['sort_name']);
2673 $this->callAPISuccess('Setting', 'create', array('includeOrderByClause' => FALSE));
2674 $result = $this->callAPISuccess('contact', 'getquick', array('name' => 'bob'));
2675 $this->assertEquals('Bob, Bob', $result['values'][0]['sort_name']);
2676 $this->assertEquals('E Bobby, Bobby', $result['values'][1]['sort_name']);
2680 * Test that getquick applies ACLs.
2682 public function testGetQuickFirstNameACLs() {
2683 $this->getQuickSearchSampleData();
2684 $userID = $this->createLoggedInUser();
2685 $this->callAPISuccess('Setting', 'create', array('includeOrderByClause' => TRUE, 'search_autocomplete_count' => 15));
2686 CRM_Core_Config
::singleton()->userPermissionClass
->permissions
= array();
2687 $result = $this->callAPISuccess('contact', 'getquick', array(
2689 'field_name' => 'first_name',
2690 'table_name' => 'cc',
2692 $this->assertEquals(0, $result['count']);
2694 $this->hookClass
->setHook('civicrm_aclWhereClause', array($this, 'aclWhereNoBobH'));
2695 CRM_Contact_BAO_Contact_Permission
::cache($userID, CRM_Core_Permission
::VIEW
, TRUE);
2696 $result = $this->callAPISuccess('contact', 'getquick', array(
2698 'field_name' => 'first_name',
2699 'table_name' => 'cc',
2701 $this->assertEquals('K Bobby, Bob', $result['values'][2]['sort_name']);
2702 // Without the ACL 9 would be bob@h.com.
2703 $this->assertEquals('I Bobby, Bobby', $result['values'][10]['sort_name']);
2707 * Full results returned.
2708 * @implements CRM_Utils_Hook::aclWhereClause
2710 * @param string $type
2711 * @param array $tables
2712 * @param array $whereTables
2713 * @param int $contactID
2714 * @param string $where
2716 public function aclWhereNoBobH($type, &$tables, &$whereTables, &$contactID, &$where) {
2717 $where = " (email <> 'bob@h.com' OR email IS NULL) ";
2718 $whereTables['civicrm_email'] = "LEFT JOIN civicrm_email e ON contact_a.id = e.contact_id";
2722 * Test that getquick returns contacts with an exact last name match first.
2724 public function testGetQuickLastName() {
2725 $this->getQuickSearchSampleData();
2726 $this->callAPISuccess('Setting', 'create', array('includeOrderByClause' => TRUE));
2727 $result = $this->callAPISuccess('contact', 'getquick', array(
2729 'field_name' => 'last_name',
2730 'table_name' => 'cc',
2738 foreach ($expected as $index => $value) {
2739 $this->assertEquals($value, $result['values'][$index]['sort_name']);
2741 $this->callAPISuccess('Setting', 'create', array('includeOrderByClause' => FALSE));
2742 $result = $this->callAPISuccess('contact', 'getquick', array('name' => 'bob'));
2743 $this->assertEquals('Bob, Bob :: bob@bob.com', $result['values'][0]['data']);
2747 * Test that getquick returns contacts by city.
2749 public function testGetQuickCity() {
2750 $this->getQuickSearchSampleData();
2751 $result = $this->callAPISuccess('contact', 'getquick', array(
2753 'field_name' => 'city',
2754 'table_name' => 'sts',
2756 $this->assertEquals('B Bobby, Bobby :: Toronto', $result['values'][0]['data']);
2757 $result = $this->callAPISuccess('contact', 'getquick', array(
2759 'field_name' => 'city',
2760 'table_name' => 'sts',
2762 $this->assertEquals('B Bobby, Bobby :: Toronto', $result['values'][0]['data']);
2763 $this->assertEquals('C Bobby, Bobby :: Whanganui', $result['values'][1]['data']);
2767 * Set up some sample data for testing quicksearch.
2769 public function getQuickSearchSampleData() {
2771 array('first_name' => 'Bob', 'last_name' => 'Bob', 'external_identifier' => 'abc', 'email' => 'bob@bob.com'),
2772 array('first_name' => 'Bobby', 'last_name' => 'E Bobby', 'external_identifier' => 'abcd'),
2774 'first_name' => 'Bobby',
2775 'last_name' => 'B Bobby',
2776 'external_identifier' => 'bcd',
2777 'api.address.create' => array(
2778 'street_address' => 'Sesame Street',
2779 'city' => 'Toronto',
2780 'location_type_id' => 1,
2784 'first_name' => 'Bobby',
2785 'last_name' => 'C Bobby',
2786 'external_identifier' => 'bcde',
2787 'api.address.create' => array(
2788 'street_address' => 'Te huarahi',
2789 'city' => 'Whanganui',
2790 'location_type_id' => 1,
2793 array('first_name' => 'Bobby', 'last_name' => 'D Bobby', 'external_identifier' => 'efg'),
2794 array('first_name' => 'Bobby', 'last_name' => 'A Bobby', 'external_identifier' => 'hij', 'email' => 'bob@bobby.com'),
2795 array('first_name' => 'Bobby', 'last_name' => 'F Bobby', 'external_identifier' => 'klm'),
2796 array('first_name' => 'Bobby', 'last_name' => 'G Bobby', 'external_identifier' => 'nop'),
2797 array('first_name' => 'Bobby', 'last_name' => 'H Bobby', 'external_identifier' => 'qrs', 'email' => 'bob@h.com'),
2798 array('first_name' => 'Bobby', 'last_name' => 'I Bobby'),
2799 array('first_name' => 'Bobby', 'last_name' => 'J Bobby'),
2800 array('first_name' => 'Bob', 'last_name' => 'K Bobby', 'external_identifier' => 'bcdef'),
2801 array('first_name' => 'Bob', 'last_name' => 'Aadvark'),
2803 foreach ($contacts as $type => $contact) {
2804 $contact['contact_type'] = 'Individual';
2805 $this->callAPISuccess('Contact', 'create', $contact);
2810 * Test get ref api - gets a list of references to an entity.
2812 public function testGetReferenceCounts() {
2813 $result = $this->callAPISuccess('Contact', 'create', array(
2814 'first_name' => 'Testily',
2815 'last_name' => 'McHaste',
2816 'contact_type' => 'Individual',
2817 'api.Address.replace' => array(
2818 'values' => array(),
2820 'api.Email.replace' => array(
2823 'email' => 'spam@dev.null',
2825 'location_type_id' => 1,
2829 'api.Phone.replace' => array(
2832 'phone' => '234-567-0001',
2834 'location_type_id' => 1,
2837 'phone' => '234-567-0002',
2839 'location_type_id' => 1,
2845 //$dao = new CRM_Contact_BAO_Contact();
2846 //$dao->id = $result['id'];
2847 //$this->assertTrue((bool) $dao->find(TRUE));
2849 //$refCounts = $dao->getReferenceCounts();
2850 //$this->assertTrue(is_array($refCounts));
2851 //$refCountsIdx = CRM_Utils_Array::index(array('name'), $refCounts);
2853 $refCounts = $this->callAPISuccess('Contact', 'getrefcount', array(
2854 'id' => $result['id'],
2856 $refCountsIdx = CRM_Utils_Array
::index(array('name'), $refCounts['values']);
2858 $this->assertEquals(1, $refCountsIdx['sql:civicrm_email:contact_id']['count']);
2859 $this->assertEquals('civicrm_email', $refCountsIdx['sql:civicrm_email:contact_id']['table']);
2860 $this->assertEquals(2, $refCountsIdx['sql:civicrm_phone:contact_id']['count']);
2861 $this->assertEquals('civicrm_phone', $refCountsIdx['sql:civicrm_phone:contact_id']['table']);
2862 $this->assertTrue(!isset($refCountsIdx['sql:civicrm_address:contact_id']));
2866 * Test the use of sql operators.
2868 public function testSQLOperatorsOnContactAPI() {
2869 $this->individualCreate();
2870 $this->organizationCreate();
2871 $this->householdCreate();
2872 $contacts = $this->callAPISuccess('contact', 'get', array('legal_name' => array('IS NOT NULL' => TRUE)));
2873 $this->assertEquals($contacts['count'], CRM_Core_DAO
::singleValueQuery('select count(*) FROM civicrm_contact WHERE legal_name IS NOT NULL'));
2874 $contacts = $this->callAPISuccess('contact', 'get', array('legal_name' => array('IS NULL' => TRUE)));
2875 $this->assertEquals($contacts['count'], CRM_Core_DAO
::singleValueQuery('select count(*) FROM civicrm_contact WHERE legal_name IS NULL'));
2879 * CRM-14743 - test api respects search operators.
2881 public function testGetModifiedDateByOperators() {
2882 $preExistingContactCount = CRM_Core_DAO
::singleValueQuery('select count(*) FROM civicrm_contact');
2883 $contact1 = $this->individualCreate();
2884 $sql = "UPDATE civicrm_contact SET created_date = '2012-01-01', modified_date = '2013-01-01' WHERE id = " . $contact1;
2885 CRM_Core_DAO
::executeQuery($sql);
2886 $contact2 = $this->individualCreate();
2887 $sql = "UPDATE civicrm_contact SET created_date = '2012-02-01', modified_date = '2013-02-01' WHERE id = " . $contact2;
2888 CRM_Core_DAO
::executeQuery($sql);
2889 $contact3 = $this->householdCreate();
2890 $sql = "UPDATE civicrm_contact SET created_date = '2012-03-01', modified_date = '2013-03-01' WHERE id = " . $contact3;
2891 CRM_Core_DAO
::executeQuery($sql);
2892 $contacts = $this->callAPISuccess('contact', 'get', array('modified_date' => array('<' => '2014-01-01')));
2893 $this->assertEquals($contacts['count'], 3);
2894 $contacts = $this->callAPISuccess('contact', 'get', array('modified_date' => array('>' => '2014-01-01')));
2895 $this->assertEquals($contacts['count'], $preExistingContactCount);
2899 * CRM-14743 - test api respects search operators.
2901 public function testGetCreatedDateByOperators() {
2902 $preExistingContactCount = CRM_Core_DAO
::singleValueQuery('select count(*) FROM civicrm_contact');
2903 $contact1 = $this->individualCreate();
2904 $sql = "UPDATE civicrm_contact SET created_date = '2012-01-01' WHERE id = " . $contact1;
2905 CRM_Core_DAO
::executeQuery($sql);
2906 $contact2 = $this->individualCreate();
2907 $sql = "UPDATE civicrm_contact SET created_date = '2012-02-01' WHERE id = " . $contact2;
2908 CRM_Core_DAO
::executeQuery($sql);
2909 $contact3 = $this->householdCreate();
2910 $sql = "UPDATE civicrm_contact SET created_date = '2012-03-01' WHERE id = " . $contact3;
2911 CRM_Core_DAO
::executeQuery($sql);
2912 $contacts = $this->callAPISuccess('contact', 'get', array('created_date' => array('<' => '2014-01-01')));
2913 $this->assertEquals($contacts['count'], 3);
2914 $contacts = $this->callAPISuccess('contact', 'get', array('created_date' => array('>' => '2014-01-01')));
2915 $this->assertEquals($contacts['count'], $preExistingContactCount);
2919 * CRM-14263 check that API is not affected by search profile related bug.
2921 public function testReturnCityProfile() {
2922 $contactID = $this->individualCreate();
2923 CRM_Core_Config
::singleton()->defaultSearchProfileID
= 1;
2924 $this->callAPISuccess('address', 'create', array(
2925 'contact_id' => $contactID,
2926 'city' => 'Cool City',
2927 'location_type_id' => 1,
2929 $result = $this->callAPISuccess('contact', 'get', array('city' => 'Cool City', 'return' => 'contact_type'));
2930 $this->assertEquals(1, $result['count']);
2934 * CRM-15443 - ensure getlist api does not return deleted contacts.
2936 public function testGetlistExcludeConditions() {
2937 $name = md5(time());
2938 $contact = $this->individualCreate(array('last_name' => $name));
2939 $this->individualCreate(array('last_name' => $name, 'is_deceased' => 1));
2940 $this->individualCreate(array('last_name' => $name, 'is_deleted' => 1));
2941 // We should get all but the deleted contact.
2942 $result = $this->callAPISuccess('contact', 'getlist', array('input' => $name));
2943 $this->assertEquals(2, $result['count']);
2944 // Force-exclude the deceased contact.
2945 $result = $this->callAPISuccess('contact', 'getlist', array(
2947 'params' => array('is_deceased' => 0),
2949 $this->assertEquals(1, $result['count']);
2950 $this->assertEquals($contact, $result['values'][0]['id']);
2954 * Test contact getactions.
2956 public function testGetActions() {
2957 $description = "Getting the available actions for an entity.";
2958 $result = $this->callAPIAndDocument($this->_entity
, 'getactions', array(), __FUNCTION__
, __FILE__
, $description);
2978 $deprecated = array(
2982 foreach ($expected as $action) {
2983 $this->assertTrue(in_array($action, $result['values']), "Expected action $action");
2985 foreach ($deprecated as $action) {
2986 $this->assertArrayKeyExists($action, $result['deprecated']);
2991 * Test the duplicate check function.
2993 public function testDuplicateCheck() {
2995 'first_name' => 'Harry',
2996 'last_name' => 'Potter',
2997 'email' => 'harry@hogwarts.edu',
2998 'contact_type' => 'Individual',
3000 $this->callAPISuccess('Contact', 'create', $harry);
3001 $result = $this->callAPISuccess('Contact', 'duplicatecheck', array(
3005 $this->assertEquals(1, $result['count']);
3006 $result = $this->callAPISuccess('Contact', 'duplicatecheck', array(
3008 'first_name' => 'Harry',
3009 'last_name' => 'Potter',
3010 'email' => 'no5@privet.drive',
3011 'contact_type' => 'Individual',
3014 $this->assertEquals(0, $result['count']);
3015 $this->callAPIFailure('Contact', 'create', array_merge($harry, array('dupe_check' => 1)));
3018 public function testGetByContactType() {
3019 $individual = $this->callAPISuccess('Contact', 'create', array(
3020 'email' => 'individual@test.com',
3021 'contact_type' => 'Individual',
3023 $household = $this->callAPISuccess('Contact', 'create', array(
3024 'household_name' => 'household@test.com',
3025 'contact_type' => 'Household',
3027 $organization = $this->callAPISuccess('Contact', 'create', array(
3028 'organization_name' => 'organization@test.com',
3029 'contact_type' => 'Organization',
3031 // Test with id - getsingle will throw an exception if not found
3032 $this->callAPISuccess('Contact', 'getsingle', array(
3033 'id' => $individual['id'],
3034 'contact_type' => 'Individual',
3036 $this->callAPISuccess('Contact', 'getsingle', array(
3037 'id' => $individual['id'],
3038 'contact_type' => array('IN' => array('Individual')),
3041 $this->callAPISuccess('Contact', 'getsingle', array(
3042 'id' => $organization['id'],
3043 'contact_type' => array('IN' => array('Individual', 'Organization')),
3046 $result = $this->callAPISuccess('Contact', 'get', array(
3047 'contact_type' => array('IN' => array('Individual', 'Organization')),
3048 'options' => array('limit' => 0),
3051 $this->assertContains($organization['id'], array_keys($result['values']));
3052 $this->assertContains($individual['id'], array_keys($result['values']));
3053 $this->assertNotContains($household['id'], array_keys($result['values']));
3055 $result = $this->callAPISuccess('Contact', 'get', array(
3056 'contact_type' => 'Household',
3057 'options' => array('limit' => 0),
3060 $this->assertNotContains($organization['id'], array_keys($result['values']));
3061 $this->assertNotContains($individual['id'], array_keys($result['values']));
3062 $this->assertContains($household['id'], array_keys($result['values']));
3066 * Test merging 2 contacts.
3068 * Someone kindly bequethed us the legacy of mixed up use of main_id & other_id
3069 * in the params for contact.merge api.
3071 * This test protects that legacy.
3073 public function testMergeBizzareOldParams() {
3074 $this->createLoggedInUser();
3075 $otherContact = $this->callAPISuccess('contact', 'create', $this->_params
);
3076 $mainContact = $this->callAPISuccess('contact', 'create', $this->_params
);
3077 $this->callAPISuccess('contact', 'merge', array(
3078 'main_id' => $mainContact['id'],
3079 'other_id' => $otherContact['id'],
3081 $contacts = $this->callAPISuccess('contact', 'get', $this->_params
);
3082 $this->assertEquals($otherContact['id'], $contacts['id']);
3086 * Test merging 2 contacts.
3088 public function testMerge() {
3089 $this->createLoggedInUser();
3090 $otherContact = $this->callAPISuccess('contact', 'create', $this->_params
);
3091 $retainedContact = $this->callAPISuccess('contact', 'create', $this->_params
);
3092 $this->callAPISuccess('contact', 'merge', array(
3093 'to_keep_id' => $retainedContact['id'],
3094 'to_remove_id' => $otherContact['id'],
3095 'auto_flip' => FALSE,
3098 $contacts = $this->callAPISuccess('contact', 'get', $this->_params
);
3099 $this->assertEquals($retainedContact['id'], $contacts['id']);
3100 $activity = $this->callAPISuccess('Activity', 'getsingle', array(
3101 'target_contact_id' => $retainedContact['id'],
3102 'activity_type_id' => 'Contact Merged',
3104 $this->assertEquals(date('Y-m-d'), date('Y-m-d', strtotime($activity['activity_date_time'])));
3105 $activity2 = $this->callAPISuccess('Activity', 'getsingle', array(
3106 'target_contact_id' => $otherContact['id'],
3107 'activity_type_id' => 'Contact Deleted by Merge',
3109 $this->assertEquals($activity['id'], $activity2['parent_id']);
3110 $this->assertEquals('Normal', civicrm_api3('option_value', 'getvalue', array(
3111 'value' => $activity['priority_id'],
3112 'return' => 'label',
3113 'option_group_id' => 'priority',
3119 * Test merging 2 contacts with delete to trash off.
3121 * We are checking that there is no error due to attempting to add an activity for the
3126 public function testMergeNoTrash() {
3127 $this->createLoggedInUser();
3128 $this->callAPISuccess('Setting', 'create', array('contact_undelete' => FALSE));
3129 $otherContact = $this->callAPISuccess('contact', 'create', $this->_params
);
3130 $retainedContact = $this->callAPISuccess('contact', 'create', $this->_params
);
3131 $this->callAPISuccess('contact', 'merge', array(
3132 'to_keep_id' => $retainedContact['id'],
3133 'to_remove_id' => $otherContact['id'],
3134 'auto_flip' => FALSE,
3136 $this->callAPISuccess('Setting', 'create', array('contact_undelete' => TRUE));
3140 * Ensure format with return=group shows comma-separated group IDs.
3144 public function testContactGetReturnGroup() {
3145 // Set up a contact, asser that they were created.
3146 $contact_params = array(
3147 'contact_type' => 'Individual',
3148 'first_name' => 'Test',
3149 'last_name' => 'Groupmember',
3150 'email' => 'test@example.org',
3152 $create_contact = $this->callApiSuccess('Contact', 'create', $contact_params);
3153 $this->assertEquals(0, $create_contact['is_error']);
3154 $this->assertInternalType('int', $create_contact['id']);
3156 $created_contact_id = $create_contact['id'];
3158 // Set up multiple groups, add the contact to the groups.
3159 $test_groups = array('Test group A', 'Test group B');
3160 foreach ($test_groups as $title) {
3161 // Use this contact as group owner, since we know they exist.
3162 $group_params = array(
3164 'created_id' => $created_contact_id,
3166 $create_group = $this->callApiSuccess('Group', 'create', $group_params);
3167 $this->assertEquals(0, $create_group['is_error']);
3168 $this->assertInternalType('int', $create_group['id']);
3170 $created_group_ids[] = $create_group['id'];
3172 // Add contact to the new group.
3173 $group_contact_params = array(
3174 'contact_id' => $created_contact_id,
3175 'group_id' => $create_group['id'],
3177 $create_group_contact = $this->callApiSuccess('GroupContact', 'create', $group_contact_params);
3178 $this->assertEquals(0, $create_group_contact['is_error']);
3179 $this->assertInternalType('int', $create_group_contact['added']);
3182 // Use the Contact,get API to retrieve the contact
3183 $contact_get_params = array(
3184 'id' => $created_contact_id,
3185 'return' => 'group',
3187 $contact_get = $this->callApiSuccess('Contact', 'get', $contact_get_params);
3188 $this->assertInternalType('array', $contact_get['values'][$created_contact_id]);
3189 $this->assertInternalType('string', $contact_get['values'][$created_contact_id]['groups']);
3191 // Ensure they are shown as being in each created group.
3192 $contact_group_ids = explode(',', $contact_get['values'][$created_contact_id]['groups']);
3193 foreach ($created_group_ids as $created_group_id) {
3194 $this->assertContains($created_group_id, $contact_group_ids);
3199 * CRM-20144 Verify that passing title of group works as well as id
3200 * Tests the following formats
3201 * contact.get group='title1'
3202 * contact.get group=id1
3204 public function testContactGetWithGroupTitle() {
3205 // Set up a contact, asser that they were created.
3206 $contact_params = array(
3207 'contact_type' => 'Individual',
3208 'first_name' => 'Test2',
3209 'last_name' => 'Groupmember',
3210 'email' => 'test@example.org',
3212 $create_contact = $this->callApiSuccess('Contact', 'create', $contact_params);
3213 $created_contact_id = $create_contact['id'];
3214 // Set up multiple groups, add the contact to the groups.
3215 $test_groups = array('Test group C', 'Test group D');
3216 foreach ($test_groups as $title) {
3217 $group_params = array(
3219 'created_id' => $created_contact_id,
3221 $create_group = $this->callApiSuccess('Group', 'create', $group_params);
3222 $created_group_id = $create_group['id'];
3224 // Add contact to the new group.
3225 $group_contact_params = array(
3226 'contact_id' => $created_contact_id,
3227 'group_id' => $create_group['id'],
3229 $create_group_contact = $this->callApiSuccess('GroupContact', 'create', $group_contact_params);
3230 $contact_get = $this->callAPISuccess('contact', 'get', array('group' => $title, 'return' => 'group'));
3231 $this->assertEquals(1, $contact_get['count']);
3232 $this->assertEquals($created_contact_id, $contact_get['id']);
3233 $contact_groups = explode(',', $contact_get['values'][$created_contact_id]['groups']);
3234 $this->assertContains((string) $create_group['id'], $contact_groups);
3235 $contact_get2 = $this->callAPISuccess('contact', 'get', array('group' => $created_group_id, 'return' => 'group'));
3236 $this->assertEquals($created_contact_id, $contact_get2['id']);
3237 $contact_groups2 = explode(',', $contact_get2['values'][$created_contact_id]['groups']);
3238 $this->assertContains((string) $create_group['id'], $contact_groups2);
3239 $this->callAPISuccess('group', 'delete', array('id' => $created_group_id));
3241 $this->callAPISuccess('contact', 'delete', array('id' => $created_contact_id, 'skip_undelete' => TRUE));
3245 * CRM-20144 Verify that passing title of group works as well as id
3246 * Tests the following formats
3247 * contact.get group=array('title1', title1)
3248 * contact.get group=array('IN' => array('title1', 'title2)
3250 public function testContactGetWithGroupTitleMultipleGroups() {
3251 $description = "Get all from group and display contacts.";
3252 $subFile = "GroupFilterUsingContactAPI";
3253 // Set up a contact, asser that they were created.
3254 $contact_params = array(
3255 'contact_type' => 'Individual',
3256 'first_name' => 'Test2',
3257 'last_name' => 'Groupmember',
3258 'email' => 'test@example.org',
3260 $create_contact = $this->callApiSuccess('Contact', 'create', $contact_params);
3261 $created_contact_id = $create_contact['id'];
3262 $createdGroupsTitles = $createdGroupsIds = array();
3263 // Set up multiple groups, add the contact to the groups.
3264 $test_groups = array('Test group C', 'Test group D');
3265 foreach ($test_groups as $title) {
3266 $group_params = array(
3268 'created_id' => $created_contact_id,
3270 $create_group = $this->callApiSuccess('Group', 'create', $group_params);
3271 $created_group_id = $create_group['id'];
3272 $createdGroupsIds[] = $create_group['id'];
3273 $createdGroupTitles[] = $title;
3274 // Add contact to the new group.
3275 $group_contact_params = array(
3276 'contact_id' => $created_contact_id,
3277 'group_id' => $create_group['id'],
3279 $create_group_contact = $this->callApiSuccess('GroupContact', 'create', $group_contact_params);
3281 $contact_get = $this->callAPISuccess('contact', 'get', array('group' => $createdGroupTitles, 'return' => 'group'));
3282 $this->assertEquals(1, $contact_get['count']);
3283 $this->assertEquals($created_contact_id, $contact_get['id']);
3284 $contact_groups = explode(',', $contact_get['values'][$created_contact_id]['groups']);
3285 foreach ($createdGroupsIds as $id) {
3286 $this->assertContains((string) $id, $contact_groups);
3288 $contact_get2 = $this->callAPIAndDocument('contact', 'get', array('group' => array('IN' => $createdGroupTitles)), __FUNCTION__
, __FILE__
, $description, $subFile);
3289 $contact_get2 = $this->callAPISuccess('contact', 'get', array('group' => array('IN' => $createdGroupTitles), 'return' => 'group'));
3290 $this->assertEquals($created_contact_id, $contact_get2['id']);
3291 $contact_groups2 = explode(',', $contact_get2['values'][$created_contact_id]['groups']);
3292 foreach ($createdGroupsIds as $id) {
3293 $this->assertContains((string) $id, $contact_groups2);
3295 foreach ($createdGroupsIds as $id) {
3296 $this->callAPISuccess('group', 'delete', array('id' => $id));
3298 $this->callAPISuccess('contact', 'delete', array('id' => $created_contact_id, 'skip_undelete' => TRUE));
3302 * CRM-20144 Verify that passing title of group works as well as id
3303 * Tests the following formats
3304 * contact.get group=array('title1' => 1)
3305 * contact.get group=array('titke1' => 1, 'title2' => 1)
3306 * contact.get group=array('id1' => 1)
3307 * contact.get group=array('id1' => 1, id2 => 1)
3309 public function testContactGetWithGroupTitleMultipleGroupsLegacyFormat() {
3310 // Set up a contact, asser that they were created.
3311 $contact_params = array(
3312 'contact_type' => 'Individual',
3313 'first_name' => 'Test2',
3314 'last_name' => 'Groupmember',
3315 'email' => 'test@example.org',
3317 $create_contact = $this->callApiSuccess('Contact', 'create', $contact_params);
3318 $created_contact_id = $create_contact['id'];
3319 $createdGroupsTitles = $createdGroupsIds = array();
3320 // Set up multiple groups, add the contact to the groups.
3321 $test_groups = array('Test group C', 'Test group D');
3322 foreach ($test_groups as $title) {
3323 $group_params = array(
3325 'created_id' => $created_contact_id,
3327 $create_group = $this->callApiSuccess('Group', 'create', $group_params);
3328 $created_group_id = $create_group['id'];
3329 $createdGroupsIds[] = $create_group['id'];
3330 $createdGroupTitles[] = $title;
3331 // Add contact to the new group.
3332 $group_contact_params = array(
3333 'contact_id' => $created_contact_id,
3334 'group_id' => $create_group['id'],
3336 $create_group_contact = $this->callApiSuccess('GroupContact', 'create', $group_contact_params);
3338 $contact_get = $this->callAPISuccess('contact', 'get', array('group' => array($createdGroupTitles[0] => 1), 'return' => 'group'));
3339 $this->assertEquals(1, $contact_get['count']);
3340 $this->assertEquals($created_contact_id, $contact_get['id']);
3341 $contact_groups = explode(',', $contact_get['values'][$created_contact_id]['groups']);
3342 foreach ($createdGroupsIds as $id) {
3343 $this->assertContains((string) $id, $contact_groups);
3345 $contact_get2 = $this->callAPISuccess('contact', 'get', array('group' => array($createdGroupTitles[0] => 1, $createdGroupTitles[1] => 1), 'return' => 'group'));
3346 $this->assertEquals(1, $contact_get2['count']);
3347 $this->assertEquals($created_contact_id, $contact_get2['id']);
3348 $contact_groups2 = explode(',', $contact_get2['values'][$created_contact_id]['groups']);
3349 foreach ($createdGroupsIds as $id) {
3350 $this->assertContains((string) $id, $contact_groups2);
3352 $contact_get3 = $this->callAPISuccess('contact', 'get', array('group' => array($createdGroupsIds[0] => 1), 'return' => 'group'));
3353 $this->assertEquals($created_contact_id, $contact_get3['id']);
3354 $contact_groups3 = explode(',', $contact_get3['values'][$created_contact_id]['groups']);
3355 foreach ($createdGroupsIds as $id) {
3356 $this->assertContains((string) $id, $contact_groups3);
3358 $contact_get4 = $this->callAPISuccess('contact', 'get', array('group' => array($createdGroupsIds[0] => 1, $createdGroupsIds[1] => 1), 'return' => 'group'));
3359 $this->assertEquals($created_contact_id, $contact_get4['id']);
3360 $contact_groups4 = explode(',', $contact_get4['values'][$created_contact_id]['groups']);
3361 foreach ($createdGroupsIds as $id) {
3362 $this->assertContains((string) $id, $contact_groups4);
3364 foreach ($createdGroupsIds as $id) {
3365 $this->callAPISuccess('group', 'delete', array('id' => $id));
3367 $this->callAPISuccess('contact', 'delete', array('id' => $created_contact_id, 'skip_undelete' => TRUE));
3370 public function testLoggedInUserAPISupportToken() {
3371 $description = "Get contact id of the current logged in user";
3372 $subFile = "ContactIDOfLoggedInUserContactAPI";
3373 $cid = $this->createLoggedInUser();
3374 $contact = $this->callAPIAndDocument('contact', 'get', array('id' => 'user_contact_id'), __FUNCTION__
, __FILE__
, $description, $subFile);
3375 $this->assertEquals($cid, $contact['id']);