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->callAPIAndDocument('Contact', 'create', $params, __FUNCTION__
, __FILE__
);
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->callAPIAndDocument('Contact', 'create', $params, __FUNCTION__
, __FILE__
);
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->callAPIAndDocument('Contact', 'create', $params, __FUNCTION__
, __FILE__
);
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->callAPIAndDocument('Contact', 'create', $params, __FUNCTION__
, __FILE__
);
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();
987 $description = "Get all from group and display contacts.";
988 $subFile = "GroupFilterUsingContactAPI";
990 'email' => 'man2@yahoo.com',
991 'contact_type' => 'Individual',
992 'location_type_id' => 1,
993 'api.group_contact.create' => array('group_id' => $groupId),
996 $this->callAPISuccess('contact', 'create', $params);
997 // testing as integer
999 'filter.group_id' => $groupId,
1000 'contact_type' => 'Individual',
1002 $result = $this->callAPIAndDocument('contact', 'get', $params, __FUNCTION__
, __FILE__
, $description, $subFile);
1003 $this->assertEquals(1, $result['count']);
1004 // group 26 doesn't exist, but we can still search contacts in it.
1006 'filter.group_id' => 26,
1007 'contact_type' => 'Individual',
1009 $this->callAPISuccess('contact', 'get', $params);
1010 // testing as string
1012 'filter.group_id' => "$groupId, 26",
1013 'contact_type' => 'Individual',
1015 $result = $this->callAPIAndDocument('contact', 'get', $params, __FUNCTION__
, __FILE__
, $description, $subFile);
1016 $this->assertEquals(1, $result['count']);
1018 'filter.group_id' => "26,27",
1019 'contact_type' => 'Individual',
1021 $this->callAPISuccess('contact', 'get', $params);
1023 // testing as string
1025 'filter.group_id' => array($groupId, 26),
1026 'contact_type' => 'Individual',
1028 $result = $this->callAPIAndDocument('contact', 'get', $params, __FUNCTION__
, __FILE__
, $description, $subFile);
1029 $this->assertEquals(1, $result['count']);
1031 //test in conjunction with other criteria
1033 'filter.group_id' => array($groupId, 26),
1034 'contact_type' => 'Organization',
1036 $this->callAPISuccess('contact', 'get', $params);
1038 'filter.group_id' => array(26, 27),
1039 'contact_type' => 'Individual',
1041 $result = $this->callAPISuccess('contact', 'get', $params);
1042 $this->assertEquals(0, $result['count']);
1046 * Verify that attempt to create individual contact with two chained websites succeeds.
1048 public function testCreateIndividualWithContributionDottedSyntax() {
1049 $description = "This demonstrates the syntax to create 2 chained entities.";
1050 $subFile = "ChainTwoWebsites";
1052 'first_name' => 'abc3',
1053 'last_name' => 'xyz3',
1054 'contact_type' => 'Individual',
1055 'email' => 'man3@yahoo.com',
1056 'api.contribution.create' => array(
1057 'receive_date' => '2010-01-01',
1058 'total_amount' => 100.00,
1059 'financial_type_id' => $this->_financialTypeId
,
1060 'payment_instrument_id' => 1,
1061 'non_deductible_amount' => 10.00,
1062 'fee_amount' => 50.00,
1063 'net_amount' => 90.00,
1065 'invoice_id' => 67990,
1067 'contribution_status_id' => 1,
1069 'api.website.create' => array(
1070 'url' => "http://civicrm.org",
1072 'api.website.create.2' => array(
1073 'url' => "http://chained.org",
1077 $result = $this->callAPIAndDocument('Contact', 'create', $params, __FUNCTION__
, __FILE__
, $description, $subFile);
1079 // checking child function result not covered in callAPIAndDocument
1080 $this->assertAPISuccess($result['values'][$result['id']]['api.website.create']);
1081 $this->assertEquals("http://chained.org", $result['values'][$result['id']]['api.website.create.2']['values'][0]['url']);
1082 $this->assertEquals("http://civicrm.org", $result['values'][$result['id']]['api.website.create']['values'][0]['url']);
1084 // delete the contact
1085 $this->callAPISuccess('contact', 'delete', $result);
1089 * Verify that attempt to create individual contact with chained contribution and website succeeds.
1091 public function testCreateIndividualWithContributionChainedArrays() {
1093 'first_name' => 'abc3',
1094 'last_name' => 'xyz3',
1095 'contact_type' => 'Individual',
1096 'email' => 'man3@yahoo.com',
1097 'api.contribution.create' => array(
1098 'receive_date' => '2010-01-01',
1099 'total_amount' => 100.00,
1100 'financial_type_id' => $this->_financialTypeId
,
1101 'payment_instrument_id' => 1,
1102 'non_deductible_amount' => 10.00,
1103 'fee_amount' => 50.00,
1104 'net_amount' => 90.00,
1106 'invoice_id' => 67890,
1108 'contribution_status_id' => 1,
1110 'api.website.create' => array(
1112 'url' => "http://civicrm.org",
1115 'url' => "http://chained.org",
1116 'website_type_id' => 2,
1121 $description = "Demonstrates creating two websites as an array.";
1122 $subfile = "ChainTwoWebsitesSyntax2";
1123 $result = $this->callAPIAndDocument('Contact', 'create', $params, __FUNCTION__
, __FILE__
, $description, $subfile);
1125 // the callAndDocument doesn't check the chained call
1126 $this->assertEquals(0, $result['values'][$result['id']]['api.website.create'][0]['is_error']);
1127 $this->assertEquals("http://chained.org", $result['values'][$result['id']]['api.website.create'][1]['values'][0]['url']);
1128 $this->assertEquals("http://civicrm.org", $result['values'][$result['id']]['api.website.create'][0]['values'][0]['url']);
1130 $this->callAPISuccess('contact', 'delete', $result);
1134 * Test for direction when chaining relationships.
1136 * https://issues.civicrm.org/jira/browse/CRM-16084
1138 public function testDirectionChainingRelationshipsCRM16084() {
1139 // Some contact, called Jules.
1140 $create_result_1 = $this->callAPISuccess('contact', 'create', array(
1141 'first_name' => 'Jules',
1142 'last_name' => 'Smos',
1143 'contact_type' => 'Individual',
1146 // Another contact: Jos, child of Jules.
1147 $create_params = array(
1148 'first_name' => 'Jos',
1149 'last_name' => 'Smos',
1150 'contact_type' => 'Individual',
1151 'api.relationship.create' => array(
1153 'contact_id_a' => '$value.id',
1154 'contact_id_b' => $create_result_1['id'],
1156 'relationship_type_id' => 1,
1160 $create_result_2 = $this->callAPISuccess('contact', 'create', $create_params);
1162 // Mia is the child of Jos.
1163 $create_params = array(
1164 'first_name' => 'Mia',
1165 'last_name' => 'Smos',
1166 'contact_type' => 'Individual',
1167 'api.relationship.create' => array(
1169 'contact_id_a' => '$value.id',
1170 'contact_id_b' => $create_result_2['id'],
1172 'relationship_type_id' => 1,
1176 $create_result_3 = $this->callAPISuccess('contact', 'create', $create_params);
1178 // Get Jos and his children.
1179 $get_params = array(
1181 'id' => $create_result_2['id'],
1182 'api.relationship.get' => array(
1183 'contact_id_b' => '$value.id',
1184 'relationship_type_id' => 1,
1187 $get_result = $this->callAPISuccess('contact', 'getsingle', $get_params);
1190 $this->callAPISuccess('contact', 'delete', array(
1191 'id' => $create_result_1['id'],
1193 $this->callAPISuccess('contact', 'delete', array(
1194 'id' => $create_result_2['id'],
1196 $this->callAPISuccess('contact', 'delete', array(
1197 'id' => $create_result_2['id'],
1201 $this->assertEquals(1, $get_result['api.relationship.get']['count']);
1202 $this->assertEquals($create_result_3['id'], $get_result['api.relationship.get']['values'][0]['contact_id_a']);
1206 * Verify that attempt to create individual contact with first, and last names and email succeeds.
1208 public function testCreateIndividualWithNameEmail() {
1210 'first_name' => 'abc3',
1211 'last_name' => 'xyz3',
1212 'contact_type' => 'Individual',
1213 'email' => 'man3@yahoo.com',
1216 $contact = $this->callAPISuccess('contact', 'create', $params);
1218 $this->callAPISuccess('contact', 'delete', $contact);
1222 * Verify that attempt to create individual contact with no data fails.
1224 public function testCreateIndividualWithOutNameEmail() {
1226 'contact_type' => 'Individual',
1228 $this->callAPIFailure('contact', 'create', $params);
1232 * Test create individual contact with first &last names, email and location type succeeds.
1234 public function testCreateIndividualWithNameEmailLocationType() {
1236 'first_name' => 'abc4',
1237 'last_name' => 'xyz4',
1238 'email' => 'man4@yahoo.com',
1239 'contact_type' => 'Individual',
1240 'location_type_id' => 1,
1242 $result = $this->callAPISuccess('contact', 'create', $params);
1244 $this->callAPISuccess('contact', 'delete', array('id' => $result['id']));
1248 * Verify that when changing employers the old employer relationship becomes inactive.
1250 public function testCreateIndividualWithEmployer() {
1251 $employer = $this->organizationCreate();
1252 $employer2 = $this->organizationCreate();
1255 'email' => 'man4@yahoo.com',
1256 'contact_type' => 'Individual',
1257 'employer_id' => $employer,
1260 $result = $this->callAPISuccess('contact', 'create', $params);
1261 $relationships = $this->callAPISuccess('relationship', 'get', array(
1262 'contact_id_a' => $result['id'],
1266 $this->assertEquals($employer, $relationships['values'][0]['contact_id_b']);
1268 // Add more random relationships to make the test more realistic
1269 foreach (array('Employee of', 'Volunteer for') as $relationshipType) {
1270 $relTypeId = CRM_Core_DAO
::getFieldValue('CRM_Contact_DAO_RelationshipType', $relationshipType, 'id', 'name_a_b');
1271 $this->callAPISuccess('relationship', 'create', array(
1272 'contact_id_a' => $result['id'],
1273 'contact_id_b' => $this->organizationCreate(),
1275 'relationship_type_id' => $relTypeId,
1279 // Add second employer
1280 $params['employer_id'] = $employer2;
1281 $params['id'] = $result['id'];
1282 $result = $this->callAPISuccess('contact', 'create', $params);
1284 $relationships = $this->callAPISuccess('relationship', 'get', array(
1285 'contact_id_a' => $result['id'],
1290 $this->assertEquals($employer, $relationships['values'][0]['contact_id_b']);
1294 * Verify that attempt to create household contact with details succeeds.
1296 public function testCreateHouseholdDetails() {
1298 'household_name' => 'abc8\'s House',
1299 'nick_name' => 'x House',
1300 'email' => 'man8@yahoo.com',
1301 'contact_type' => 'Household',
1304 $contact = $this->callAPISuccess('contact', 'create', $params);
1306 $this->callAPISuccess('contact', 'delete', $contact);
1310 * Verify that attempt to create household contact with inadequate details fails.
1312 public function testCreateHouseholdInadequateDetails() {
1314 'nick_name' => 'x House',
1315 'email' => 'man8@yahoo.com',
1316 'contact_type' => 'Household',
1318 $this->callAPIFailure('contact', 'create', $params);
1322 * Verify successful update of individual contact.
1324 public function testUpdateIndividualWithAll() {
1325 // Insert a row in civicrm_contact creating individual contact.
1326 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1327 $op->execute($this->_dbconn
,
1328 $this->createXMLDataSet(
1329 dirname(__FILE__
) . '/dataset/contact_ind.xml'
1335 'first_name' => 'abcd',
1336 'contact_type' => 'Individual',
1337 'nick_name' => 'This is nickname first',
1338 'do_not_email' => '1',
1339 'do_not_phone' => '1',
1340 'do_not_mail' => '1',
1341 'do_not_trade' => '1',
1342 'legal_identifier' => 'ABC23853ZZ2235',
1343 'external_identifier' => '1928837465',
1344 'image_URL' => 'http://some.url.com/image.jpg',
1345 'home_url' => 'http://www.example.org',
1349 $this->callAPISuccess('Contact', 'Update', $params);
1350 $getResult = $this->callAPISuccess('Contact', 'Get', $params);
1351 unset($params['contact_id']);
1352 //Todo - neither API v2 or V3 are testing for home_url - not sure if it is being set.
1353 //reducing this test partially back to api v2 level to get it through
1354 unset($params['home_url']);
1355 foreach ($params as $key => $value) {
1356 $this->assertEquals($value, $getResult['values'][23][$key]);
1358 // Check updated civicrm_contact against expected.
1359 $expected = $this->createXMLDataSet(
1360 dirname(__FILE__
) . '/dataset/contact_ind_upd.xml'
1362 $actual = new PHPUnit_Extensions_Database_DataSet_QueryDataSet(
1365 $actual->addTable('civicrm_contact');
1366 $expected->matches($actual);
1370 * Verify successful update of organization contact.
1372 public function testUpdateOrganizationWithAll() {
1373 // Insert a row in civicrm_contact creating organization contact
1374 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1375 $op->execute($this->_dbconn
,
1376 $this->createXMLDataSet(
1377 dirname(__FILE__
) . '/dataset/contact_org.xml'
1383 'organization_name' => 'WebAccess India Pvt Ltd',
1384 'legal_name' => 'WebAccess',
1385 'sic_code' => 'ABC12DEF',
1386 'contact_type' => 'Organization',
1389 $this->callAPISuccess('Contact', 'Update', $params);
1391 // Check updated civicrm_contact against expected.
1392 $expected = $this->createXMLDataSet(
1393 dirname(__FILE__
) . '/dataset/contact_org_upd.xml'
1395 $actual = new PHPUnit_Extensions_Database_DataSet_QueryDataSet(
1398 $actual->addTable('civicrm_contact');
1399 $expected->matches($actual);
1403 * Verify successful update of household contact.
1405 public function testUpdateHouseholdWithAll() {
1406 // Insert a row in civicrm_contact creating household contact
1407 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1408 $op->execute($this->_dbconn
,
1409 $this->createXMLDataSet(
1410 dirname(__FILE__
) . '/dataset/contact_hld.xml'
1416 'household_name' => 'ABC household',
1417 'nick_name' => 'ABC House',
1418 'contact_type' => 'Household',
1421 $result = $this->callAPISuccess('Contact', 'Update', $params);
1424 'contact_type' => 'Household',
1426 'sort_name' => 'ABC household',
1427 'display_name' => 'ABC household',
1428 'nick_name' => 'ABC House',
1430 $this->getAndCheck($expected, $result['id'], 'contact');
1434 * Test civicrm_update() without contact type.
1436 * Deliberately exclude contact_type as it should still cope using civicrm_api.
1440 public function testUpdateCreateWithID() {
1441 // Insert a row in civicrm_contact creating individual contact.
1442 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1443 $op->execute($this->_dbconn
,
1444 $this->createXMLDataSet(
1445 dirname(__FILE__
) . '/dataset/contact_ind.xml'
1451 'first_name' => 'abcd',
1452 'last_name' => 'wxyz',
1454 $this->callAPISuccess('Contact', 'Update', $params);
1458 * Test civicrm_contact_delete() with no contact ID.
1460 public function testContactDeleteNoID() {
1464 $this->callAPIFailure('contact', 'delete', $params);
1468 * Test civicrm_contact_delete() with error.
1470 public function testContactDeleteError() {
1471 $params = array('contact_id' => 999);
1472 $this->callAPIFailure('contact', 'delete', $params);
1476 * Test civicrm_contact_delete().
1478 public function testContactDelete() {
1479 $contactID = $this->individualCreate();
1483 $this->callAPIAndDocument('contact', 'delete', $params, __FUNCTION__
, __FILE__
);
1487 * Test civicrm_contact_get() return only first name.
1489 public function testContactGetRetFirst() {
1490 $contact = $this->callAPISuccess('contact', 'create', $this->_params
);
1492 'contact_id' => $contact['id'],
1493 'return_first_name' => TRUE,
1494 'sort' => 'first_name',
1496 $result = $this->callAPISuccess('contact', 'get', $params);
1497 $this->assertEquals(1, $result['count']);
1498 $this->assertEquals($contact['id'], $result['id']);
1499 $this->assertEquals('abc1', $result['values'][$contact['id']]['first_name']);
1503 * Test civicrm_contact_get() return only first name & last name.
1505 * Use comma separated string return with a space.
1507 public function testContactGetReturnFirstLast() {
1508 $contact = $this->callAPISuccess('contact', 'create', $this->_params
);
1510 'contact_id' => $contact['id'],
1511 'return' => 'first_name, last_name',
1513 $result = $this->callAPISuccess('contact', 'getsingle', $params);
1514 $this->assertEquals('abc1', $result['first_name']);
1515 $this->assertEquals('xyz1', $result['last_name']);
1516 //check that other defaults not returns
1517 $this->assertArrayNotHasKey('sort_name', $result);
1519 'contact_id' => $contact['id'],
1520 'return' => 'first_name,last_name',
1522 $result = $this->callAPISuccess('contact', 'getsingle', $params);
1523 $this->assertEquals('abc1', $result['first_name']);
1524 $this->assertEquals('xyz1', $result['last_name']);
1525 //check that other defaults not returns
1526 $this->assertArrayNotHasKey('sort_name', $result);
1530 * Test civicrm_contact_get() return only first name & last name.
1532 * Use comma separated string return without a space
1534 public function testContactGetReturnFirstLastNoComma() {
1535 $contact = $this->callAPISuccess('contact', 'create', $this->_params
);
1537 'contact_id' => $contact['id'],
1538 'return' => 'first_name,last_name',
1540 $result = $this->callAPISuccess('contact', 'getsingle', $params);
1541 $this->assertEquals('abc1', $result['first_name']);
1542 $this->assertEquals('xyz1', $result['last_name']);
1543 //check that other defaults not returns
1544 $this->assertArrayNotHasKey('sort_name', $result);
1548 * Test civicrm_contact_get() with default return properties.
1550 public function testContactGetRetDefault() {
1551 $contactID = $this->individualCreate();
1553 'contact_id' => $contactID,
1554 'sort' => 'first_name',
1556 $result = $this->callAPISuccess('contact', 'get', $params);
1557 $this->assertEquals($contactID, $result['values'][$contactID]['contact_id']);
1558 $this->assertEquals('Anthony', $result['values'][$contactID]['first_name']);
1562 * Test civicrm_contact_getquick() with empty name param.
1564 public function testContactGetQuick() {
1565 // Insert a row in civicrm_contact creating individual contact.
1566 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1567 $op->execute($this->_dbconn
,
1568 $this->createXMLDataSet(
1569 dirname(__FILE__
) . '/dataset/contact_17.xml'
1572 $op->execute($this->_dbconn
,
1573 $this->createXMLDataSet(
1574 dirname(__FILE__
) . '/dataset/email_contact_17.xml'
1581 $result = $this->callAPISuccess('contact', 'getquick', $params);
1582 $this->assertEquals(17, $result['values'][0]['id']);
1586 * Test civicrm_contact_get) with empty params.
1588 public function testContactGetEmptyParams() {
1589 $this->callAPISuccess('contact', 'get', array());
1593 * Test civicrm_contact_get(,true) with no matches.
1595 public function testContactGetOldParamsNoMatches() {
1596 // Insert a row in civicrm_contact creating contact 17.
1597 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1598 $op->execute($this->_dbconn
,
1599 $this->createXMLDataSet(
1600 dirname(__FILE__
) . '/dataset/contact_17.xml'
1605 'first_name' => 'Fred',
1607 $result = $this->callAPISuccess('contact', 'get', $params);
1608 $this->assertEquals(0, $result['count']);
1612 * Test civicrm_contact_get(,true) with one match.
1614 public function testContactGetOldParamsOneMatch() {
1615 // Insert a row in civicrm_contact creating contact 17
1616 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1617 $op->execute($this->_dbconn
,
1618 $this->createXMLDataSet(dirname(__FILE__
) . '/dataset/contact_17.xml'
1623 'first_name' => 'Test',
1625 $result = $this->callAPISuccess('contact', 'get', $params);
1626 $this->assertEquals(17, $result['values'][17]['contact_id']);
1627 $this->assertEquals(17, $result['id']);
1631 * Test civicrm_contact_search_count().
1633 public function testContactGetEmail() {
1635 'email' => 'man2@yahoo.com',
1636 'contact_type' => 'Individual',
1637 'location_type_id' => 1,
1640 $contact = $this->callAPISuccess('contact', 'create', $params);
1643 'email' => 'man2@yahoo.com',
1645 $result = $this->callAPIAndDocument('contact', 'get', $params, __FUNCTION__
, __FILE__
);
1646 $this->assertEquals('man2@yahoo.com', $result['values'][$result['id']]['email']);
1648 $this->callAPISuccess('contact', 'delete', $contact);
1652 * Test birth date parameters.
1654 * These include value, array & birth_date_high, birth_date_low
1657 public function testContactGetBirthDate() {
1658 $contact1 = $this->callAPISuccess('contact', 'create', array_merge($this->_params
, array('birth_date' => 'first day of next month - 2 years')));
1659 $contact2 = $this->callAPISuccess('contact', 'create', array_merge($this->_params
, array('birth_date' => 'first day of next month - 5 years')));
1660 $contact3 = $this->callAPISuccess('contact', 'create', array_merge($this->_params
, array('birth_date' => 'first day of next month -20 years')));
1662 $result = $this->callAPISuccess('contact', 'get', array());
1663 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -2 years')), $result['values'][$contact1['id']]['birth_date']);
1664 $result = $this->callAPISuccess('contact', 'get', array('birth_date' => 'first day of next month -5 years'));
1665 $this->assertEquals(1, $result['count']);
1666 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -5 years')), $result['values'][$contact2['id']]['birth_date']);
1667 $result = $this->callAPISuccess('contact', 'get', array('birth_date_high' => date('Y-m-d', strtotime('-6 years'))));
1668 $this->assertEquals(1, $result['count']);
1669 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -20 years')), $result['values'][$contact3['id']]['birth_date']);
1670 $result = $this->callAPISuccess('contact', 'get', array(
1671 'birth_date_low' => date('Y-m-d', strtotime('-6 years')),
1672 'birth_date_high' => date('Y-m-d', strtotime('- 3 years')),
1674 $this->assertEquals(1, $result['count']);
1675 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -5 years')), $result['values'][$contact2['id']]['birth_date']);
1676 $result = $this->callAPISuccess('contact', 'get', array(
1677 'birth_date_low' => '-6 years',
1678 'birth_date_high' => '- 3 years',
1680 $this->assertEquals(1, $result['count']);
1681 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -5 years')), $result['values'][$contact2['id']]['birth_date']);
1685 * Test Address parameters
1687 * This include state_province, state_province_name, country
1689 public function testContactGetWithAddressFields() {
1690 $individuals = array(
1692 'first_name' => 'abc1',
1693 'contact_type' => 'Individual',
1694 'last_name' => 'xyz1',
1695 'api.address.create' => array(
1696 'country' => 'United States',
1697 'state_province_id' => 'Michigan',
1698 'location_type_id' => 1,
1702 'first_name' => 'abc2',
1703 'contact_type' => 'Individual',
1704 'last_name' => 'xyz2',
1705 'api.address.create' => array(
1706 'country' => 'United States',
1707 'state_province_id' => 'Alabama',
1708 'location_type_id' => 1,
1712 foreach ($individuals as $params) {
1713 $contact = $this->callAPISuccess('contact', 'create', $params);
1716 // Check whether Contact get API return successfully with below Address params.
1717 $fieldsToTest = array(
1718 'state_province_name' => 'Michigan',
1719 'state_province' => 'Michigan',
1720 'country' => 'United States',
1721 'state_province_name' => array('IN' => array('Michigan', 'Alabama')),
1722 'state_province' => array('IN' => array('Michigan', 'Alabama')),
1724 foreach ($fieldsToTest as $field => $value) {
1726 'id' => $contact['id'],
1729 $result = $this->callAPISuccess('Contact', 'get', $getParams);
1730 $this->assertEquals(1, $result['count']);
1735 * Test Deceased date parameters.
1737 * These include value, array & Deceased_date_high, Deceased date_low
1740 public function testContactGetDeceasedDate() {
1741 $contact1 = $this->callAPISuccess('contact', 'create', array_merge($this->_params
, array('deceased_date' => 'first day of next month - 2 years')));
1742 $contact2 = $this->callAPISuccess('contact', 'create', array_merge($this->_params
, array('deceased_date' => 'first day of next month - 5 years')));
1743 $contact3 = $this->callAPISuccess('contact', 'create', array_merge($this->_params
, array('deceased_date' => 'first day of next month -20 years')));
1745 $result = $this->callAPISuccess('contact', 'get', array());
1746 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -2 years')), $result['values'][$contact1['id']]['deceased_date']);
1747 $result = $this->callAPISuccess('contact', 'get', array('deceased_date' => 'first day of next month -5 years'));
1748 $this->assertEquals(1, $result['count']);
1749 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -5 years')), $result['values'][$contact2['id']]['deceased_date']);
1750 $result = $this->callAPISuccess('contact', 'get', array('deceased_date_high' => date('Y-m-d', strtotime('-6 years'))));
1751 $this->assertEquals(1, $result['count']);
1752 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -20 years')), $result['values'][$contact3['id']]['deceased_date']);
1753 $result = $this->callAPISuccess('contact', 'get', array(
1754 'deceased_date_low' => '-6 years',
1755 'deceased_date_high' => date('Y-m-d', strtotime('- 3 years')),
1757 $this->assertEquals(1, $result['count']);
1758 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -5 years')), $result['values'][$contact2['id']]['deceased_date']);
1762 * Test for Contact.get id=@user:username.
1764 public function testContactGetByUsername() {
1765 // Setup - create contact with a uf-match.
1766 $cid = $this->individualCreate(array(
1767 'contact_type' => 'Individual',
1768 'first_name' => 'testGetByUsername',
1769 'last_name' => 'testGetByUsername',
1772 $ufMatchParams = array(
1773 'domain_id' => CRM_Core_Config
::domainID(),
1775 'uf_name' => 'the-email-matching-key-is-not-really-the-username',
1776 'contact_id' => $cid,
1778 $ufMatch = CRM_Core_BAO_UFMatch
::create($ufMatchParams);
1779 $this->assertTrue(is_numeric($ufMatch->id
));
1781 // setup - mock the calls to CRM_Utils_System_*::getUfId
1782 $userSystem = $this->getMock('CRM_Utils_System_UnitTests', array('getUfId'));
1783 $userSystem->expects($this->once())
1785 ->with($this->equalTo('exampleUser'))
1786 ->will($this->returnValue(99));
1787 CRM_Core_Config
::singleton()->userSystem
= $userSystem;
1790 $result = $this->callAPISuccess('Contact', 'get', array(
1791 'id' => '@user:exampleUser',
1793 $this->assertEquals('testGetByUsername', $result['values'][$cid]['first_name']);
1797 * Test to check return works OK.
1799 public function testContactGetReturnValues() {
1800 $extraParams = array(
1801 'nick_name' => 'Bob',
1803 'email' => 'e@mail.com',
1805 $contactID = $this->individualCreate($extraParams);
1806 //actually it turns out the above doesn't create a phone
1807 $this->callAPISuccess('phone', 'create', array('contact_id' => $contactID, 'phone' => '456'));
1808 $result = $this->callAPISuccess('contact', 'getsingle', array('id' => $contactID));
1809 foreach ($extraParams as $key => $value) {
1810 $this->assertEquals($result[$key], $value);
1812 //now we check they are still returned with 'return' key
1813 $result = $this->callAPISuccess('contact', 'getsingle', array(
1815 'return' => array_keys($extraParams),
1817 foreach ($extraParams as $key => $value) {
1818 $this->assertEquals($result[$key], $value);
1823 * Test creating multiple phones using chaining.
1825 * @throws \Exception
1827 public function testCRM13252MultipleChainedPhones() {
1828 $contactID = $this->householdCreate();
1829 $this->callAPISuccessGetCount('phone', array('contact_id' => $contactID), 0);
1831 'contact_id' => $contactID,
1832 'household_name' => 'Household 1',
1833 'contact_type' => 'Household',
1834 'api.phone.create' => array(
1836 'phone' => '111-111-1111',
1837 'location_type_id' => 1,
1838 'phone_type_id' => 1,
1841 'phone' => '222-222-2222',
1842 'location_type_id' => 1,
1843 'phone_type_id' => 2,
1847 $this->callAPISuccess('contact', 'create', $params);
1848 $this->callAPISuccessGetCount('phone', array('contact_id' => $contactID), 2);
1853 * Test for Contact.get id=@user:username (with an invalid username).
1855 public function testContactGetByUnknownUsername() {
1856 // setup - mock the calls to CRM_Utils_System_*::getUfId
1857 $userSystem = $this->getMock('CRM_Utils_System_UnitTests', array('getUfId'));
1858 $userSystem->expects($this->once())
1860 ->with($this->equalTo('exampleUser'))
1861 ->will($this->returnValue(NULL));
1862 CRM_Core_Config
::singleton()->userSystem
= $userSystem;
1865 $result = $this->callAPIFailure('Contact', 'get', array(
1866 'id' => '@user:exampleUser',
1868 $this->assertRegExp('/cannot be resolved to a contact ID/', $result['error_message']);
1872 * Verify attempt to create individual with chained arrays and sequential.
1874 public function testGetIndividualWithChainedArraysAndSequential() {
1875 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__
, __FILE__
);
1876 $params['custom_' . $ids['custom_field_id']] = "custom string";
1878 $moreIDs = $this->CustomGroupMultipleCreateWithFields();
1881 'first_name' => 'abc3',
1882 'last_name' => 'xyz3',
1883 'contact_type' => 'Individual',
1884 'email' => 'man3@yahoo.com',
1885 'api.website.create' => array(
1887 'url' => "http://civicrm.org",
1890 'url' => "https://civicrm.org",
1895 $result = $this->callAPISuccess('Contact', 'create', $params);
1897 // delete the contact and custom groups
1898 $this->callAPISuccess('contact', 'delete', array('id' => $result['id']));
1899 $this->customGroupDelete($ids['custom_group_id']);
1900 $this->customGroupDelete($moreIDs['custom_group_id']);
1902 $this->assertEquals($result['id'], $result['values'][0]['id']);
1903 $this->assertArrayKeyExists('api.website.create', $result['values'][0]);
1907 * Verify attempt to create individual with chained arrays.
1909 public function testGetIndividualWithChainedArrays() {
1910 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__
, __FILE__
);
1911 $params['custom_' . $ids['custom_field_id']] = "custom string";
1913 $moreIDs = $this->CustomGroupMultipleCreateWithFields();
1914 $description = "This demonstrates the usage of chained api functions.\nIn this case no notes or custom fields have been created.";
1915 $subfile = "APIChainedArray";
1917 'first_name' => 'abc3',
1918 'last_name' => 'xyz3',
1919 'contact_type' => 'Individual',
1920 'email' => 'man3@yahoo.com',
1921 'api.contribution.create' => array(
1922 'receive_date' => '2010-01-01',
1923 'total_amount' => 100.00,
1924 'financial_type_id' => 1,
1925 'payment_instrument_id' => 1,
1926 'non_deductible_amount' => 10.00,
1927 'fee_amount' => 50.00,
1928 'net_amount' => 90.00,
1930 'invoice_id' => 67890,
1932 'contribution_status_id' => 1,
1934 'api.contribution.create.1' => array(
1935 'receive_date' => '2011-01-01',
1936 'total_amount' => 120.00,
1937 'financial_type_id' => $this->_financialTypeId
= 1,
1938 'payment_instrument_id' => 1,
1939 'non_deductible_amount' => 10.00,
1940 'fee_amount' => 50.00,
1941 'net_amount' => 90.00,
1943 'invoice_id' => 67830,
1945 'contribution_status_id' => 1,
1947 'api.website.create' => array(
1949 'url' => "http://civicrm.org",
1954 $result = $this->callAPISuccess('Contact', 'create', $params);
1956 'id' => $result['id'],
1957 'api.website.get' => array(),
1958 'api.Contribution.get' => array(
1959 'total_amount' => '120.00',
1961 'api.CustomValue.get' => 1,
1962 'api.Note.get' => 1,
1964 $result = $this->callAPIAndDocument('Contact', 'Get', $params, __FUNCTION__
, __FILE__
, $description, $subfile);
1965 // delete the contact
1966 $this->callAPISuccess('contact', 'delete', $result);
1967 $this->customGroupDelete($ids['custom_group_id']);
1968 $this->customGroupDelete($moreIDs['custom_group_id']);
1969 $this->assertEquals(0, $result['values'][$result['id']]['api.website.get']['is_error']);
1970 $this->assertEquals("http://civicrm.org", $result['values'][$result['id']]['api.website.get']['values'][0]['url']);
1974 * Verify attempt to create individual with chained arrays and sequential.
1976 * See https://issues.civicrm.org/jira/browse/CRM-15815
1978 public function testCreateIndividualWithChainedArrayAndSequential() {
1981 'first_name' => 'abc5',
1982 'last_name' => 'xyz5',
1983 'contact_type' => 'Individual',
1984 'email' => 'woman5@yahoo.com',
1985 'api.phone.create' => array(
1986 array('phone' => '03-231 07 95'),
1987 array('phone' => '03-232 51 62'),
1989 'api.website.create' => array(
1990 'url' => 'http://civicrm.org',
1993 $result = $this->callAPISuccess('Contact', 'create', $params);
1995 // I could try to parse the result to see whether the two phone numbers
1996 // and the website are there, but I am not sure about the correct format.
1997 // So I will just fetch it again before checking.
1998 // See also http://forum.civicrm.org/index.php/topic,35393.0.html
2001 'id' => $result['id'],
2002 'api.website.get' => array(),
2003 'api.phone.get' => array(),
2005 $result = $this->callAPISuccess('Contact', 'get', $params);
2007 // delete the contact
2008 $this->callAPISuccess('contact', 'delete', $result);
2010 $this->assertEquals(2, $result['values'][0]['api.phone.get']['count']);
2011 $this->assertEquals(1, $result['values'][0]['api.website.get']['count']);
2015 * Test retrieving an individual with chained array syntax.
2017 public function testGetIndividualWithChainedArraysFormats() {
2018 $description = "This demonstrates the usage of chained api functions.\nIn this case no notes or custom fields have been created.";
2019 $subfile = "APIChainedArrayFormats";
2020 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__
, __FILE__
);
2021 $params['custom_' . $ids['custom_field_id']] = "custom string";
2023 $moreIDs = $this->CustomGroupMultipleCreateWithFields();
2025 'first_name' => 'abc3',
2026 'last_name' => 'xyz3',
2027 'contact_type' => 'Individual',
2028 'email' => 'man3@yahoo.com',
2029 'api.contribution.create' => array(
2030 'receive_date' => '2010-01-01',
2031 'total_amount' => 100.00,
2032 'financial_type_id' => $this->_financialTypeId
,
2033 'payment_instrument_id' => 1,
2034 'non_deductible_amount' => 10.00,
2035 'fee_amount' => 50.00,
2036 'net_amount' => 90.00,
2038 'contribution_status_id' => 1,
2040 'api.contribution.create.1' => array(
2041 'receive_date' => '2011-01-01',
2042 'total_amount' => 120.00,
2043 'financial_type_id' => $this->_financialTypeId
,
2044 'payment_instrument_id' => 1,
2045 'non_deductible_amount' => 10.00,
2046 'fee_amount' => 50.00,
2047 'net_amount' => 90.00,
2049 'contribution_status_id' => 1,
2051 'api.website.create' => array(
2053 'url' => "http://civicrm.org",
2058 $result = $this->callAPISuccess('Contact', 'create', $params);
2060 'id' => $result['id'],
2061 'api.website.getValue' => array('return' => 'url'),
2062 'api.Contribution.getCount' => array(),
2063 'api.CustomValue.get' => 1,
2064 'api.Note.get' => 1,
2065 'api.Membership.getCount' => array(),
2067 $result = $this->callAPIAndDocument('Contact', 'Get', $params, __FUNCTION__
, __FILE__
, $description, $subfile);
2068 $this->assertEquals(2, $result['values'][$result['id']]['api.Contribution.getCount']);
2069 $this->assertEquals(0, $result['values'][$result['id']]['api.Note.get']['is_error']);
2070 $this->assertEquals("http://civicrm.org", $result['values'][$result['id']]['api.website.getValue']);
2072 $this->callAPISuccess('contact', 'delete', $result);
2073 $this->customGroupDelete($ids['custom_group_id']);
2074 $this->customGroupDelete($moreIDs['custom_group_id']);
2078 * Test complex chaining.
2080 public function testGetIndividualWithChainedArraysAndMultipleCustom() {
2081 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__
, __FILE__
);
2082 $params['custom_' . $ids['custom_field_id']] = "custom string";
2083 $moreIDs = $this->CustomGroupMultipleCreateWithFields();
2084 $andMoreIDs = $this->CustomGroupMultipleCreateWithFields(array(
2085 'title' => "another group",
2086 'name' => 'another name',
2088 $description = "This demonstrates the usage of chained api functions with multiple custom fields.";
2089 $subfile = "APIChainedArrayMultipleCustom";
2091 'first_name' => 'abc3',
2092 'last_name' => 'xyz3',
2093 'contact_type' => 'Individual',
2094 'email' => 'man3@yahoo.com',
2095 'api.contribution.create' => array(
2096 'receive_date' => '2010-01-01',
2097 'total_amount' => 100.00,
2098 'financial_type_id' => 1,
2099 'payment_instrument_id' => 1,
2100 'non_deductible_amount' => 10.00,
2101 'fee_amount' => 50.00,
2102 'net_amount' => 90.00,
2104 'invoice_id' => 67890,
2106 'contribution_status_id' => 1,
2108 'api.contribution.create.1' => array(
2109 'receive_date' => '2011-01-01',
2110 'total_amount' => 120.00,
2111 'financial_type_id' => 1,
2112 'payment_instrument_id' => 1,
2113 'non_deductible_amount' => 10.00,
2114 'fee_amount' => 50.00,
2115 'net_amount' => 90.00,
2117 'invoice_id' => 67830,
2119 'contribution_status_id' => 1,
2121 'api.website.create' => array(
2123 'url' => "http://civicrm.org",
2126 'custom_' . $ids['custom_field_id'] => "value 1",
2127 'custom_' . $moreIDs['custom_field_id'][0] => "value 2",
2128 'custom_' . $moreIDs['custom_field_id'][1] => "warm beer",
2129 'custom_' . $andMoreIDs['custom_field_id'][1] => "vegemite",
2132 $result = $this->callAPISuccess('Contact', 'create', $params);
2133 $result = $this->callAPISuccess('Contact', 'create', array(
2134 'contact_type' => 'Individual',
2135 'id' => $result['id'],
2137 $moreIDs['custom_field_id'][0] => "value 3",
2139 $ids['custom_field_id'] => "value 4",
2143 'id' => $result['id'],
2144 'api.website.getValue' => array('return' => 'url'),
2145 'api.Contribution.getCount' => array(),
2146 'api.CustomValue.get' => 1,
2148 $result = $this->callAPIAndDocument('Contact', 'Get', $params, __FUNCTION__
, __FILE__
, $description, $subfile);
2150 $this->customGroupDelete($ids['custom_group_id']);
2151 $this->customGroupDelete($moreIDs['custom_group_id']);
2152 $this->customGroupDelete($andMoreIDs['custom_group_id']);
2153 $this->assertEquals(0, $result['values'][$result['id']]['api.CustomValue.get']['is_error']);
2154 $this->assertEquals('http://civicrm.org', $result['values'][$result['id']]['api.website.getValue']);
2158 * Test checks usage of $values to pick & choose inputs.
2160 public function testChainingValuesCreate() {
2161 $description = "This demonstrates the usage of chained api functions. Specifically it has one 'parent function' &
2162 2 child functions - one receives values from the parent (Contact) and the other child (Tag).";
2163 $subfile = "APIChainedArrayValuesFromSiblingFunction";
2165 'display_name' => 'batman',
2166 'contact_type' => 'Individual',
2167 'api.tag.create' => array(
2168 'name' => '$value.id',
2169 'description' => '$value.display_name',
2170 'format.only_id' => 1,
2172 'api.entity_tag.create' => array('tag_id' => '$value.api.tag.create'),
2174 $result = $this->callAPIAndDocument('Contact', 'Create', $params, __FUNCTION__
, __FILE__
, $description, $subfile);
2175 $this->assertEquals(0, $result['values'][$result['id']]['api.entity_tag.create']['is_error']);
2177 $tablesToTruncate = array(
2180 'civicrm_entity_tag',
2183 $this->quickCleanup($tablesToTruncate, TRUE);
2187 * Test TrueFalse format - I couldn't come up with an easy way to get an error on Get.
2189 public function testContactGetFormatIsSuccessTrue() {
2190 $this->createContactFromXML();
2191 $description = "This demonstrates use of the 'format.is_success' param.
2192 This param causes only the success or otherwise of the function to be returned as BOOLEAN";
2193 $subfile = "FormatIsSuccess_True";
2194 $params = array('id' => 17, 'format.is_success' => 1);
2195 $result = $this->callAPIAndDocument('Contact', 'Get', $params, __FUNCTION__
, __FILE__
, $description, $subfile);
2196 $this->assertEquals(1, $result);
2197 $this->callAPISuccess('Contact', 'Delete', $params);
2201 * Test TrueFalse format.
2203 public function testContactCreateFormatIsSuccessFalse() {
2205 $description = "This demonstrates use of the 'format.is_success' param.
2206 This param causes only the success or otherwise of the function to be returned as BOOLEAN";
2207 $subfile = "FormatIsSuccess_Fail";
2208 $params = array('id' => 500, 'format.is_success' => 1);
2209 $result = $this->callAPIAndDocument('Contact', 'Create', $params, __FUNCTION__
, __FILE__
, $description, $subfile);
2210 $this->assertEquals(0, $result);
2214 * Test Single Entity format.
2216 public function testContactGetSingleEntityArray() {
2217 $this->createContactFromXML();
2218 $description = "This demonstrates use of the 'format.single_entity_array' param.
2219 This param causes the only contact to be returned as an array without the other levels.
2220 It will be ignored if there is not exactly 1 result";
2221 $subfile = "GetSingleContact";
2222 $params = array('id' => 17);
2223 $result = $this->callAPIAndDocument('Contact', 'GetSingle', $params, __FUNCTION__
, __FILE__
, $description, $subfile);
2224 $this->assertEquals('Test Contact', $result['display_name']);
2225 $this->callAPISuccess('Contact', 'Delete', $params);
2229 * Test Single Entity format.
2231 public function testContactGetFormatCountOnly() {
2232 $this->createContactFromXML();
2233 $description = "This demonstrates use of the 'getCount' action.
2234 This param causes the count of the only function to be returned as an integer.";
2235 $params = array('id' => 17);
2236 $result = $this->callAPIAndDocument('Contact', 'GetCount', $params, __FUNCTION__
, __FILE__
, $description,
2238 $this->assertEquals('1', $result);
2239 $this->callAPISuccess('Contact', 'Delete', $params);
2243 * Test id only format.
2245 public function testContactGetFormatIDOnly() {
2246 $this->createContactFromXML();
2247 $description = "This demonstrates use of the 'format.id_only' param.
2248 This param causes the id of the only entity to be returned as an integer.
2249 It will be ignored if there is not exactly 1 result";
2250 $subfile = "FormatOnlyID";
2251 $params = array('id' => 17, 'format.only_id' => 1);
2252 $result = $this->callAPIAndDocument('Contact', 'Get', $params, __FUNCTION__
, __FILE__
, $description, $subfile);
2253 $this->assertEquals('17', $result);
2254 $this->callAPISuccess('Contact', 'Delete', $params);
2258 * Test id only format.
2260 public function testContactGetFormatSingleValue() {
2261 $this->createContactFromXML();
2262 $description = "This demonstrates use of the 'format.single_value' param.
2263 This param causes only a single value of the only entity to be returned as an string.
2264 It will be ignored if there is not exactly 1 result";
2265 $subFile = "FormatSingleValue";
2266 $params = array('id' => 17, 'return' => 'display_name');
2267 $result = $this->callAPIAndDocument('Contact', 'getvalue', $params, __FUNCTION__
, __FILE__
, $description, $subFile);
2268 $this->assertEquals('Test Contact', $result);
2269 $this->callAPISuccess('Contact', 'Delete', $params);
2273 * Test that permissions are respected when creating contacts.
2275 public function testContactCreationPermissions() {
2277 'contact_type' => 'Individual',
2278 'first_name' => 'Foo',
2279 'last_name' => 'Bear',
2280 'check_permissions' => TRUE,
2282 $config = CRM_Core_Config
::singleton();
2283 $config->userPermissionClass
->permissions
= array('access CiviCRM');
2284 $result = $this->callAPIFailure('contact', 'create', $params);
2285 $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');
2287 $config->userPermissionClass
->permissions
= array('access CiviCRM', 'add contacts', 'import contacts');
2288 $this->callAPISuccess('contact', 'create', $params);
2292 * Test that delete with skip undelete respects permissions.
2294 public function testContactDeletePermissions() {
2295 $contactID = $this->individualCreate();
2296 CRM_Core_Config
::singleton()->userPermissionClass
->permissions
= array('access CiviCRM');
2297 $this->callAPIFailure('Contact', 'delete', array(
2299 'check_permissions' => 1,
2300 'skip_undelete' => 1,
2302 $this->callAPISuccess('Contact', 'delete', array(
2304 'check_permissions' => 0,
2305 'skip_undelete' => 1,
2310 * Test update with check permissions set.
2312 public function testContactUpdatePermissions() {
2314 'contact_type' => 'Individual',
2315 'first_name' => 'Foo',
2316 'last_name' => 'Bear',
2317 'check_permissions' => TRUE,
2319 $result = $this->callAPISuccess('contact', 'create', $params);
2320 $config = CRM_Core_Config
::singleton();
2322 'id' => $result['id'],
2323 'contact_type' => 'Individual',
2324 'last_name' => 'Bar',
2325 'check_permissions' => TRUE,
2328 $config->userPermissionClass
->permissions
= array('access CiviCRM');
2329 $result = $this->callAPIFailure('contact', 'update', $params);
2330 $this->assertEquals('Permission denied to modify contact record', $result['error_message']);
2332 $config->userPermissionClass
->permissions
= array(
2335 'view all contacts',
2336 'edit all contacts',
2339 $this->callAPISuccess('contact', 'update', $params);
2343 * Set up helper to create a contact.
2345 public function createContactFromXML() {
2346 // Insert a row in civicrm_contact creating contact 17.
2347 $op = new PHPUnit_Extensions_Database_Operation_Insert();
2348 $op->execute($this->_dbconn
,
2349 $this->createXMLDataSet(
2350 dirname(__FILE__
) . '/dataset/contact_17.xml'
2356 * Test contact proximity api.
2358 public function testContactProximity() {
2359 // first create a contact with a SF location with a specific
2361 $contactID = $this->organizationCreate();
2363 // now create the address
2365 'street_address' => '123 Main Street',
2366 'city' => 'San Francisco',
2368 'country_id' => 1228,
2369 'state_province_id' => 1004,
2370 'geo_code_1' => '37.79',
2371 'geo_code_2' => '-122.40',
2372 'location_type_id' => 1,
2373 'contact_id' => $contactID,
2376 $result = $this->callAPISuccess('address', 'create', $params);
2377 $this->assertEquals(1, $result['count']);
2379 // now do a proximity search with a close enough geocode and hope to match
2380 // that specific contact only!
2381 $proxParams = array(
2383 'longitude' => -122.3,
2387 $result = $this->callAPISuccess('contact', 'proximity', $proxParams);
2388 $this->assertEquals(1, $result['count']);
2392 * Test that Ajax API permission is sufficient to access getquick api.
2394 * (note that getquick api is required for autocomplete & has ACL permissions applied)
2396 public function testGetquickPermissionCRM13744() {
2397 CRM_Core_Config
::singleton()->userPermissionClass
->permissions
= array('access CiviEvent');
2398 $this->callAPIFailure('contact', 'getquick', array('name' => 'b', 'check_permissions' => TRUE));
2399 CRM_Core_Config
::singleton()->userPermissionClass
->permissions
= array('access CiviCRM');
2400 $this->callAPISuccess('contact', 'getquick', array('name' => 'b', 'check_permissions' => TRUE));
2401 CRM_Core_Config
::singleton()->userPermissionClass
->permissions
= array('access AJAX API');
2402 $this->callAPISuccess('contact', 'getquick', array('name' => 'b', 'check_permissions' => TRUE));
2406 * Test that getquick returns contacts with an exact first name match first.
2408 * The search string 'b' & 'bob' both return ordered by sort_name if includeOrderByClause
2409 * is true (default) but if it is false then matches are returned in ID order.
2411 public function testGetQuickExactFirst() {
2412 $this->getQuickSearchSampleData();
2413 $result = $this->callAPISuccess('contact', 'getquick', array('name' => 'b'));
2414 $this->assertEquals('A Bobby, Bobby', $result['values'][0]['sort_name']);
2415 $this->assertEquals('B Bobby, Bobby', $result['values'][1]['sort_name']);
2416 $result = $this->callAPISuccess('contact', 'getquick', array('name' => 'bob'));
2417 $this->assertEquals('A Bobby, Bobby', $result['values'][0]['sort_name']);
2418 $this->assertEquals('B Bobby, Bobby', $result['values'][1]['sort_name']);
2419 $this->callAPISuccess('Setting', 'create', array('includeOrderByClause' => FALSE));
2420 $result = $this->callAPISuccess('contact', 'getquick', array('name' => 'bob'));
2421 $this->assertEquals('Bob, Bob', $result['values'][0]['sort_name']);
2422 $this->assertEquals('A Bobby, Bobby', $result['values'][1]['sort_name']);
2426 * Test that getquick returns contacts with an exact first name match first.
2428 public function testGetQuickEmail() {
2429 $this->getQuickSearchSampleData();
2430 $loggedInContactID = $this->createLoggedInUser();
2431 $result = $this->callAPISuccess('contact', 'getquick', array(
2434 $expectedData = array(
2435 'Bob, Bob :: bob@bob.com',
2437 'E Bobby, Bobby :: bob@bobby.com',
2438 'H Bobby, Bobby :: bob@h.com',
2440 $this->callAPISuccessGetValue('Contact', array('id' => $loggedInContactID, 'return' => 'last_name')) . ', Logged In :: anthony_anderson@civicrm.org',
2442 $this->assertEquals(6, $result['count']);
2443 foreach ($expectedData as $index => $value) {
2444 $this->assertEquals($value, $result['values'][$index]['data']);
2446 $result = $this->callAPISuccess('contact', 'getquick', array(
2449 $expectedData = array(
2450 'H Bobby, Bobby :: bob@h.com',
2452 foreach ($expectedData as $index => $value) {
2453 $this->assertEquals($value, $result['values'][$index]['data']);
2455 $this->callAPISuccess('Setting', 'create', array('includeWildCardInName' => FALSE));
2456 $result = $this->callAPISuccess('contact', 'getquick', array(
2459 $this->callAPISuccess('Setting', 'create', array('includeWildCardInName' => TRUE));
2460 $this->assertEquals(0, $result['count']);
2464 * Test that getquick returns contacts with an exact first name match first.
2466 public function testGetQuickEmailACL() {
2467 $this->getQuickSearchSampleData();
2468 $loggedInContactID = $this->createLoggedInUser();
2469 CRM_Core_Config
::singleton()->userPermissionClass
->permissions
= array();
2470 $result = $this->callAPISuccess('contact', 'getquick', array(
2473 $this->assertEquals(0, $result['count']);
2475 $this->hookClass
->setHook('civicrm_aclWhereClause', array($this, 'aclWhereNoBobH'));
2476 CRM_Contact_BAO_Contact_Permission
::cache($loggedInContactID, CRM_Core_Permission
::VIEW
, TRUE);
2477 $result = $this->callAPISuccess('contact', 'getquick', array(
2481 // Without the acl it would be 6 like the previous email getquick test.
2482 $this->assertEquals(5, $result['count']);
2483 $expectedData = array(
2484 'Bob, Bob :: bob@bob.com',
2486 'E Bobby, Bobby :: bob@bobby.com',
2488 $this->callAPISuccessGetValue('Contact', array('id' => $loggedInContactID, 'return' => 'last_name')) . ', Logged In :: anthony_anderson@civicrm.org',
2490 foreach ($expectedData as $index => $value) {
2491 $this->assertEquals($value, $result['values'][$index]['data']);
2496 * Test that getquick returns contacts with an exact first name match first.
2498 public function testGetQuickExternalID() {
2499 $this->getQuickSearchSampleData();
2500 $result = $this->callAPISuccess('contact', 'getquick', array(
2502 'field_name' => 'external_identifier',
2503 'table_name' => 'cc',
2505 $this->assertEquals(0, $result['count']);
2506 $result = $this->callAPISuccess('contact', 'getquick', array(
2508 'field_name' => 'external_identifier',
2509 'table_name' => 'cc',
2511 $this->assertEquals(1, $result['count']);
2512 $this->assertEquals('Bob, Bob', $result['values'][0]['sort_name']);
2516 * Test that getquick returns contacts with an exact first name match first.
2518 public function testGetQuickID() {
2519 $max = CRM_Core_DAO
::singleValueQuery("SELECT max(id) FROM civicrm_contact");
2520 $this->getQuickSearchSampleData();
2521 $result = $this->callAPISuccess('contact', 'getquick', array(
2523 'field_name' => 'id',
2524 'table_name' => 'cc',
2526 $this->assertEquals(1, $result['count']);
2527 $this->assertEquals('A Bobby, Bobby', $result['values'][0]['sort_name']);
2528 $result = $this->callAPISuccess('contact', 'getquick', array(
2530 'field_name' => 'contact_id',
2531 'table_name' => 'cc',
2533 $this->assertEquals(1, $result['count']);
2534 $this->assertEquals('A Bobby, Bobby', $result['values'][0]['sort_name']);
2538 * Test that getquick returns contacts with an exact first name match first.
2540 * Depending on the setting the sort name sort might click in next or not - test!
2542 public function testGetQuickFirstName() {
2543 $this->getQuickSearchSampleData();
2544 $this->callAPISuccess('Setting', 'create', array('includeOrderByClause' => TRUE));
2545 $result = $this->callAPISuccess('contact', 'getquick', array(
2547 'field_name' => 'first_name',
2548 'table_name' => 'cc',
2556 foreach ($expected as $index => $value) {
2557 $this->assertEquals($value, $result['values'][$index]['sort_name']);
2559 $this->callAPISuccess('Setting', 'create', array('includeOrderByClause' => FALSE));
2560 $result = $this->callAPISuccess('contact', 'getquick', array('name' => 'bob'));
2561 $this->assertEquals('Bob, Bob', $result['values'][0]['sort_name']);
2562 $this->assertEquals('A Bobby, Bobby', $result['values'][1]['sort_name']);
2566 * Test that getquick applies ACLs.
2568 public function testGetQuickFirstNameACLs() {
2569 $this->getQuickSearchSampleData();
2570 $userID = $this->createLoggedInUser();
2571 $this->callAPISuccess('Setting', 'create', array('includeOrderByClause' => TRUE));
2572 CRM_Core_Config
::singleton()->userPermissionClass
->permissions
= array();
2573 $result = $this->callAPISuccess('contact', 'getquick', array(
2575 'field_name' => 'first_name',
2576 'table_name' => 'cc',
2578 $this->assertEquals(0, $result['count']);
2580 $this->hookClass
->setHook('civicrm_aclWhereClause', array($this, 'aclWhereNoBobH'));
2581 CRM_Contact_BAO_Contact_Permission
::cache($userID, CRM_Core_Permission
::VIEW
, TRUE);
2582 $result = $this->callAPISuccess('contact', 'getquick', array(
2584 'field_name' => 'first_name',
2585 'table_name' => 'cc',
2587 $this->assertEquals('K Bobby, Bob', $result['values'][1]['sort_name']);
2588 // Without the ACL 9 would be bob@h.com.
2589 $this->assertEquals('I Bobby, Bobby', $result['values'][9]['sort_name']);
2593 * Full results returned.
2594 * @implements CRM_Utils_Hook::aclWhereClause
2596 * @param string $type
2597 * @param array $tables
2598 * @param array $whereTables
2599 * @param int $contactID
2600 * @param string $where
2602 public function aclWhereNoBobH($type, &$tables, &$whereTables, &$contactID, &$where) {
2603 $where = " (email <> 'bob@h.com' OR email IS NULL) ";
2604 $whereTables['civicrm_email'] = "LEFT JOIN civicrm_email e ON contact_a.id = e.contact_id";
2608 * Test that getquick returns contacts with an exact last name match first.
2610 public function testGetQuickLastName() {
2611 $this->getQuickSearchSampleData();
2612 $this->callAPISuccess('Setting', 'create', array('includeOrderByClause' => TRUE));
2613 $result = $this->callAPISuccess('contact', 'getquick', array(
2615 'field_name' => 'last_name',
2616 'table_name' => 'cc',
2624 foreach ($expected as $index => $value) {
2625 $this->assertEquals($value, $result['values'][$index]['sort_name']);
2627 $this->callAPISuccess('Setting', 'create', array('includeOrderByClause' => FALSE));
2628 $result = $this->callAPISuccess('contact', 'getquick', array('name' => 'bob'));
2629 $this->assertEquals('Bob, Bob :: bob@bob.com', $result['values'][0]['data']);
2633 * Test that getquick returns contacts by city.
2635 public function testGetQuickCity() {
2636 $this->getQuickSearchSampleData();
2637 $result = $this->callAPISuccess('contact', 'getquick', array(
2639 'field_name' => 'city',
2640 'table_name' => 'sts',
2642 $this->assertEquals('B Bobby, Bobby :: Toronto', $result['values'][0]['data']);
2643 $result = $this->callAPISuccess('contact', 'getquick', array(
2645 'field_name' => 'city',
2646 'table_name' => 'sts',
2648 $this->assertEquals('B Bobby, Bobby :: Toronto', $result['values'][0]['data']);
2649 $this->assertEquals('C Bobby, Bobby :: Whanganui', $result['values'][1]['data']);
2653 * Set up some sample data for testing quicksearch.
2655 public function getQuickSearchSampleData() {
2657 array('first_name' => 'Bob', 'last_name' => 'Bob', 'external_identifier' => 'abc', 'email' => 'bob@bob.com'),
2658 array('first_name' => 'Bobby', 'last_name' => 'A Bobby', 'external_identifier' => 'abcd'),
2660 'first_name' => 'Bobby',
2661 'last_name' => 'B Bobby',
2662 'external_identifier' => 'bcd',
2663 'api.address.create' => array(
2664 'street_address' => 'Sesame Street',
2665 'city' => 'Toronto',
2666 'location_type_id' => 1,
2670 'first_name' => 'Bobby',
2671 'last_name' => 'C Bobby',
2672 'external_identifier' => 'bcde',
2673 'api.address.create' => array(
2674 'street_address' => 'Te huarahi',
2675 'city' => 'Whanganui',
2676 'location_type_id' => 1,
2679 array('first_name' => 'Bobby', 'last_name' => 'D Bobby', 'external_identifier' => 'efg'),
2680 array('first_name' => 'Bobby', 'last_name' => 'E Bobby', 'external_identifier' => 'hij', 'email' => 'bob@bobby.com'),
2681 array('first_name' => 'Bobby', 'last_name' => 'F Bobby', 'external_identifier' => 'klm'),
2682 array('first_name' => 'Bobby', 'last_name' => 'G Bobby', 'external_identifier' => 'nop'),
2683 array('first_name' => 'Bobby', 'last_name' => 'H Bobby', 'external_identifier' => 'qrs', 'email' => 'bob@h.com'),
2684 array('first_name' => 'Bobby', 'last_name' => 'I Bobby'),
2685 array('first_name' => 'Bobby', 'last_name' => 'J Bobby'),
2686 array('first_name' => 'Bob', 'last_name' => 'K Bobby', 'external_identifier' => 'bcdef'),
2688 foreach ($contacts as $type => $contact) {
2689 $contact['contact_type'] = 'Individual';
2690 $this->callAPISuccess('Contact', 'create', $contact);
2695 * Test get ref api - gets a list of references to an entity.
2697 public function testGetReferenceCounts() {
2698 $result = $this->callAPISuccess('Contact', 'create', array(
2699 'first_name' => 'Testily',
2700 'last_name' => 'McHaste',
2701 'contact_type' => 'Individual',
2702 'api.Address.replace' => array(
2703 'values' => array(),
2705 'api.Email.replace' => array(
2708 'email' => 'spam@dev.null',
2710 'location_type_id' => 1,
2714 'api.Phone.replace' => array(
2717 'phone' => '234-567-0001',
2719 'location_type_id' => 1,
2722 'phone' => '234-567-0002',
2724 'location_type_id' => 1,
2730 //$dao = new CRM_Contact_BAO_Contact();
2731 //$dao->id = $result['id'];
2732 //$this->assertTrue((bool) $dao->find(TRUE));
2734 //$refCounts = $dao->getReferenceCounts();
2735 //$this->assertTrue(is_array($refCounts));
2736 //$refCountsIdx = CRM_Utils_Array::index(array('name'), $refCounts);
2738 $refCounts = $this->callAPISuccess('Contact', 'getrefcount', array(
2739 'id' => $result['id'],
2741 $refCountsIdx = CRM_Utils_Array
::index(array('name'), $refCounts['values']);
2743 $this->assertEquals(1, $refCountsIdx['sql:civicrm_email:contact_id']['count']);
2744 $this->assertEquals('civicrm_email', $refCountsIdx['sql:civicrm_email:contact_id']['table']);
2745 $this->assertEquals(2, $refCountsIdx['sql:civicrm_phone:contact_id']['count']);
2746 $this->assertEquals('civicrm_phone', $refCountsIdx['sql:civicrm_phone:contact_id']['table']);
2747 $this->assertTrue(!isset($refCountsIdx['sql:civicrm_address:contact_id']));
2751 * Test the use of sql operators.
2753 public function testSQLOperatorsOnContactAPI() {
2754 $this->individualCreate();
2755 $this->organizationCreate();
2756 $this->householdCreate();
2757 $contacts = $this->callAPISuccess('contact', 'get', array('legal_name' => array('IS NOT NULL' => TRUE)));
2758 $this->assertEquals($contacts['count'], CRM_Core_DAO
::singleValueQuery('select count(*) FROM civicrm_contact WHERE legal_name IS NOT NULL'));
2759 $contacts = $this->callAPISuccess('contact', 'get', array('legal_name' => array('IS NULL' => TRUE)));
2760 $this->assertEquals($contacts['count'], CRM_Core_DAO
::singleValueQuery('select count(*) FROM civicrm_contact WHERE legal_name IS NULL'));
2764 * CRM-14743 - test api respects search operators.
2766 public function testGetModifiedDateByOperators() {
2767 $preExistingContactCount = CRM_Core_DAO
::singleValueQuery('select count(*) FROM civicrm_contact');
2768 $contact1 = $this->individualCreate();
2769 $sql = "UPDATE civicrm_contact SET created_date = '2012-01-01', modified_date = '2013-01-01' WHERE id = " . $contact1;
2770 CRM_Core_DAO
::executeQuery($sql);
2771 $contact2 = $this->individualCreate();
2772 $sql = "UPDATE civicrm_contact SET created_date = '2012-02-01', modified_date = '2013-02-01' WHERE id = " . $contact2;
2773 CRM_Core_DAO
::executeQuery($sql);
2774 $contact3 = $this->householdCreate();
2775 $sql = "UPDATE civicrm_contact SET created_date = '2012-03-01', modified_date = '2013-03-01' WHERE id = " . $contact3;
2776 CRM_Core_DAO
::executeQuery($sql);
2777 $contacts = $this->callAPISuccess('contact', 'get', array('modified_date' => array('<' => '2014-01-01')));
2778 $this->assertEquals($contacts['count'], 3);
2779 $contacts = $this->callAPISuccess('contact', 'get', array('modified_date' => array('>' => '2014-01-01')));
2780 $this->assertEquals($contacts['count'], $preExistingContactCount);
2784 * CRM-14743 - test api respects search operators.
2786 public function testGetCreatedDateByOperators() {
2787 $preExistingContactCount = CRM_Core_DAO
::singleValueQuery('select count(*) FROM civicrm_contact');
2788 $contact1 = $this->individualCreate();
2789 $sql = "UPDATE civicrm_contact SET created_date = '2012-01-01' WHERE id = " . $contact1;
2790 CRM_Core_DAO
::executeQuery($sql);
2791 $contact2 = $this->individualCreate();
2792 $sql = "UPDATE civicrm_contact SET created_date = '2012-02-01' WHERE id = " . $contact2;
2793 CRM_Core_DAO
::executeQuery($sql);
2794 $contact3 = $this->householdCreate();
2795 $sql = "UPDATE civicrm_contact SET created_date = '2012-03-01' WHERE id = " . $contact3;
2796 CRM_Core_DAO
::executeQuery($sql);
2797 $contacts = $this->callAPISuccess('contact', 'get', array('created_date' => array('<' => '2014-01-01')));
2798 $this->assertEquals($contacts['count'], 3);
2799 $contacts = $this->callAPISuccess('contact', 'get', array('created_date' => array('>' => '2014-01-01')));
2800 $this->assertEquals($contacts['count'], $preExistingContactCount);
2804 * CRM-14263 check that API is not affected by search profile related bug.
2806 public function testReturnCityProfile() {
2807 $contactID = $this->individualCreate();
2808 CRM_Core_Config
::singleton()->defaultSearchProfileID
= 1;
2809 $this->callAPISuccess('address', 'create', array(
2810 'contact_id' => $contactID,
2811 'city' => 'Cool City',
2812 'location_type_id' => 1,
2814 $result = $this->callAPISuccess('contact', 'get', array('city' => 'Cool City', 'return' => 'contact_type'));
2815 $this->assertEquals(1, $result['count']);
2819 * CRM-15443 - ensure getlist api does not return deleted contacts.
2821 public function testGetlistExcludeConditions() {
2822 $name = md5(time());
2823 $contact = $this->individualCreate(array('last_name' => $name));
2824 $this->individualCreate(array('last_name' => $name, 'is_deceased' => 1));
2825 $this->individualCreate(array('last_name' => $name, 'is_deleted' => 1));
2826 // We should get all but the deleted contact.
2827 $result = $this->callAPISuccess('contact', 'getlist', array('input' => $name));
2828 $this->assertEquals(2, $result['count']);
2829 // Force-exclude the deceased contact.
2830 $result = $this->callAPISuccess('contact', 'getlist', array(
2832 'params' => array('is_deceased' => 0),
2834 $this->assertEquals(1, $result['count']);
2835 $this->assertEquals($contact, $result['values'][0]['id']);
2839 * Test contact getactions.
2841 public function testGetActions() {
2842 $description = "Getting the available actions for an entity.";
2843 $result = $this->callAPIAndDocument($this->_entity
, 'getactions', array(), __FUNCTION__
, __FILE__
, $description);
2863 $deprecated = array(
2867 foreach ($expected as $action) {
2868 $this->assertTrue(in_array($action, $result['values']), "Expected action $action");
2870 foreach ($deprecated as $action) {
2871 $this->assertArrayKeyExists($action, $result['deprecated']);
2876 * Test the duplicate check function.
2878 public function testDuplicateCheck() {
2879 $this->callAPISuccess('Contact', 'create', array(
2880 'first_name' => 'Harry',
2881 'last_name' => 'Potter',
2882 'email' => 'harry@hogwarts.edu',
2883 'contact_type' => 'Individual',
2885 $result = $this->callAPISuccess('Contact', 'duplicatecheck', array(
2887 'first_name' => 'Harry',
2888 'last_name' => 'Potter',
2889 'email' => 'harry@hogwarts.edu',
2890 'contact_type' => 'Individual',
2894 $this->assertEquals(1, $result['count']);
2895 $result = $this->callAPISuccess('Contact', 'duplicatecheck', array(
2897 'first_name' => 'Harry',
2898 'last_name' => 'Potter',
2899 'email' => 'no5@privet.drive',
2900 'contact_type' => 'Individual',
2903 $this->assertEquals(0, $result['count']);
2906 public function testGetByContactType() {
2907 $individual = $this->callAPISuccess('Contact', 'create', array(
2908 'email' => 'individual@test.com',
2909 'contact_type' => 'Individual',
2911 $household = $this->callAPISuccess('Contact', 'create', array(
2912 'household_name' => 'household@test.com',
2913 'contact_type' => 'Household',
2915 $organization = $this->callAPISuccess('Contact', 'create', array(
2916 'organization_name' => 'organization@test.com',
2917 'contact_type' => 'Organization',
2919 // Test with id - getsingle will throw an exception if not found
2920 $this->callAPISuccess('Contact', 'getsingle', array(
2921 'id' => $individual['id'],
2922 'contact_type' => 'Individual',
2924 $this->callAPISuccess('Contact', 'getsingle', array(
2925 'id' => $individual['id'],
2926 'contact_type' => array('IN' => array('Individual')),
2929 $this->callAPISuccess('Contact', 'getsingle', array(
2930 'id' => $organization['id'],
2931 'contact_type' => array('IN' => array('Individual', 'Organization')),
2934 $result = $this->callAPISuccess('Contact', 'get', array(
2935 'contact_type' => array('IN' => array('Individual', 'Organization')),
2936 'options' => array('limit' => 0),
2939 $this->assertContains($organization['id'], array_keys($result['values']));
2940 $this->assertContains($individual['id'], array_keys($result['values']));
2941 $this->assertNotContains($household['id'], array_keys($result['values']));
2943 $result = $this->callAPISuccess('Contact', 'get', array(
2944 'contact_type' => 'Household',
2945 'options' => array('limit' => 0),
2948 $this->assertNotContains($organization['id'], array_keys($result['values']));
2949 $this->assertNotContains($individual['id'], array_keys($result['values']));
2950 $this->assertContains($household['id'], array_keys($result['values']));
2954 * Test merging 2 contacts.
2956 * Someone kindly bequethed us the legacy of mixed up use of main_id & other_id
2957 * in the params for contact.merge api.
2959 * This test protects that legacy.
2961 public function testMergeBizzareOldParams() {
2962 $this->createLoggedInUser();
2963 $otherContact = $this->callAPISuccess('contact', 'create', $this->_params
);
2964 $mainContact = $this->callAPISuccess('contact', 'create', $this->_params
);
2965 $this->callAPISuccess('contact', 'merge', array(
2966 'main_id' => $mainContact['id'],
2967 'other_id' => $otherContact['id'],
2969 $contacts = $this->callAPISuccess('contact', 'get', $this->_params
);
2970 $this->assertEquals($otherContact['id'], $contacts['id']);
2974 * Test merging 2 contacts.
2976 public function testMerge() {
2977 $this->createLoggedInUser();
2978 $otherContact = $this->callAPISuccess('contact', 'create', $this->_params
);
2979 $retainedContact = $this->callAPISuccess('contact', 'create', $this->_params
);
2980 $this->callAPISuccess('contact', 'merge', array(
2981 'to_keep_id' => $retainedContact['id'],
2982 'to_remove_id' => $otherContact['id'],
2983 'auto_flip' => FALSE,
2986 $contacts = $this->callAPISuccess('contact', 'get', $this->_params
);
2987 $this->assertEquals($retainedContact['id'], $contacts['id']);
2988 $activity = $this->callAPISuccess('Activity', 'getsingle', array(
2989 'target_contact_id' => $retainedContact['id'],
2990 'activity_type_id' => 'Contact Merged',
2992 $this->assertEquals(date('Y-m-d'), date('Y-m-d', strtotime($activity['activity_date_time'])));
2993 $activity2 = $this->callAPISuccess('Activity', 'getsingle', array(
2994 'target_contact_id' => $otherContact['id'],
2995 'activity_type_id' => 'Contact Deleted by Merge',
2997 $this->assertEquals($activity['id'], $activity2['parent_id']);
2998 $this->assertEquals('Normal', civicrm_api3('option_value', 'getvalue', array(
2999 'value' => $activity['priority_id'],
3000 'return' => 'label',
3001 'option_group_id' => 'priority',
3007 * Test merging 2 contacts with delete to trash off.
3009 * We are checking that there is no error due to attempting to add an activity for the
3014 public function testMergeNoTrash() {
3015 $this->createLoggedInUser();
3016 $this->callAPISuccess('Setting', 'create', array('contact_undelete' => FALSE));
3017 $otherContact = $this->callAPISuccess('contact', 'create', $this->_params
);
3018 $retainedContact = $this->callAPISuccess('contact', 'create', $this->_params
);
3019 $this->callAPISuccess('contact', 'merge', array(
3020 'to_keep_id' => $retainedContact['id'],
3021 'to_remove_id' => $otherContact['id'],
3022 'auto_flip' => FALSE,
3024 $this->callAPISuccess('Setting', 'create', array('contact_undelete' => TRUE));
3028 * Ensure format with return=group shows comma-separated group IDs.
3032 public function testContactGetReturnGroup() {
3033 // Set up a contact, asser that they were created.
3034 $contact_params = array(
3035 'contact_type' => 'Individual',
3036 'first_name' => 'Test',
3037 'last_name' => 'Groupmember',
3038 'email' => 'test@example.org',
3040 $create_contact = $this->callApiSuccess('Contact', 'create', $contact_params);
3041 $this->assertEquals(0, $create_contact['is_error']);
3042 $this->assertInternalType('int', $create_contact['id']);
3044 $created_contact_id = $create_contact['id'];
3046 // Set up multiple groups, add the contact to the groups.
3047 $test_groups = array('Test group A', 'Test group B');
3048 foreach ($test_groups as $title) {
3049 // Use this contact as group owner, since we know they exist.
3050 $group_params = array(
3052 'created_id' => $created_contact_id,
3054 $create_group = $this->callApiSuccess('Group', 'create', $group_params);
3055 $this->assertEquals(0, $create_group['is_error']);
3056 $this->assertInternalType('int', $create_group['id']);
3058 $created_group_ids[] = $create_group['id'];
3060 // Add contact to the new group.
3061 $group_contact_params = array(
3062 'contact_id' => $created_contact_id,
3063 'group_id' => $create_group['id'],
3065 $create_group_contact = $this->callApiSuccess('GroupContact', 'create', $group_contact_params);
3066 $this->assertEquals(0, $create_group_contact['is_error']);
3067 $this->assertInternalType('int', $create_group_contact['added']);
3070 // Use the Contact,get API to retrieve the contact
3071 $contact_get_params = array(
3072 'id' => $created_contact_id,
3073 'return' => 'group',
3075 $contact_get = $this->callApiSuccess('Contact', 'get', $contact_get_params);
3076 $this->assertInternalType('array', $contact_get['values'][$created_contact_id]);
3077 $this->assertInternalType('string', $contact_get['values'][$created_contact_id]['groups']);
3079 // Ensure they are shown as being in each created group.
3080 $contact_group_ids = explode(',', $contact_get['values'][$created_contact_id]['groups']);
3081 foreach ($created_group_ids as $created_group_id) {
3082 $this->assertContains($created_group_id, $contact_group_ids);