4 * File for the TestContact class.
8 * @author Walt Haas <walt@dharmatech.org> (801) 534-1262
9 * @copyright Copyright CiviCRM LLC (C) 2009
10 * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html
11 * GNU Affero General Public License version 3
12 * @version $Id: ContactTest.php 31254 2010-12-15 10:09:29Z eileen $
15 * This file is part of CiviCRM
17 * CiviCRM is free software; you can redistribute it and/or
18 * modify it under the terms of the GNU Affero General Public License
19 * as published by the Free Software Foundation; either version 3 of
20 * the License, or (at your option) any later version.
22 * CiviCRM is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 * GNU Affero General Public License for more details.
27 * You should have received a copy of the GNU Affero General Public
28 * License along with this program. If not, see
29 * <http://www.gnu.org/licenses/>.
33 * Test APIv3 civicrm_contact* functions
35 * @package CiviCRM_APIv3
36 * @subpackage API_Contact
39 class api_v3_ContactTest
extends CiviUnitTestCase
{
40 public $DBResetRequired = FALSE;
41 protected $_apiversion;
45 protected $_contactID;
46 protected $_financialTypeId = 1;
49 * Test setup for every test.
51 * Connect to the database, truncate the tables that will be used
52 * and redirect stdin to a temporary file
54 public function setUp() {
55 // Connect to the database.
57 $this->_apiversion
= 3;
58 $this->_entity
= 'contact';
59 $this->_params
= array(
60 'first_name' => 'abc1',
61 'contact_type' => 'Individual',
62 'last_name' => 'xyz1',
67 * Restore the DB for the next test.
71 public function tearDown() {
72 $this->callAPISuccess('Setting', 'create', array('includeOrderByClause' => TRUE));
73 // truncate a few tables
74 $tablesToTruncate = array(
76 'civicrm_contribution',
79 'civicrm_relationship',
83 'civicrm_acl_contact_cache',
84 'civicrm_activity_contact',
88 $this->quickCleanup($tablesToTruncate, TRUE);
93 * Test civicrm_contact_create.
95 * Verify that attempt to create individual contact with only
96 * first and last names succeeds
98 public function testAddCreateIndividual() {
99 $oldCount = CRM_Core_DAO
::singleValueQuery('select count(*) from civicrm_contact');
101 'first_name' => 'abc1',
102 'contact_type' => 'Individual',
103 'last_name' => 'xyz1',
106 $contact = $this->callAPISuccess('contact', 'create', $params);
107 $this->assertTrue(is_numeric($contact['id']));
108 $this->assertTrue($contact['id'] > 0);
109 $newCount = CRM_Core_DAO
::singleValueQuery('select count(*) from civicrm_contact');
110 $this->assertEquals($oldCount +
1, $newCount);
112 $this->assertDBState('CRM_Contact_DAO_Contact',
119 * Test for international string acceptance (CRM-10210).
121 * @dataProvider getInternationalStrings
123 * @param string $string
124 * String to be tested.
128 public function testInternationalStrings($string) {
129 $this->callAPISuccess('Contact', 'create', array_merge(
131 array('first_name' => $string)
133 $result = $this->callAPISuccessGetSingle('Contact', array('first_name' => $string));
134 $this->assertEquals($string, $result['first_name']);
136 $organizationParams = array(
137 'organization_name' => $string,
138 'contact_type' => 'Organization',
141 $this->callAPISuccess('Contact', 'create', $organizationParams);
142 $result = $this->callAPISuccessGetSingle('Contact', $organizationParams);
143 $this->assertEquals($string, $result['organization_name']);
147 * Get international string data for testing against api calls.
149 public function getInternationalStrings() {
150 $invocations = array();
151 $invocations[] = array('Scarabée');
152 $invocations[] = array('Iñtërnâtiônàlizætiøn');
153 $invocations[] = array('これは日本語のテキストです。読めますか');
154 $invocations[] = array('देखें हिन्दी कैसी नजर आती है। अरे वाह ये तो नजर आती है।');
159 * Test civicrm_contact_create.
161 * Verify that preferred language can be set.
163 public function testAddCreateIndividualWithPreferredLanguage() {
165 'first_name' => 'abc1',
166 'contact_type' => 'Individual',
167 'last_name' => 'xyz1',
168 'preferred_language' => 'es_ES',
171 $contact = $this->callAPISuccess('contact', 'create', $params);
172 $this->getAndCheck($params, $contact['id'], 'Contact');
176 * Test civicrm_contact_create with sub-types.
178 * Verify that sub-types are created successfully and not deleted by subsequent updates.
180 public function testIndividualSubType() {
182 'first_name' => 'test abc',
183 'contact_type' => 'Individual',
184 'last_name' => 'test xyz',
185 'contact_sub_type' => array('Student', 'Staff'),
187 $contact = $this->callAPISuccess('contact', 'create', $params);
188 $cid = $contact['id'];
192 'middle_name' => 'foo',
194 $this->callAPISuccess('contact', 'create', $params);
195 unset($params['middle_name']);
197 $contact = $this->callAPISuccess('contact', 'get', $params);
199 $this->assertEquals(array('Student', 'Staff'), $contact['values'][$cid]['contact_sub_type']);
203 * Verify that we can retreive contacts of different sub types
205 public function testGetMultipleContactSubTypes() {
207 // This test presumes that there are no parents or students in the dataset
210 $student = $this->callAPISuccess('contact', 'create', array(
211 'email' => 'student@example.com',
212 'contact_type' => 'Individual',
213 'contact_sub_type' => 'Student',
217 $parent = $this->callAPISuccess('contact', 'create', array(
218 'email' => 'parent@example.com',
219 'contact_type' => 'Individual',
220 'contact_sub_type' => 'Parent',
224 $contact = $this->callAPISuccess('contact', 'create', array(
225 'email' => 'parent@example.com',
226 'contact_type' => 'Individual',
229 // get all students and parents
230 $getParams = array('contact_sub_type' => array('IN' => array('Parent', 'Student')));
231 $result = civicrm_api3('contact', 'get', $getParams);
233 // check that we retrieved the student and the parent
234 $this->assertArrayHasKey($student['id'], $result['values']);
235 $this->assertArrayHasKey($parent['id'], $result['values']);
236 $this->assertEquals(2, $result['count']);
242 * Verify that attempt to create contact with empty params fails.
244 public function testCreateEmptyContact() {
245 $this->callAPIFailure('contact', 'create', array());
249 * Verify that attempt to create contact with bad contact type fails.
251 public function testCreateBadTypeContact() {
253 'email' => 'man1@yahoo.com',
254 'contact_type' => 'Does not Exist',
256 $this->callAPIFailure('contact', 'create', $params, "'Does not Exist' is not a valid option for field contact_type");
260 * Verify that attempt to create individual contact without required fields fails.
262 public function testCreateBadRequiredFieldsIndividual() {
264 'middle_name' => 'This field is not required',
265 'contact_type' => 'Individual',
267 $this->callAPIFailure('contact', 'create', $params);
271 * Verify that attempt to create household contact without required fields fails.
273 public function testCreateBadRequiredFieldsHousehold() {
275 'middle_name' => 'This field is not required',
276 'contact_type' => 'Household',
278 $this->callAPIFailure('contact', 'create', $params);
282 * Test required field check.
284 * Verify that attempt to create organization contact without required fields fails.
286 public function testCreateBadRequiredFieldsOrganization() {
288 'middle_name' => 'This field is not required',
289 'contact_type' => 'Organization',
292 $this->callAPIFailure('contact', 'create', $params);
296 * Verify that attempt to create individual contact with only an email succeeds.
298 public function testCreateEmailIndividual() {
299 $primaryEmail = 'man3@yahoo.com';
300 $notPrimaryEmail = 'man4@yahoo.com';
302 'email' => $primaryEmail,
303 'contact_type' => 'Individual',
304 'location_type_id' => 1,
307 $contact1 = $this->callAPISuccess('contact', 'create', $params);
309 $this->assertEquals(3, $contact1['id']);
310 $email1 = $this->callAPISuccess('email', 'get', array('contact_id' => $contact1['id']));
311 $this->assertEquals(1, $email1['count']);
312 $this->assertEquals($primaryEmail, $email1['values'][$email1['id']]['email']);
314 $email2 = $this->callAPISuccess('email', 'create', array('contact_id' => $contact1['id'], 'is_primary' => 0, 'email' => $notPrimaryEmail));
316 // Case 1: Check with criteria primary 'email' => array('IS NOT NULL' => 1)
317 $result = $this->callAPISuccess('contact', 'get', array('email' => array('IS NOT NULL' => 1)));
318 $primaryEmailContactIds = array_keys($result['values']);
319 $this->assertEquals($primaryEmail, $email1['values'][$email1['id']]['email']);
321 // Case 2: Check with criteria primary 'email' => array('<>' => '')
322 $result = $this->callAPISuccess('contact', 'get', array('email' => array('<>' => '')));
323 $primaryEmailContactIds = array_keys($result['values']);
324 $this->assertEquals($primaryEmail, $email1['values'][$email1['id']]['email']);
326 // Case 3: Check with email_id='primary email id'
327 $result = $this->callAPISuccess('contact', 'get', array('email_id' => $email1['id']));
328 $this->assertEquals(1, $result['count']);
329 $this->assertEquals($contact1['id'], $result['id']);
331 $this->callAPISuccess('contact', 'delete', $contact1);
335 * Test creating individual by name.
337 * Verify create individual contact with only first and last names succeeds.
339 public function testCreateNameIndividual() {
341 'first_name' => 'abc1',
342 'contact_type' => 'Individual',
343 'last_name' => 'xyz1',
346 $this->callAPISuccess('contact', 'create', $params);
350 * Test creating individual by display_name.
352 * Display name & sort name should be set.
354 public function testCreateDisplayNameIndividual() {
356 'display_name' => 'abc1',
357 'contact_type' => 'Individual',
360 $contact = $this->callAPISuccess('contact', 'create', $params);
361 $params['sort_name'] = 'abc1';
362 $this->getAndCheck($params, $contact['id'], 'contact');
366 * Test old keys still work.
368 * Verify that attempt to create individual contact with
369 * first and last names and old key values works
371 public function testCreateNameIndividualOldKeys() {
373 'individual_prefix' => 'Dr.',
374 'first_name' => 'abc1',
375 'contact_type' => 'Individual',
376 'last_name' => 'xyz1',
377 'individual_suffix' => 'Jr.',
380 $contact = $this->callAPISuccess('contact', 'create', $params);
381 $result = $this->callAPISuccess('contact', 'getsingle', array('id' => $contact['id']));
383 $this->assertArrayKeyExists('prefix_id', $result);
384 $this->assertArrayKeyExists('suffix_id', $result);
385 $this->assertArrayKeyExists('gender_id', $result);
386 $this->assertEquals(4, $result['prefix_id']);
387 $this->assertEquals(1, $result['suffix_id']);
391 * Test preferred keys work.
393 * Verify that attempt to create individual contact with
394 * first and last names and old key values works
396 public function testCreateNameIndividualRecommendedKeys2() {
398 'prefix_id' => 'Dr.',
399 'first_name' => 'abc1',
400 'contact_type' => 'Individual',
401 'last_name' => 'xyz1',
402 'suffix_id' => 'Jr.',
403 'gender_id' => 'Male',
406 $contact = $this->callAPISuccess('contact', 'create', $params);
407 $result = $this->callAPISuccess('contact', 'getsingle', array('id' => $contact['id']));
409 $this->assertArrayKeyExists('prefix_id', $result);
410 $this->assertArrayKeyExists('suffix_id', $result);
411 $this->assertArrayKeyExists('gender_id', $result);
412 $this->assertEquals(4, $result['prefix_id']);
413 $this->assertEquals(1, $result['suffix_id']);
417 * Test household name is sufficient for create.
419 * Verify that attempt to create household contact with only
420 * household name succeeds
422 public function testCreateNameHousehold() {
424 'household_name' => 'The abc Household',
425 'contact_type' => 'Household',
427 $this->callAPISuccess('contact', 'create', $params);
431 * Test organization name is sufficient for create.
433 * Verify that attempt to create organization contact with only
434 * organization name succeeds.
436 public function testCreateNameOrganization() {
438 'organization_name' => 'The abc Organization',
439 'contact_type' => 'Organization',
441 $this->callAPISuccess('contact', 'create', $params);
445 * Verify that attempt to create organization contact without organization name fails.
447 public function testCreateNoNameOrganization() {
449 'first_name' => 'The abc Organization',
450 'contact_type' => 'Organization',
452 $this->callAPIFailure('contact', 'create', $params);
456 * Check with complete array + custom field.
458 * Note that the test is written on purpose without any
459 * variables specific to participant so it can be replicated into other entities
460 * and / or moved to the automated test suite
462 public function testCreateWithCustom() {
463 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__
, __FILE__
);
465 $params = $this->_params
;
466 $params['custom_' . $ids['custom_field_id']] = "custom string";
467 $description = "This demonstrates setting a custom field through the API.";
468 $result = $this->callAPIAndDocument($this->_entity
, 'create', $params, __FUNCTION__
, __FILE__
, $description);
470 $check = $this->callAPISuccess($this->_entity
, 'get', array(
471 'return.custom_' . $ids['custom_field_id'] => 1,
472 'id' => $result['id'],
474 $this->assertEquals("custom string", $check['values'][$check['id']]['custom_' . $ids['custom_field_id']]);
476 $this->customFieldDelete($ids['custom_field_id']);
477 $this->customGroupDelete($ids['custom_group_id']);
481 * CRM-12773 - expectation is that civicrm quietly ignores fields without values.
483 public function testCreateWithNULLCustomCRM12773() {
484 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__
, __FILE__
);
485 $params = $this->_params
;
486 $params['custom_' . $ids['custom_field_id']] = NULL;
487 $this->callAPISuccess('contact', 'create', $params);
488 $this->customFieldDelete($ids['custom_field_id']);
489 $this->customGroupDelete($ids['custom_group_id']);
493 * CRM-14232 test preferred language set to site default if not passed.
495 public function testCreatePreferredLanguageUnset() {
496 $this->callAPISuccess('Contact', 'create', array(
497 'first_name' => 'Snoop',
498 'last_name' => 'Dog',
499 'contact_type' => 'Individual')
501 $result = $this->callAPISuccessGetSingle('Contact', array('last_name' => 'Dog'));
502 $this->assertEquals('en_US', $result['preferred_language']);
506 * CRM-14232 test preferred language returns setting if not passed.
508 public function testCreatePreferredLanguageSet() {
509 $this->callAPISuccess('Setting', 'create', array('contact_default_language' => 'fr_FR'));
510 $this->callAPISuccess('Contact', 'create', array(
511 'first_name' => 'Snoop',
512 'last_name' => 'Dog',
513 'contact_type' => 'Individual',
515 $result = $this->callAPISuccessGetSingle('Contact', array('last_name' => 'Dog'));
516 $this->assertEquals('fr_FR', $result['preferred_language']);
520 * CRM-14232 test preferred language returns setting if not passed where setting is NULL.
522 public function testCreatePreferredLanguageNull() {
523 $this->callAPISuccess('Setting', 'create', array('contact_default_language' => 'null'));
524 $this->callAPISuccess('Contact', 'create', array(
525 'first_name' => 'Snoop',
526 'last_name' => 'Dog',
527 'contact_type' => 'Individual',
530 $result = $this->callAPISuccessGetSingle('Contact', array('last_name' => 'Dog'));
531 $this->assertEquals(NULL, $result['preferred_language']);
535 * CRM-14232 test preferred language returns setting if not passed where setting is NULL.
537 public function testCreatePreferredLanguagePassed() {
538 $this->callAPISuccess('Setting', 'create', array('contact_default_language' => 'null'));
539 $this->callAPISuccess('Contact', 'create', array(
540 'first_name' => 'Snoop',
541 'last_name' => 'Dog',
542 'contact_type' => 'Individual',
543 'preferred_language' => 'en_AU',
545 $result = $this->callAPISuccessGetSingle('Contact', array('last_name' => 'Dog'));
546 $this->assertEquals('en_AU', $result['preferred_language']);
550 * CRM-15792 - create/update datetime field for contact.
552 public function testCreateContactCustomFldDateTime() {
553 $customGroup = $this->customGroupCreate(array('extends' => 'Individual', 'title' => 'datetime_test_group'));
554 $dateTime = CRM_Utils_Date
::currentDBDate();
555 //check date custom field is saved along with time when time_format is set
557 'first_name' => 'abc3',
558 'last_name' => 'xyz3',
559 'contact_type' => 'Individual',
560 'email' => 'man3@yahoo.com',
561 'api.CustomField.create' => array(
562 'custom_group_id' => $customGroup['id'],
563 'name' => 'test_datetime',
564 'label' => 'Demo Date',
565 'html_type' => 'Select Date',
566 'data_type' => 'Date',
570 'is_searchable' => 0,
575 $result = $this->callAPISuccess('Contact', 'create', $params);
576 $customFldId = $result['values'][$result['id']]['api.CustomField.create']['id'];
577 $this->assertNotNull($result['id']);
578 $this->assertNotNull($customFldId);
581 'id' => $result['id'],
582 "custom_{$customFldId}" => $dateTime,
583 'api.CustomValue.get' => 1,
586 $result = $this->callAPISuccess('Contact', 'create', $params);
587 $this->assertNotNull($result['id']);
588 $customFldDate = date("YmdHis", strtotime($result['values'][$result['id']]['api.CustomValue.get']['values'][0]['latest']));
589 $this->assertNotNull($customFldDate);
590 $this->assertEquals($dateTime, $customFldDate);
591 $customValueId = $result['values'][$result['id']]['api.CustomValue.get']['values'][0]['id'];
592 $dateTime = date('Ymd');
593 //date custom field should not contain time part when time_format is null
595 'id' => $result['id'],
596 'api.CustomField.create' => array(
597 'id' => $customFldId,
598 'html_type' => 'Select Date',
599 'data_type' => 'Date',
602 'api.CustomValue.create' => array(
603 'id' => $customValueId,
604 'entity_id' => $result['id'],
605 "custom_{$customFldId}" => $dateTime,
607 'api.CustomValue.get' => 1,
609 $result = $this->callAPISuccess('Contact', 'create', $params);
610 $this->assertNotNull($result['id']);
611 $customFldDate = date("Ymd", strtotime($result['values'][$result['id']]['api.CustomValue.get']['values'][0]['latest']));
612 $customFldTime = date("His", strtotime($result['values'][$result['id']]['api.CustomValue.get']['values'][0]['latest']));
613 $this->assertNotNull($customFldDate);
614 $this->assertEquals($dateTime, $customFldDate);
615 $this->assertEquals(000000, $customFldTime);
616 $this->callAPISuccess('Contact', 'create', $params);
621 * Test creating a current employer through API.
623 public function testContactCreateCurrentEmployer() {
624 // Here we will just do the get for set-up purposes.
625 $count = $this->callAPISuccess('contact', 'getcount', array(
626 'organization_name' => 'new employer org',
627 'contact_type' => 'Organization',
629 $this->assertEquals(0, $count);
630 $employerResult = $this->callAPISuccess('contact', 'create', array_merge($this->_params
, array(
631 'current_employer' => 'new employer org',
634 // do it again as an update to check it doesn't cause an error
635 $employerResult = $this->callAPISuccess('contact', 'create', array_merge($this->_params
, array(
636 'current_employer' => 'new employer org',
637 'id' => $employerResult['id'],
641 $this->callAPISuccess('contact', 'getcount', array(
642 'organization_name' => 'new employer org',
643 'contact_type' => 'Organization',
647 $result = $this->callAPISuccess('contact', 'getsingle', array(
648 'id' => $employerResult['id'],
651 $this->assertEquals('new employer org', $result['current_employer']);
656 * Test creating a current employer through API.
658 * Check it will re-activate a de-activated employer
660 public function testContactCreateDuplicateCurrentEmployerEnables() {
661 // Set up - create employer relationship.
662 $employerResult = $this->callAPISuccess('contact', 'create', array_merge($this->_params
, array(
663 'current_employer' => 'new employer org',
666 $relationship = $this->callAPISuccess('relationship', 'get', array(
667 'contact_id_a' => $employerResult['id'],
670 //disable & check it is disabled
671 $this->callAPISuccess('relationship', 'create', array('id' => $relationship['id'], 'is_active' => 0));
672 $this->callAPISuccess('relationship', 'getvalue', array(
673 'id' => $relationship['id'],
674 'return' => 'is_active',
677 // Re-set the current employer - thus enabling the relationship.
678 $this->callAPISuccess('contact', 'create', array_merge($this->_params
, array(
679 'current_employer' => 'new employer org',
680 'id' => $employerResult['id'],
683 //check is_active is now 1
684 $relationship = $this->callAPISuccess('relationship', 'getsingle', array(
685 'return' => 'is_active',
687 $this->assertEquals(1, $relationship['is_active']);
691 * Check deceased contacts are not retrieved.
693 * Note at time of writing the default is to return default. This should possibly be changed & test added.
695 public function testGetDeceasedRetrieved() {
696 $this->callAPISuccess($this->_entity
, 'create', $this->_params
);
697 $c2 = $this->callAPISuccess($this->_entity
, 'create', array(
698 'first_name' => 'bb',
699 'last_name' => 'ccc',
700 'contact_type' => 'Individual',
703 $result = $this->callAPISuccess($this->_entity
, 'get', array('is_deceased' => 0));
704 $this->assertFalse(array_key_exists($c2['id'], $result['values']));
708 * Test that sort works - old syntax.
710 public function testGetSort() {
711 $c1 = $this->callAPISuccess($this->_entity
, 'create', $this->_params
);
712 $c2 = $this->callAPISuccess($this->_entity
, 'create', array(
713 'first_name' => 'bb',
714 'last_name' => 'ccc',
715 'contact_type' => 'Individual',
717 $result = $this->callAPISuccess($this->_entity
, 'get', array(
718 'sort' => 'first_name ASC',
719 'return.first_name' => 1,
722 'contact_type' => 'Individual',
725 $this->assertEquals('abc1', $result['values'][0]['first_name']);
726 $result = $this->callAPISuccess($this->_entity
, 'get', array(
727 'sort' => 'first_name DESC',
728 'return.first_name' => 1,
732 $this->assertEquals('bb', $result['values'][0]['first_name']);
734 $this->callAPISuccess($this->_entity
, 'delete', array('id' => $c1['id']));
735 $this->callAPISuccess($this->_entity
, 'delete', array('id' => $c2['id']));
739 * Test that we can retrieve contacts using array syntax.
741 * I.e 'id' => array('IN' => array('3,4')).
743 public function testGetINIDArray() {
744 $c1 = $this->callAPISuccess($this->_entity
, 'create', $this->_params
);
745 $c2 = $this->callAPISuccess($this->_entity
, 'create', array(
746 'first_name' => 'bb',
747 'last_name' => 'ccc',
748 'contact_type' => 'Individual',
750 $c3 = $this->callAPISuccess($this->_entity
, 'create', array(
751 'first_name' => 'hh',
753 'contact_type' => 'Individual',
755 $result = $this->callAPISuccess($this->_entity
, 'get', array('id' => array('IN' => array($c1['id'], $c3['id']))));
756 $this->assertEquals(2, $result['count']);
757 $this->assertEquals(array($c1['id'], $c3['id']), array_keys($result['values']));
758 $this->callAPISuccess($this->_entity
, 'delete', array('id' => $c1['id']));
759 $this->callAPISuccess($this->_entity
, 'delete', array('id' => $c2['id']));
760 $this->callAPISuccess($this->_entity
, 'delete', array('id' => $c3['id']));
764 * Test variants on deleted behaviour.
766 public function testGetDeleted() {
767 $params = $this->_params
;
768 $contact1 = $this->callAPISuccess('contact', 'create', $params);
769 $params['is_deleted'] = 1;
770 $params['last_name'] = 'bcd';
771 $contact2 = $this->callAPISuccess('contact', 'create', $params);
772 $countActive = $this->callAPISuccess('contact', 'getcount', array(
773 'showAll' => 'active',
774 'contact_type' => 'Individual',
776 $countAll = $this->callAPISuccess('contact', 'getcount', array('showAll' => 'all', 'contact_type' => 'Individual'));
777 $countTrash = $this->callAPISuccess('contact', 'getcount', array('showAll' => 'trash', 'contact_type' => 'Individual'));
778 $countDefault = $this->callAPISuccess('contact', 'getcount', array('contact_type' => 'Individual'));
779 $countDeleted = $this->callAPISuccess('contact', 'getcount', array(
780 'contact_type' => 'Individual',
781 'contact_is_deleted' => 1,
783 $countNotDeleted = $this->callAPISuccess('contact', 'getcount', array(
784 'contact_is_deleted' => 0,
785 'contact_type' => 'Individual',
787 $this->callAPISuccess('contact', 'delete', array('id' => $contact1['id']));
788 $this->callAPISuccess('contact', 'delete', array('id' => $contact2['id']));
789 $this->assertEquals(1, $countNotDeleted, 'contact_is_deleted => 0 is respected');
790 $this->assertEquals(1, $countActive);
791 $this->assertEquals(1, $countTrash);
792 $this->assertEquals(2, $countAll);
793 $this->assertEquals(1, $countDeleted);
794 $this->assertEquals(1, $countDefault, 'Only active by default in line');
798 * Test that sort works - new syntax.
800 public function testGetSortNewSyntax() {
801 $c1 = $this->callAPISuccess($this->_entity
, 'create', $this->_params
);
802 $c2 = $this->callAPISuccess($this->_entity
, 'create', array(
803 'first_name' => 'bb',
804 'last_name' => 'ccc',
805 'contact_type' => 'Individual',
807 $result = $this->callAPISuccess($this->_entity
, 'getvalue', array(
808 'return' => 'first_name',
809 'contact_type' => 'Individual',
812 'sort' => 'first_name',
815 $this->assertEquals('abc1', $result);
817 $result = $this->callAPISuccess($this->_entity
, 'getvalue', array(
818 'return' => 'first_name',
819 'contact_type' => 'Individual',
822 'sort' => 'first_name DESC',
825 $this->assertEquals('bb', $result);
827 $this->callAPISuccess($this->_entity
, 'delete', array('id' => $c1['id']));
828 $this->callAPISuccess($this->_entity
, 'delete', array('id' => $c2['id']));
832 * Test sort and limit for chained relationship get.
834 * https://issues.civicrm.org/jira/browse/CRM-15983
836 public function testSortLimitChainedRelationshipGetCRM15983() {
838 $create_result_1 = $this->callAPISuccess('contact', 'create', array(
839 'first_name' => 'Jules',
840 'last_name' => 'Smos',
841 'contact_type' => 'Individual',
844 // Create another contact with two relationships.
845 $create_params = array(
846 'first_name' => 'Jos',
847 'last_name' => 'Smos',
848 'contact_type' => 'Individual',
849 'api.relationship.create' => array(
851 'contact_id_a' => '$value.id',
852 'contact_id_b' => $create_result_1['id'],
854 'relationship_type_id' => 2,
855 'start_date' => '2005-01-12',
856 'end_date' => '2006-01-11',
857 'description' => 'old',
860 'contact_id_a' => '$value.id',
861 'contact_id_b' => $create_result_1['id'],
862 // spouse of (was married twice :))
863 'relationship_type_id' => 2,
864 'start_date' => '2006-07-01',
865 'end_date' => '2010-07-01',
866 'description' => 'new',
870 $create_result = $this->callAPISuccess('contact', 'create', $create_params);
872 // Try to retrieve the contact and the most recent relationship.
875 'id' => $create_result['id'],
876 'api.relationship.get' => array(
877 'contact_id_a' => '$value.id',
880 'sort' => 'start_date DESC',
883 $get_result = $this->callAPISuccess('contact', 'getsingle', $get_params);
886 $this->callAPISuccess('contact', 'delete', array(
887 'id' => $create_result['id'],
891 $this->assertEquals(1, $get_result['api.relationship.get']['count']);
892 $this->assertEquals('new', $get_result['api.relationship.get']['values'][0]['description']);
896 * Test apostrophe works in get & create.
898 public function testGetApostropheCRM10857() {
899 $params = array_merge($this->_params
, array('last_name' => "O'Connor"));
900 $this->callAPISuccess($this->_entity
, 'create', $params);
901 $result = $this->callAPISuccess($this->_entity
, 'getsingle', array(
902 'last_name' => "O'Connor",
905 $this->assertEquals("O'Connor", $result['last_name'], 'in line' . __LINE__
);
909 * Check with complete array + custom field.
911 * Note that the test is written on purpose without any
912 * variables specific to participant so it can be replicated into other entities
913 * and / or moved to the automated test suite
915 public function testGetWithCustom() {
916 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__
, __FILE__
);
918 $params = $this->_params
;
919 $params['custom_' . $ids['custom_field_id']] = "custom string";
920 $description = "This demonstrates setting a custom field through the API.";
921 $subfile = "CustomFieldGet";
922 $result = $this->callAPISuccess($this->_entity
, 'create', $params);
924 $check = $this->callAPIAndDocument($this->_entity
, 'get', array(
925 'return.custom_' . $ids['custom_field_id'] => 1,
926 'id' => $result['id'],
927 ), __FUNCTION__
, __FILE__
, $description, $subfile);
929 $this->assertEquals("custom string", $check['values'][$check['id']]['custom_' . $ids['custom_field_id']]);
930 $fields = ($this->callAPISuccess('contact', 'getfields', $params));
931 $this->assertTrue(is_array($fields['values']['custom_' . $ids['custom_field_id']]));
932 $this->customFieldDelete($ids['custom_field_id']);
933 $this->customGroupDelete($ids['custom_group_id']);
937 * Check with complete array + custom field.
939 * Note that the test is written on purpose without any
940 * variables specific to participant so it can be replicated into other entities
941 * and / or moved to the automated test suite
943 public function testGetWithCustomReturnSyntax() {
944 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__
, __FILE__
);
946 $params = $this->_params
;
947 $params['custom_' . $ids['custom_field_id']] = "custom string";
948 $description = "This demonstrates setting a custom field through the API.";
949 $subfile = "CustomFieldGetReturnSyntaxVariation";
950 $result = $this->callAPISuccess($this->_entity
, 'create', $params);
951 $params = array('return' => 'custom_' . $ids['custom_field_id'], 'id' => $result['id']);
952 $check = $this->callAPIAndDocument($this->_entity
, 'get', $params, __FUNCTION__
, __FILE__
, $description, $subfile);
954 $this->assertEquals("custom string", $check['values'][$check['id']]['custom_' . $ids['custom_field_id']]);
955 $this->customFieldDelete($ids['custom_field_id']);
956 $this->customGroupDelete($ids['custom_group_id']);
960 * Check that address name, ID is returned if required.
962 public function testGetReturnAddress() {
963 $contactID = $this->individualCreate();
964 $result = $this->callAPISuccess('address', 'create', array(
965 'contact_id' => $contactID,
966 'address_name' => 'My house',
967 'location_type_id' => 'Home',
968 'street_address' => '1 my road',
970 $addressID = $result['id'];
972 $result = $this->callAPISuccessGetSingle('contact', array(
973 'return' => 'address_name, street_address, address_id',
976 $this->assertEquals($addressID, $result['address_id']);
977 $this->assertEquals('1 my road', $result['street_address']);
978 $this->assertEquals('My house', $result['address_name']);
983 * Test group filter syntaxes.
985 public function testGetGroupIDFromContact() {
986 $groupId = $this->groupCreate();
988 'email' => 'man2@yahoo.com',
989 'contact_type' => 'Individual',
990 'location_type_id' => 1,
991 'api.group_contact.create' => array('group_id' => $groupId),
994 $this->callAPISuccess('contact', 'create', $params);
995 // testing as integer
997 'filter.group_id' => $groupId,
998 'contact_type' => 'Individual',
1000 $result = $this->callAPISuccess('contact', 'get', $params);
1001 $this->assertEquals(1, $result['count']);
1002 // group 26 doesn't exist, but we can still search contacts in it.
1004 'filter.group_id' => 26,
1005 'contact_type' => 'Individual',
1007 $this->callAPISuccess('contact', 'get', $params);
1008 // testing as string
1010 'filter.group_id' => "$groupId, 26",
1011 'contact_type' => 'Individual',
1013 $result = $this->callAPISuccess('contact', 'get', $params);
1014 $this->assertEquals(1, $result['count']);
1016 'filter.group_id' => "26,27",
1017 'contact_type' => 'Individual',
1019 $this->callAPISuccess('contact', 'get', $params);
1021 // testing as string
1023 'filter.group_id' => array($groupId, 26),
1024 'contact_type' => 'Individual',
1026 $result = $this->callAPISuccess('contact', 'get', $params);
1027 $this->assertEquals(1, $result['count']);
1029 //test in conjunction with other criteria
1031 'filter.group_id' => array($groupId, 26),
1032 'contact_type' => 'Organization',
1034 $this->callAPISuccess('contact', 'get', $params);
1036 'filter.group_id' => array(26, 27),
1037 'contact_type' => 'Individual',
1039 $result = $this->callAPISuccess('contact', 'get', $params);
1040 $this->assertEquals(0, $result['count']);
1044 * Verify that attempt to create individual contact with two chained websites succeeds.
1046 public function testCreateIndividualWithContributionDottedSyntax() {
1047 $description = "This demonstrates the syntax to create 2 chained entities.";
1048 $subFile = "ChainTwoWebsites";
1050 'first_name' => 'abc3',
1051 'last_name' => 'xyz3',
1052 'contact_type' => 'Individual',
1053 'email' => 'man3@yahoo.com',
1054 'api.contribution.create' => array(
1055 'receive_date' => '2010-01-01',
1056 'total_amount' => 100.00,
1057 'financial_type_id' => $this->_financialTypeId
,
1058 'payment_instrument_id' => 1,
1059 'non_deductible_amount' => 10.00,
1060 'fee_amount' => 50.00,
1061 'net_amount' => 90.00,
1063 'invoice_id' => 67990,
1065 'contribution_status_id' => 1,
1067 'api.website.create' => array(
1068 'url' => "http://civicrm.org",
1070 'api.website.create.2' => array(
1071 'url' => "http://chained.org",
1075 $result = $this->callAPIAndDocument('Contact', 'create', $params, __FUNCTION__
, __FILE__
, $description, $subFile);
1077 // checking child function result not covered in callAPIAndDocument
1078 $this->assertAPISuccess($result['values'][$result['id']]['api.website.create']);
1079 $this->assertEquals("http://chained.org", $result['values'][$result['id']]['api.website.create.2']['values'][0]['url']);
1080 $this->assertEquals("http://civicrm.org", $result['values'][$result['id']]['api.website.create']['values'][0]['url']);
1082 // delete the contact
1083 $this->callAPISuccess('contact', 'delete', $result);
1087 * Verify that attempt to create individual contact with chained contribution and website succeeds.
1089 public function testCreateIndividualWithContributionChainedArrays() {
1091 'first_name' => 'abc3',
1092 'last_name' => 'xyz3',
1093 'contact_type' => 'Individual',
1094 'email' => 'man3@yahoo.com',
1095 'api.contribution.create' => array(
1096 'receive_date' => '2010-01-01',
1097 'total_amount' => 100.00,
1098 'financial_type_id' => $this->_financialTypeId
,
1099 'payment_instrument_id' => 1,
1100 'non_deductible_amount' => 10.00,
1101 'fee_amount' => 50.00,
1102 'net_amount' => 90.00,
1104 'invoice_id' => 67890,
1106 'contribution_status_id' => 1,
1108 'api.website.create' => array(
1110 'url' => "http://civicrm.org",
1113 'url' => "http://chained.org",
1114 'website_type_id' => 2,
1119 $description = "Demonstrates creating two websites as an array.";
1120 $subfile = "ChainTwoWebsitesSyntax2";
1121 $result = $this->callAPIAndDocument('Contact', 'create', $params, __FUNCTION__
, __FILE__
, $description, $subfile);
1123 // the callAndDocument doesn't check the chained call
1124 $this->assertEquals(0, $result['values'][$result['id']]['api.website.create'][0]['is_error']);
1125 $this->assertEquals("http://chained.org", $result['values'][$result['id']]['api.website.create'][1]['values'][0]['url']);
1126 $this->assertEquals("http://civicrm.org", $result['values'][$result['id']]['api.website.create'][0]['values'][0]['url']);
1128 $this->callAPISuccess('contact', 'delete', $result);
1132 * Test for direction when chaining relationships.
1134 * https://issues.civicrm.org/jira/browse/CRM-16084
1136 public function testDirectionChainingRelationshipsCRM16084() {
1137 // Some contact, called Jules.
1138 $create_result_1 = $this->callAPISuccess('contact', 'create', array(
1139 'first_name' => 'Jules',
1140 'last_name' => 'Smos',
1141 'contact_type' => 'Individual',
1144 // Another contact: Jos, child of Jules.
1145 $create_params = array(
1146 'first_name' => 'Jos',
1147 'last_name' => 'Smos',
1148 'contact_type' => 'Individual',
1149 'api.relationship.create' => array(
1151 'contact_id_a' => '$value.id',
1152 'contact_id_b' => $create_result_1['id'],
1154 'relationship_type_id' => 1,
1158 $create_result_2 = $this->callAPISuccess('contact', 'create', $create_params);
1160 // Mia is the child of Jos.
1161 $create_params = array(
1162 'first_name' => 'Mia',
1163 'last_name' => 'Smos',
1164 'contact_type' => 'Individual',
1165 'api.relationship.create' => array(
1167 'contact_id_a' => '$value.id',
1168 'contact_id_b' => $create_result_2['id'],
1170 'relationship_type_id' => 1,
1174 $create_result_3 = $this->callAPISuccess('contact', 'create', $create_params);
1176 // Get Jos and his children.
1177 $get_params = array(
1179 'id' => $create_result_2['id'],
1180 'api.relationship.get' => array(
1181 'contact_id_b' => '$value.id',
1182 'relationship_type_id' => 1,
1185 $get_result = $this->callAPISuccess('contact', 'getsingle', $get_params);
1188 $this->callAPISuccess('contact', 'delete', array(
1189 'id' => $create_result_1['id'],
1191 $this->callAPISuccess('contact', 'delete', array(
1192 'id' => $create_result_2['id'],
1194 $this->callAPISuccess('contact', 'delete', array(
1195 'id' => $create_result_2['id'],
1199 $this->assertEquals(1, $get_result['api.relationship.get']['count']);
1200 $this->assertEquals($create_result_3['id'], $get_result['api.relationship.get']['values'][0]['contact_id_a']);
1204 * Verify that attempt to create individual contact with first, and last names and email succeeds.
1206 public function testCreateIndividualWithNameEmail() {
1208 'first_name' => 'abc3',
1209 'last_name' => 'xyz3',
1210 'contact_type' => 'Individual',
1211 'email' => 'man3@yahoo.com',
1214 $contact = $this->callAPISuccess('contact', 'create', $params);
1216 $this->callAPISuccess('contact', 'delete', $contact);
1220 * Verify that attempt to create individual contact with no data fails.
1222 public function testCreateIndividualWithOutNameEmail() {
1224 'contact_type' => 'Individual',
1226 $this->callAPIFailure('contact', 'create', $params);
1230 * Test create individual contact with first &last names, email and location type succeeds.
1232 public function testCreateIndividualWithNameEmailLocationType() {
1234 'first_name' => 'abc4',
1235 'last_name' => 'xyz4',
1236 'email' => 'man4@yahoo.com',
1237 'contact_type' => 'Individual',
1238 'location_type_id' => 1,
1240 $result = $this->callAPISuccess('contact', 'create', $params);
1242 $this->callAPISuccess('contact', 'delete', array('id' => $result['id']));
1246 * Verify that when changing employers the old employer relationship becomes inactive.
1248 public function testCreateIndividualWithEmployer() {
1249 $employer = $this->organizationCreate();
1250 $employer2 = $this->organizationCreate();
1253 'email' => 'man4@yahoo.com',
1254 'contact_type' => 'Individual',
1255 'employer_id' => $employer,
1258 $result = $this->callAPISuccess('contact', 'create', $params);
1259 $relationships = $this->callAPISuccess('relationship', 'get', array(
1260 'contact_id_a' => $result['id'],
1264 $this->assertEquals($employer, $relationships['values'][0]['contact_id_b']);
1266 // Add more random relationships to make the test more realistic
1267 foreach (array('Employee of', 'Volunteer for') as $relationshipType) {
1268 $relTypeId = CRM_Core_DAO
::getFieldValue('CRM_Contact_DAO_RelationshipType', $relationshipType, 'id', 'name_a_b');
1269 $this->callAPISuccess('relationship', 'create', array(
1270 'contact_id_a' => $result['id'],
1271 'contact_id_b' => $this->organizationCreate(),
1273 'relationship_type_id' => $relTypeId,
1277 // Add second employer
1278 $params['employer_id'] = $employer2;
1279 $params['id'] = $result['id'];
1280 $result = $this->callAPISuccess('contact', 'create', $params);
1282 $relationships = $this->callAPISuccess('relationship', 'get', array(
1283 'contact_id_a' => $result['id'],
1288 $this->assertEquals($employer, $relationships['values'][0]['contact_id_b']);
1292 * Verify that attempt to create household contact with details succeeds.
1294 public function testCreateHouseholdDetails() {
1296 'household_name' => 'abc8\'s House',
1297 'nick_name' => 'x House',
1298 'email' => 'man8@yahoo.com',
1299 'contact_type' => 'Household',
1302 $contact = $this->callAPISuccess('contact', 'create', $params);
1304 $this->callAPISuccess('contact', 'delete', $contact);
1308 * Verify that attempt to create household contact with inadequate details fails.
1310 public function testCreateHouseholdInadequateDetails() {
1312 'nick_name' => 'x House',
1313 'email' => 'man8@yahoo.com',
1314 'contact_type' => 'Household',
1316 $this->callAPIFailure('contact', 'create', $params);
1320 * Verify successful update of individual contact.
1322 public function testUpdateIndividualWithAll() {
1323 // Insert a row in civicrm_contact creating individual contact.
1324 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1325 $op->execute($this->_dbconn
,
1326 $this->createXMLDataSet(
1327 dirname(__FILE__
) . '/dataset/contact_ind.xml'
1333 'first_name' => 'abcd',
1334 'contact_type' => 'Individual',
1335 'nick_name' => 'This is nickname first',
1336 'do_not_email' => '1',
1337 'do_not_phone' => '1',
1338 'do_not_mail' => '1',
1339 'do_not_trade' => '1',
1340 'legal_identifier' => 'ABC23853ZZ2235',
1341 'external_identifier' => '1928837465',
1342 'image_URL' => 'http://some.url.com/image.jpg',
1343 'home_url' => 'http://www.example.org',
1347 $this->callAPISuccess('Contact', 'Update', $params);
1348 $getResult = $this->callAPISuccess('Contact', 'Get', $params);
1349 unset($params['contact_id']);
1350 //Todo - neither API v2 or V3 are testing for home_url - not sure if it is being set.
1351 //reducing this test partially back to api v2 level to get it through
1352 unset($params['home_url']);
1353 foreach ($params as $key => $value) {
1354 $this->assertEquals($value, $getResult['values'][23][$key]);
1356 // Check updated civicrm_contact against expected.
1357 $expected = $this->createXMLDataSet(
1358 dirname(__FILE__
) . '/dataset/contact_ind_upd.xml'
1360 $actual = new PHPUnit_Extensions_Database_DataSet_QueryDataSet(
1363 $actual->addTable('civicrm_contact');
1364 $expected->matches($actual);
1368 * Verify successful update of organization contact.
1370 public function testUpdateOrganizationWithAll() {
1371 // Insert a row in civicrm_contact creating organization contact
1372 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1373 $op->execute($this->_dbconn
,
1374 $this->createXMLDataSet(
1375 dirname(__FILE__
) . '/dataset/contact_org.xml'
1381 'organization_name' => 'WebAccess India Pvt Ltd',
1382 'legal_name' => 'WebAccess',
1383 'sic_code' => 'ABC12DEF',
1384 'contact_type' => 'Organization',
1387 $this->callAPISuccess('Contact', 'Update', $params);
1389 // Check updated civicrm_contact against expected.
1390 $expected = $this->createXMLDataSet(
1391 dirname(__FILE__
) . '/dataset/contact_org_upd.xml'
1393 $actual = new PHPUnit_Extensions_Database_DataSet_QueryDataSet(
1396 $actual->addTable('civicrm_contact');
1397 $expected->matches($actual);
1401 * Verify successful update of household contact.
1403 public function testUpdateHouseholdWithAll() {
1404 // Insert a row in civicrm_contact creating household contact
1405 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1406 $op->execute($this->_dbconn
,
1407 $this->createXMLDataSet(
1408 dirname(__FILE__
) . '/dataset/contact_hld.xml'
1414 'household_name' => 'ABC household',
1415 'nick_name' => 'ABC House',
1416 'contact_type' => 'Household',
1419 $result = $this->callAPISuccess('Contact', 'Update', $params);
1422 'contact_type' => 'Household',
1424 'sort_name' => 'ABC household',
1425 'display_name' => 'ABC household',
1426 'nick_name' => 'ABC House',
1428 $this->getAndCheck($expected, $result['id'], 'contact');
1432 * Test civicrm_update() without contact type.
1434 * Deliberately exclude contact_type as it should still cope using civicrm_api.
1438 public function testUpdateCreateWithID() {
1439 // Insert a row in civicrm_contact creating individual contact.
1440 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1441 $op->execute($this->_dbconn
,
1442 $this->createXMLDataSet(
1443 dirname(__FILE__
) . '/dataset/contact_ind.xml'
1449 'first_name' => 'abcd',
1450 'last_name' => 'wxyz',
1452 $this->callAPISuccess('Contact', 'Update', $params);
1456 * Test civicrm_contact_delete() with no contact ID.
1458 public function testContactDeleteNoID() {
1462 $this->callAPIFailure('contact', 'delete', $params);
1466 * Test civicrm_contact_delete() with error.
1468 public function testContactDeleteError() {
1469 $params = array('contact_id' => 999);
1470 $this->callAPIFailure('contact', 'delete', $params);
1474 * Test civicrm_contact_delete().
1476 public function testContactDelete() {
1477 $contactID = $this->individualCreate();
1481 $this->callAPIAndDocument('contact', 'delete', $params, __FUNCTION__
, __FILE__
);
1485 * Test civicrm_contact_get() return only first name.
1487 public function testContactGetRetFirst() {
1488 $contact = $this->callAPISuccess('contact', 'create', $this->_params
);
1490 'contact_id' => $contact['id'],
1491 'return_first_name' => TRUE,
1492 'sort' => 'first_name',
1494 $result = $this->callAPISuccess('contact', 'get', $params);
1495 $this->assertEquals(1, $result['count']);
1496 $this->assertEquals($contact['id'], $result['id']);
1497 $this->assertEquals('abc1', $result['values'][$contact['id']]['first_name']);
1501 * Test civicrm_contact_get() return only first name & last name.
1503 * Use comma separated string return with a space.
1505 public function testContactGetReturnFirstLast() {
1506 $contact = $this->callAPISuccess('contact', 'create', $this->_params
);
1508 'contact_id' => $contact['id'],
1509 'return' => 'first_name, last_name',
1511 $result = $this->callAPISuccess('contact', 'getsingle', $params);
1512 $this->assertEquals('abc1', $result['first_name']);
1513 $this->assertEquals('xyz1', $result['last_name']);
1514 //check that other defaults not returns
1515 $this->assertArrayNotHasKey('sort_name', $result);
1517 'contact_id' => $contact['id'],
1518 'return' => 'first_name,last_name',
1520 $result = $this->callAPISuccess('contact', 'getsingle', $params);
1521 $this->assertEquals('abc1', $result['first_name']);
1522 $this->assertEquals('xyz1', $result['last_name']);
1523 //check that other defaults not returns
1524 $this->assertArrayNotHasKey('sort_name', $result);
1528 * Test civicrm_contact_get() return only first name & last name.
1530 * Use comma separated string return without a space
1532 public function testContactGetReturnFirstLastNoComma() {
1533 $contact = $this->callAPISuccess('contact', 'create', $this->_params
);
1535 'contact_id' => $contact['id'],
1536 'return' => 'first_name,last_name',
1538 $result = $this->callAPISuccess('contact', 'getsingle', $params);
1539 $this->assertEquals('abc1', $result['first_name']);
1540 $this->assertEquals('xyz1', $result['last_name']);
1541 //check that other defaults not returns
1542 $this->assertArrayNotHasKey('sort_name', $result);
1546 * Test civicrm_contact_get() with default return properties.
1548 public function testContactGetRetDefault() {
1549 $contactID = $this->individualCreate();
1551 'contact_id' => $contactID,
1552 'sort' => 'first_name',
1554 $result = $this->callAPISuccess('contact', 'get', $params);
1555 $this->assertEquals($contactID, $result['values'][$contactID]['contact_id']);
1556 $this->assertEquals('Anthony', $result['values'][$contactID]['first_name']);
1560 * Test civicrm_contact_getquick() with empty name param.
1562 public function testContactGetQuick() {
1563 // Insert a row in civicrm_contact creating individual contact.
1564 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1565 $op->execute($this->_dbconn
,
1566 $this->createXMLDataSet(
1567 dirname(__FILE__
) . '/dataset/contact_17.xml'
1570 $op->execute($this->_dbconn
,
1571 $this->createXMLDataSet(
1572 dirname(__FILE__
) . '/dataset/email_contact_17.xml'
1579 $result = $this->callAPISuccess('contact', 'getquick', $params);
1580 $this->assertEquals(17, $result['values'][0]['id']);
1584 * Test civicrm_contact_get) with empty params.
1586 public function testContactGetEmptyParams() {
1587 $this->callAPISuccess('contact', 'get', array());
1591 * Test civicrm_contact_get(,true) with no matches.
1593 public function testContactGetOldParamsNoMatches() {
1594 // Insert a row in civicrm_contact creating contact 17.
1595 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1596 $op->execute($this->_dbconn
,
1597 $this->createXMLDataSet(
1598 dirname(__FILE__
) . '/dataset/contact_17.xml'
1603 'first_name' => 'Fred',
1605 $result = $this->callAPISuccess('contact', 'get', $params);
1606 $this->assertEquals(0, $result['count']);
1610 * Test civicrm_contact_get(,true) with one match.
1612 public function testContactGetOldParamsOneMatch() {
1613 // Insert a row in civicrm_contact creating contact 17
1614 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1615 $op->execute($this->_dbconn
,
1616 $this->createXMLDataSet(dirname(__FILE__
) . '/dataset/contact_17.xml'
1621 'first_name' => 'Test',
1623 $result = $this->callAPISuccess('contact', 'get', $params);
1624 $this->assertEquals(17, $result['values'][17]['contact_id']);
1625 $this->assertEquals(17, $result['id']);
1629 * Test civicrm_contact_search_count().
1631 public function testContactGetEmail() {
1633 'email' => 'man2@yahoo.com',
1634 'contact_type' => 'Individual',
1635 'location_type_id' => 1,
1638 $contact = $this->callAPISuccess('contact', 'create', $params);
1641 'email' => 'man2@yahoo.com',
1643 $result = $this->callAPIAndDocument('contact', 'get', $params, __FUNCTION__
, __FILE__
);
1644 $this->assertEquals('man2@yahoo.com', $result['values'][$result['id']]['email']);
1646 $this->callAPISuccess('contact', 'delete', $contact);
1650 * Test birth date parameters.
1652 * These include value, array & birth_date_high, birth_date_low
1655 public function testContactGetBirthDate() {
1656 $contact1 = $this->callAPISuccess('contact', 'create', array_merge($this->_params
, array('birth_date' => 'first day of next month - 2 years')));
1657 $contact2 = $this->callAPISuccess('contact', 'create', array_merge($this->_params
, array('birth_date' => 'first day of next month - 5 years')));
1658 $contact3 = $this->callAPISuccess('contact', 'create', array_merge($this->_params
, array('birth_date' => 'first day of next month -20 years')));
1660 $result = $this->callAPISuccess('contact', 'get', array());
1661 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -2 years')), $result['values'][$contact1['id']]['birth_date']);
1662 $result = $this->callAPISuccess('contact', 'get', array('birth_date' => 'first day of next month -5 years'));
1663 $this->assertEquals(1, $result['count']);
1664 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -5 years')), $result['values'][$contact2['id']]['birth_date']);
1665 $result = $this->callAPISuccess('contact', 'get', array('birth_date_high' => date('Y-m-d', strtotime('-6 years'))));
1666 $this->assertEquals(1, $result['count']);
1667 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -20 years')), $result['values'][$contact3['id']]['birth_date']);
1668 $result = $this->callAPISuccess('contact', 'get', array(
1669 'birth_date_low' => date('Y-m-d', strtotime('-6 years')),
1670 'birth_date_high' => date('Y-m-d', strtotime('- 3 years')),
1672 $this->assertEquals(1, $result['count']);
1673 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -5 years')), $result['values'][$contact2['id']]['birth_date']);
1674 $result = $this->callAPISuccess('contact', 'get', array(
1675 'birth_date_low' => '-6 years',
1676 'birth_date_high' => '- 3 years',
1678 $this->assertEquals(1, $result['count']);
1679 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -5 years')), $result['values'][$contact2['id']]['birth_date']);
1683 * Test Address parameters
1685 * This include state_province, state_province_name, country
1687 public function testContactGetWithAddressFields() {
1688 $individuals = array(
1690 'first_name' => 'abc1',
1691 'contact_type' => 'Individual',
1692 'last_name' => 'xyz1',
1693 'api.address.create' => array(
1694 'country' => 'United States',
1695 'state_province_id' => 'Michigan',
1696 'location_type_id' => 1,
1700 'first_name' => 'abc2',
1701 'contact_type' => 'Individual',
1702 'last_name' => 'xyz2',
1703 'api.address.create' => array(
1704 'country' => 'United States',
1705 'state_province_id' => 'Alabama',
1706 'location_type_id' => 1,
1710 foreach ($individuals as $params) {
1711 $contact = $this->callAPISuccess('contact', 'create', $params);
1714 // Check whether Contact get API return successfully with below Address params.
1715 $fieldsToTest = array(
1716 'state_province_name' => 'Michigan',
1717 'state_province' => 'Michigan',
1718 'country' => 'United States',
1719 'state_province_name' => array('IN' => array('Michigan', 'Alabama')),
1720 'state_province' => array('IN' => array('Michigan', 'Alabama')),
1722 foreach ($fieldsToTest as $field => $value) {
1724 'id' => $contact['id'],
1727 $result = $this->callAPISuccess('Contact', 'get', $getParams);
1728 $this->assertEquals(1, $result['count']);
1733 * Test Deceased date parameters.
1735 * These include value, array & Deceased_date_high, Deceased date_low
1738 public function testContactGetDeceasedDate() {
1739 $contact1 = $this->callAPISuccess('contact', 'create', array_merge($this->_params
, array('deceased_date' => 'first day of next month - 2 years')));
1740 $contact2 = $this->callAPISuccess('contact', 'create', array_merge($this->_params
, array('deceased_date' => 'first day of next month - 5 years')));
1741 $contact3 = $this->callAPISuccess('contact', 'create', array_merge($this->_params
, array('deceased_date' => 'first day of next month -20 years')));
1743 $result = $this->callAPISuccess('contact', 'get', array());
1744 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -2 years')), $result['values'][$contact1['id']]['deceased_date']);
1745 $result = $this->callAPISuccess('contact', 'get', array('deceased_date' => 'first day of next month -5 years'));
1746 $this->assertEquals(1, $result['count']);
1747 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -5 years')), $result['values'][$contact2['id']]['deceased_date']);
1748 $result = $this->callAPISuccess('contact', 'get', array('deceased_date_high' => date('Y-m-d', strtotime('-6 years'))));
1749 $this->assertEquals(1, $result['count']);
1750 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -20 years')), $result['values'][$contact3['id']]['deceased_date']);
1751 $result = $this->callAPISuccess('contact', 'get', array(
1752 'deceased_date_low' => '-6 years',
1753 'deceased_date_high' => date('Y-m-d', strtotime('- 3 years')),
1755 $this->assertEquals(1, $result['count']);
1756 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -5 years')), $result['values'][$contact2['id']]['deceased_date']);
1760 * Test for Contact.get id=@user:username.
1762 public function testContactGetByUsername() {
1763 // Setup - create contact with a uf-match.
1764 $cid = $this->individualCreate(array(
1765 'contact_type' => 'Individual',
1766 'first_name' => 'testGetByUsername',
1767 'last_name' => 'testGetByUsername',
1770 $ufMatchParams = array(
1771 'domain_id' => CRM_Core_Config
::domainID(),
1773 'uf_name' => 'the-email-matching-key-is-not-really-the-username',
1774 'contact_id' => $cid,
1776 $ufMatch = CRM_Core_BAO_UFMatch
::create($ufMatchParams);
1777 $this->assertTrue(is_numeric($ufMatch->id
));
1779 // setup - mock the calls to CRM_Utils_System_*::getUfId
1780 $userSystem = $this->getMock('CRM_Utils_System_UnitTests', array('getUfId'));
1781 $userSystem->expects($this->once())
1783 ->with($this->equalTo('exampleUser'))
1784 ->will($this->returnValue(99));
1785 CRM_Core_Config
::singleton()->userSystem
= $userSystem;
1788 $result = $this->callAPISuccess('Contact', 'get', array(
1789 'id' => '@user:exampleUser',
1791 $this->assertEquals('testGetByUsername', $result['values'][$cid]['first_name']);
1795 * Test to check return works OK.
1797 public function testContactGetReturnValues() {
1798 $extraParams = array(
1799 'nick_name' => 'Bob',
1801 'email' => 'e@mail.com',
1803 $contactID = $this->individualCreate($extraParams);
1804 //actually it turns out the above doesn't create a phone
1805 $this->callAPISuccess('phone', 'create', array('contact_id' => $contactID, 'phone' => '456'));
1806 $result = $this->callAPISuccess('contact', 'getsingle', array('id' => $contactID));
1807 foreach ($extraParams as $key => $value) {
1808 $this->assertEquals($result[$key], $value);
1810 //now we check they are still returned with 'return' key
1811 $result = $this->callAPISuccess('contact', 'getsingle', array(
1813 'return' => array_keys($extraParams),
1815 foreach ($extraParams as $key => $value) {
1816 $this->assertEquals($result[$key], $value);
1821 * Test creating multiple phones using chaining.
1823 * @throws \Exception
1825 public function testCRM13252MultipleChainedPhones() {
1826 $contactID = $this->householdCreate();
1827 $this->callAPISuccessGetCount('phone', array('contact_id' => $contactID), 0);
1829 'contact_id' => $contactID,
1830 'household_name' => 'Household 1',
1831 'contact_type' => 'Household',
1832 'api.phone.create' => array(
1834 'phone' => '111-111-1111',
1835 'location_type_id' => 1,
1836 'phone_type_id' => 1,
1839 'phone' => '222-222-2222',
1840 'location_type_id' => 1,
1841 'phone_type_id' => 2,
1845 $this->callAPISuccess('contact', 'create', $params);
1846 $this->callAPISuccessGetCount('phone', array('contact_id' => $contactID), 2);
1851 * Test for Contact.get id=@user:username (with an invalid username).
1853 public function testContactGetByUnknownUsername() {
1854 // setup - mock the calls to CRM_Utils_System_*::getUfId
1855 $userSystem = $this->getMock('CRM_Utils_System_UnitTests', array('getUfId'));
1856 $userSystem->expects($this->once())
1858 ->with($this->equalTo('exampleUser'))
1859 ->will($this->returnValue(NULL));
1860 CRM_Core_Config
::singleton()->userSystem
= $userSystem;
1863 $result = $this->callAPIFailure('Contact', 'get', array(
1864 'id' => '@user:exampleUser',
1866 $this->assertRegExp('/cannot be resolved to a contact ID/', $result['error_message']);
1870 * Verify attempt to create individual with chained arrays and sequential.
1872 public function testGetIndividualWithChainedArraysAndSequential() {
1873 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__
, __FILE__
);
1874 $params['custom_' . $ids['custom_field_id']] = "custom string";
1876 $moreIDs = $this->CustomGroupMultipleCreateWithFields();
1879 'first_name' => 'abc3',
1880 'last_name' => 'xyz3',
1881 'contact_type' => 'Individual',
1882 'email' => 'man3@yahoo.com',
1883 'api.website.create' => array(
1885 'url' => "http://civicrm.org",
1888 'url' => "https://civicrm.org",
1893 $result = $this->callAPISuccess('Contact', 'create', $params);
1895 // delete the contact and custom groups
1896 $this->callAPISuccess('contact', 'delete', array('id' => $result['id']));
1897 $this->customGroupDelete($ids['custom_group_id']);
1898 $this->customGroupDelete($moreIDs['custom_group_id']);
1900 $this->assertEquals($result['id'], $result['values'][0]['id']);
1901 $this->assertArrayKeyExists('api.website.create', $result['values'][0]);
1905 * Verify attempt to create individual with chained arrays.
1907 public function testGetIndividualWithChainedArrays() {
1908 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__
, __FILE__
);
1909 $params['custom_' . $ids['custom_field_id']] = "custom string";
1911 $moreIDs = $this->CustomGroupMultipleCreateWithFields();
1912 $description = "This demonstrates the usage of chained api functions.\nIn this case no notes or custom fields have been created.";
1913 $subfile = "APIChainedArray";
1915 'first_name' => 'abc3',
1916 'last_name' => 'xyz3',
1917 'contact_type' => 'Individual',
1918 'email' => 'man3@yahoo.com',
1919 'api.contribution.create' => array(
1920 'receive_date' => '2010-01-01',
1921 'total_amount' => 100.00,
1922 'financial_type_id' => 1,
1923 'payment_instrument_id' => 1,
1924 'non_deductible_amount' => 10.00,
1925 'fee_amount' => 50.00,
1926 'net_amount' => 90.00,
1928 'invoice_id' => 67890,
1930 'contribution_status_id' => 1,
1932 'api.contribution.create.1' => array(
1933 'receive_date' => '2011-01-01',
1934 'total_amount' => 120.00,
1935 'financial_type_id' => $this->_financialTypeId
= 1,
1936 'payment_instrument_id' => 1,
1937 'non_deductible_amount' => 10.00,
1938 'fee_amount' => 50.00,
1939 'net_amount' => 90.00,
1941 'invoice_id' => 67830,
1943 'contribution_status_id' => 1,
1945 'api.website.create' => array(
1947 'url' => "http://civicrm.org",
1952 $result = $this->callAPISuccess('Contact', 'create', $params);
1954 'id' => $result['id'],
1955 'api.website.get' => array(),
1956 'api.Contribution.get' => array(
1957 'total_amount' => '120.00',
1959 'api.CustomValue.get' => 1,
1960 'api.Note.get' => 1,
1962 $result = $this->callAPIAndDocument('Contact', 'Get', $params, __FUNCTION__
, __FILE__
, $description, $subfile);
1963 // delete the contact
1964 $this->callAPISuccess('contact', 'delete', $result);
1965 $this->customGroupDelete($ids['custom_group_id']);
1966 $this->customGroupDelete($moreIDs['custom_group_id']);
1967 $this->assertEquals(0, $result['values'][$result['id']]['api.website.get']['is_error']);
1968 $this->assertEquals("http://civicrm.org", $result['values'][$result['id']]['api.website.get']['values'][0]['url']);
1972 * Verify attempt to create individual with chained arrays and sequential.
1974 * See https://issues.civicrm.org/jira/browse/CRM-15815
1976 public function testCreateIndividualWithChainedArrayAndSequential() {
1979 'first_name' => 'abc5',
1980 'last_name' => 'xyz5',
1981 'contact_type' => 'Individual',
1982 'email' => 'woman5@yahoo.com',
1983 'api.phone.create' => array(
1984 array('phone' => '03-231 07 95'),
1985 array('phone' => '03-232 51 62'),
1987 'api.website.create' => array(
1988 'url' => 'http://civicrm.org',
1991 $result = $this->callAPISuccess('Contact', 'create', $params);
1993 // I could try to parse the result to see whether the two phone numbers
1994 // and the website are there, but I am not sure about the correct format.
1995 // So I will just fetch it again before checking.
1996 // See also http://forum.civicrm.org/index.php/topic,35393.0.html
1999 'id' => $result['id'],
2000 'api.website.get' => array(),
2001 'api.phone.get' => array(),
2003 $result = $this->callAPISuccess('Contact', 'get', $params);
2005 // delete the contact
2006 $this->callAPISuccess('contact', 'delete', $result);
2008 $this->assertEquals(2, $result['values'][0]['api.phone.get']['count']);
2009 $this->assertEquals(1, $result['values'][0]['api.website.get']['count']);
2013 * Test retrieving an individual with chained array syntax.
2015 public function testGetIndividualWithChainedArraysFormats() {
2016 $description = "This demonstrates the usage of chained api functions.\nIn this case no notes or custom fields have been created.";
2017 $subfile = "APIChainedArrayFormats";
2018 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__
, __FILE__
);
2019 $params['custom_' . $ids['custom_field_id']] = "custom string";
2021 $moreIDs = $this->CustomGroupMultipleCreateWithFields();
2023 'first_name' => 'abc3',
2024 'last_name' => 'xyz3',
2025 'contact_type' => 'Individual',
2026 'email' => 'man3@yahoo.com',
2027 'api.contribution.create' => array(
2028 'receive_date' => '2010-01-01',
2029 'total_amount' => 100.00,
2030 'financial_type_id' => $this->_financialTypeId
,
2031 'payment_instrument_id' => 1,
2032 'non_deductible_amount' => 10.00,
2033 'fee_amount' => 50.00,
2034 'net_amount' => 90.00,
2036 'contribution_status_id' => 1,
2038 'api.contribution.create.1' => array(
2039 'receive_date' => '2011-01-01',
2040 'total_amount' => 120.00,
2041 'financial_type_id' => $this->_financialTypeId
,
2042 'payment_instrument_id' => 1,
2043 'non_deductible_amount' => 10.00,
2044 'fee_amount' => 50.00,
2045 'net_amount' => 90.00,
2047 'contribution_status_id' => 1,
2049 'api.website.create' => array(
2051 'url' => "http://civicrm.org",
2056 $result = $this->callAPISuccess('Contact', 'create', $params);
2058 'id' => $result['id'],
2059 'api.website.getValue' => array('return' => 'url'),
2060 'api.Contribution.getCount' => array(),
2061 'api.CustomValue.get' => 1,
2062 'api.Note.get' => 1,
2063 'api.Membership.getCount' => array(),
2065 $result = $this->callAPIAndDocument('Contact', 'Get', $params, __FUNCTION__
, __FILE__
, $description, $subfile);
2066 $this->assertEquals(2, $result['values'][$result['id']]['api.Contribution.getCount']);
2067 $this->assertEquals(0, $result['values'][$result['id']]['api.Note.get']['is_error']);
2068 $this->assertEquals("http://civicrm.org", $result['values'][$result['id']]['api.website.getValue']);
2070 $this->callAPISuccess('contact', 'delete', $result);
2071 $this->customGroupDelete($ids['custom_group_id']);
2072 $this->customGroupDelete($moreIDs['custom_group_id']);
2076 * Test complex chaining.
2078 public function testGetIndividualWithChainedArraysAndMultipleCustom() {
2079 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__
, __FILE__
);
2080 $params['custom_' . $ids['custom_field_id']] = "custom string";
2081 $moreIDs = $this->CustomGroupMultipleCreateWithFields();
2082 $andMoreIDs = $this->CustomGroupMultipleCreateWithFields(array(
2083 'title' => "another group",
2084 'name' => 'another name',
2086 $description = "This demonstrates the usage of chained api functions with multiple custom fields.";
2087 $subfile = "APIChainedArrayMultipleCustom";
2089 'first_name' => 'abc3',
2090 'last_name' => 'xyz3',
2091 'contact_type' => 'Individual',
2092 'email' => 'man3@yahoo.com',
2093 'api.contribution.create' => array(
2094 'receive_date' => '2010-01-01',
2095 'total_amount' => 100.00,
2096 'financial_type_id' => 1,
2097 'payment_instrument_id' => 1,
2098 'non_deductible_amount' => 10.00,
2099 'fee_amount' => 50.00,
2100 'net_amount' => 90.00,
2102 'invoice_id' => 67890,
2104 'contribution_status_id' => 1,
2106 'api.contribution.create.1' => array(
2107 'receive_date' => '2011-01-01',
2108 'total_amount' => 120.00,
2109 'financial_type_id' => 1,
2110 'payment_instrument_id' => 1,
2111 'non_deductible_amount' => 10.00,
2112 'fee_amount' => 50.00,
2113 'net_amount' => 90.00,
2115 'invoice_id' => 67830,
2117 'contribution_status_id' => 1,
2119 'api.website.create' => array(
2121 'url' => "http://civicrm.org",
2124 'custom_' . $ids['custom_field_id'] => "value 1",
2125 'custom_' . $moreIDs['custom_field_id'][0] => "value 2",
2126 'custom_' . $moreIDs['custom_field_id'][1] => "warm beer",
2127 'custom_' . $andMoreIDs['custom_field_id'][1] => "vegemite",
2130 $result = $this->callAPISuccess('Contact', 'create', $params);
2131 $result = $this->callAPISuccess('Contact', 'create', array(
2132 'contact_type' => 'Individual',
2133 'id' => $result['id'],
2135 $moreIDs['custom_field_id'][0] => "value 3",
2137 $ids['custom_field_id'] => "value 4",
2141 'id' => $result['id'],
2142 'api.website.getValue' => array('return' => 'url'),
2143 'api.Contribution.getCount' => array(),
2144 'api.CustomValue.get' => 1,
2146 $result = $this->callAPIAndDocument('Contact', 'Get', $params, __FUNCTION__
, __FILE__
, $description, $subfile);
2148 $this->customGroupDelete($ids['custom_group_id']);
2149 $this->customGroupDelete($moreIDs['custom_group_id']);
2150 $this->customGroupDelete($andMoreIDs['custom_group_id']);
2151 $this->assertEquals(0, $result['values'][$result['id']]['api.CustomValue.get']['is_error']);
2152 $this->assertEquals('http://civicrm.org', $result['values'][$result['id']]['api.website.getValue']);
2156 * Test checks usage of $values to pick & choose inputs.
2158 public function testChainingValuesCreate() {
2159 $description = "This demonstrates the usage of chained api functions. Specifically it has one 'parent function' &
2160 2 child functions - one receives values from the parent (Contact) and the other child (Tag).";
2161 $subfile = "APIChainedArrayValuesFromSiblingFunction";
2163 'display_name' => 'batman',
2164 'contact_type' => 'Individual',
2165 'api.tag.create' => array(
2166 'name' => '$value.id',
2167 'description' => '$value.display_name',
2168 'format.only_id' => 1,
2170 'api.entity_tag.create' => array('tag_id' => '$value.api.tag.create'),
2172 $result = $this->callAPIAndDocument('Contact', 'Create', $params, __FUNCTION__
, __FILE__
, $description, $subfile);
2173 $this->assertEquals(0, $result['values'][$result['id']]['api.entity_tag.create']['is_error']);
2175 $tablesToTruncate = array(
2178 'civicrm_entity_tag',
2181 $this->quickCleanup($tablesToTruncate, TRUE);
2185 * Test TrueFalse format - I couldn't come up with an easy way to get an error on Get.
2187 public function testContactGetFormatIsSuccessTrue() {
2188 $this->createContactFromXML();
2189 $description = "This demonstrates use of the 'format.is_success' param.
2190 This param causes only the success or otherwise of the function to be returned as BOOLEAN";
2191 $subfile = "FormatIsSuccess_True";
2192 $params = array('id' => 17, 'format.is_success' => 1);
2193 $result = $this->callAPIAndDocument('Contact', 'Get', $params, __FUNCTION__
, __FILE__
, $description, $subfile);
2194 $this->assertEquals(1, $result);
2195 $this->callAPISuccess('Contact', 'Delete', $params);
2199 * Test TrueFalse format.
2201 public function testContactCreateFormatIsSuccessFalse() {
2203 $description = "This demonstrates use of the 'format.is_success' param.
2204 This param causes only the success or otherwise of the function to be returned as BOOLEAN";
2205 $subfile = "FormatIsSuccess_Fail";
2206 $params = array('id' => 500, 'format.is_success' => 1);
2207 $result = $this->callAPIAndDocument('Contact', 'Create', $params, __FUNCTION__
, __FILE__
, $description, $subfile);
2208 $this->assertEquals(0, $result);
2212 * Test Single Entity format.
2214 public function testContactGetSingleEntityArray() {
2215 $this->createContactFromXML();
2216 $description = "This demonstrates use of the 'format.single_entity_array' param.
2217 This param causes the only contact to be returned as an array without the other levels.
2218 It will be ignored if there is not exactly 1 result";
2219 $subfile = "GetSingleContact";
2220 $params = array('id' => 17);
2221 $result = $this->callAPIAndDocument('Contact', 'GetSingle', $params, __FUNCTION__
, __FILE__
, $description, $subfile);
2222 $this->assertEquals('Test Contact', $result['display_name']);
2223 $this->callAPISuccess('Contact', 'Delete', $params);
2227 * Test Single Entity format.
2229 public function testContactGetFormatCountOnly() {
2230 $this->createContactFromXML();
2231 $description = "This demonstrates use of the 'getCount' action.
2232 This param causes the count of the only function to be returned as an integer.";
2233 $params = array('id' => 17);
2234 $result = $this->callAPIAndDocument('Contact', 'GetCount', $params, __FUNCTION__
, __FILE__
, $description,
2236 $this->assertEquals('1', $result);
2237 $this->callAPISuccess('Contact', 'Delete', $params);
2241 * Test id only format.
2243 public function testContactGetFormatIDOnly() {
2244 $this->createContactFromXML();
2245 $description = "This demonstrates use of the 'format.id_only' param.
2246 This param causes the id of the only entity to be returned as an integer.
2247 It will be ignored if there is not exactly 1 result";
2248 $subfile = "FormatOnlyID";
2249 $params = array('id' => 17, 'format.only_id' => 1);
2250 $result = $this->callAPIAndDocument('Contact', 'Get', $params, __FUNCTION__
, __FILE__
, $description, $subfile);
2251 $this->assertEquals('17', $result);
2252 $this->callAPISuccess('Contact', 'Delete', $params);
2256 * Test id only format.
2258 public function testContactGetFormatSingleValue() {
2259 $this->createContactFromXML();
2260 $description = "This demonstrates use of the 'format.single_value' param.
2261 This param causes only a single value of the only entity to be returned as an string.
2262 It will be ignored if there is not exactly 1 result";
2263 $subFile = "FormatSingleValue";
2264 $params = array('id' => 17, 'return' => 'display_name');
2265 $result = $this->callAPIAndDocument('Contact', 'getvalue', $params, __FUNCTION__
, __FILE__
, $description, $subFile);
2266 $this->assertEquals('Test Contact', $result);
2267 $this->callAPISuccess('Contact', 'Delete', $params);
2271 * Test that permissions are respected when creating contacts.
2273 public function testContactCreationPermissions() {
2275 'contact_type' => 'Individual',
2276 'first_name' => 'Foo',
2277 'last_name' => 'Bear',
2278 'check_permissions' => TRUE,
2280 $config = CRM_Core_Config
::singleton();
2281 $config->userPermissionClass
->permissions
= array('access CiviCRM');
2282 $result = $this->callAPIFailure('contact', 'create', $params);
2283 $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');
2285 $config->userPermissionClass
->permissions
= array('access CiviCRM', 'add contacts', 'import contacts');
2286 $this->callAPISuccess('contact', 'create', $params);
2290 * Test that delete with skip undelete respects permissions.
2292 public function testContactDeletePermissions() {
2293 $contactID = $this->individualCreate();
2294 CRM_Core_Config
::singleton()->userPermissionClass
->permissions
= array('access CiviCRM');
2295 $this->callAPIFailure('Contact', 'delete', array(
2297 'check_permissions' => 1,
2298 'skip_undelete' => 1,
2300 $this->callAPISuccess('Contact', 'delete', array(
2302 'check_permissions' => 0,
2303 'skip_undelete' => 1,
2308 * Test update with check permissions set.
2310 public function testContactUpdatePermissions() {
2312 'contact_type' => 'Individual',
2313 'first_name' => 'Foo',
2314 'last_name' => 'Bear',
2315 'check_permissions' => TRUE,
2317 $result = $this->callAPISuccess('contact', 'create', $params);
2318 $config = CRM_Core_Config
::singleton();
2320 'id' => $result['id'],
2321 'contact_type' => 'Individual',
2322 'last_name' => 'Bar',
2323 'check_permissions' => TRUE,
2326 $config->userPermissionClass
->permissions
= array('access CiviCRM');
2327 $result = $this->callAPIFailure('contact', 'update', $params);
2328 $this->assertEquals('Permission denied to modify contact record', $result['error_message']);
2330 $config->userPermissionClass
->permissions
= array(
2333 'view all contacts',
2334 'edit all contacts',
2337 $this->callAPISuccess('contact', 'update', $params);
2341 * Set up helper to create a contact.
2343 public function createContactFromXML() {
2344 // Insert a row in civicrm_contact creating contact 17.
2345 $op = new PHPUnit_Extensions_Database_Operation_Insert();
2346 $op->execute($this->_dbconn
,
2347 $this->createXMLDataSet(
2348 dirname(__FILE__
) . '/dataset/contact_17.xml'
2354 * Test contact proximity api.
2356 public function testContactProximity() {
2357 // first create a contact with a SF location with a specific
2359 $contactID = $this->organizationCreate();
2361 // now create the address
2363 'street_address' => '123 Main Street',
2364 'city' => 'San Francisco',
2366 'country_id' => 1228,
2367 'state_province_id' => 1004,
2368 'geo_code_1' => '37.79',
2369 'geo_code_2' => '-122.40',
2370 'location_type_id' => 1,
2371 'contact_id' => $contactID,
2374 $result = $this->callAPISuccess('address', 'create', $params);
2375 $this->assertEquals(1, $result['count']);
2377 // now do a proximity search with a close enough geocode and hope to match
2378 // that specific contact only!
2379 $proxParams = array(
2381 'longitude' => -122.3,
2385 $result = $this->callAPISuccess('contact', 'proximity', $proxParams);
2386 $this->assertEquals(1, $result['count']);
2390 * Test that Ajax API permission is sufficient to access getquick api.
2392 * (note that getquick api is required for autocomplete & has ACL permissions applied)
2394 public function testGetquickPermissionCRM13744() {
2395 CRM_Core_Config
::singleton()->userPermissionClass
->permissions
= array('access CiviEvent');
2396 $this->callAPIFailure('contact', 'getquick', array('name' => 'b', 'check_permissions' => TRUE));
2397 CRM_Core_Config
::singleton()->userPermissionClass
->permissions
= array('access CiviCRM');
2398 $this->callAPISuccess('contact', 'getquick', array('name' => 'b', 'check_permissions' => TRUE));
2399 CRM_Core_Config
::singleton()->userPermissionClass
->permissions
= array('access AJAX API');
2400 $this->callAPISuccess('contact', 'getquick', array('name' => 'b', 'check_permissions' => TRUE));
2404 * Test that getquick returns contacts with an exact first name match first.
2406 * The search string 'b' & 'bob' both return ordered by sort_name if includeOrderByClause
2407 * is true (default) but if it is false then matches are returned in ID order.
2409 * @dataProvider getSearchSortOptions
2411 public function testGetQuickExactFirst($searchParameters, $settings, $firstContact, $secondContact = NULL) {
2412 $this->getQuickSearchSampleData();
2413 $this->callAPISuccess('Setting', 'create', $settings);
2414 $result = $this->callAPISuccess('contact', 'getquick', $searchParameters);
2415 $this->assertEquals($firstContact, $result['values'][0]['sort_name']);
2416 $this->assertEquals($secondContact, $result['values'][1]['sort_name']);
2417 $this->callAPISuccess('Setting', 'create', array('includeWildCardInName' => TRUE, 'includeOrderByClause' => TRUE));
2420 public function getSearchSortOptions() {
2421 $firstAlphabeticalContactBySortName = 'A Bobby, Bobby';
2422 $secondAlphabeticalContactBySortName = 'Aadvark, Bob';
2423 $secondAlphabeticalContactWithEmailBySortName = 'Bob, Bob';
2424 $firstAlphabeticalContactFirstNameBob = 'Aadvark, Bob';
2425 $secondAlphabeticalContactFirstNameBob = 'Bob, Bob';
2426 $firstByIDContactFirstNameBob = 'Bob, Bob';
2427 $secondByIDContactFirstNameBob = 'K Bobby, Bob';
2428 $firstContactByID = 'Bob, Bob';
2429 $secondContactByID = 'E Bobby, Bobby';
2430 $bobLikeEmail = 'A Bobby, Bobby';
2433 'empty_search_basic' => array(
2434 'search_parameters' => array('name' => '%'),
2435 'settings' => array('includeWildCardInName' => TRUE, 'includeOrderByClause' => TRUE),
2436 'first_contact' => $firstAlphabeticalContactBySortName,
2437 'second_contact' => $secondAlphabeticalContactBySortName,
2439 'empty_search_basic_no_wildcard' => array(
2440 'search_parameters' => array('name' => '%'),
2441 'settings' => array('includeWildCardInName' => FALSE, 'includeOrderByClause' => TRUE),
2442 'first_contact' => $firstAlphabeticalContactBySortName,
2443 'second_contact' => $secondAlphabeticalContactBySortName,
2445 'single_letter_search_basic' => array(
2446 'search_parameters' => array('name' => 'b'),
2447 'settings' => array('includeWildCardInName' => TRUE, 'includeOrderByClause' => TRUE),
2448 'first_contact' => $firstAlphabeticalContactBySortName,
2449 'second_contact' => $secondAlphabeticalContactBySortName,
2451 'bob_search_basic' => array(
2452 'search_parameters' => array('name' => 'bob'),
2453 'settings' => array('includeWildCardInName' => TRUE, 'includeOrderByClause' => TRUE),
2454 'first_contact' => $firstAlphabeticalContactBySortName,
2455 'second_contact' => $secondAlphabeticalContactBySortName,
2457 'bob_search_no_orderby' => array(
2458 'search_parameters' => array('name' => 'bob'),
2459 'settings' => array('includeWildCardInName' => TRUE, 'includeOrderByClause' => FALSE),
2460 'first_contact' => $firstContactByID,
2461 'second_contact' => $secondContactByID,
2463 'bob_search_no_wildcard' => array(
2464 'search_parameters' => array('name' => 'bob'),
2465 'settings' => array('includeWildCardInName' => FALSE, 'includeOrderByClause' => TRUE),
2466 'second_contact' => $bobLikeEmail,
2467 'first_contact' => $secondAlphabeticalContactFirstNameBob,
2469 // This should be the same as just no wildcard as if we had an exactMatch while searching by
2470 // sort name it would rise to the top CRM-19547
2471 'bob_search_no_wildcard_no_orderby' => array(
2472 'search_parameters' => array('name' => 'bob'),
2473 'settings' => array('includeWildCardInName' => FALSE, 'includeOrderByClause' => TRUE),
2474 'second_contact' => $bobLikeEmail,
2475 'first_contact' => $secondAlphabeticalContactFirstNameBob,
2477 'first_name_search_basic' => array(
2478 'search_parameters' => array('name' => 'bob', 'field_name' => 'first_name'),
2479 'settings' => array('includeWildCardInName' => TRUE, 'includeOrderByClause' => TRUE),
2480 'first_contact' => $firstAlphabeticalContactFirstNameBob,
2481 'second_contact' => $secondAlphabeticalContactFirstNameBob,
2483 'first_name_search_no_wildcard' => array(
2484 'search_parameters' => array('name' => 'bob', 'field_name' => 'first_name'),
2485 'settings' => array('includeWildCardInName' => FALSE, 'includeOrderByClause' => TRUE),
2486 'first_contact' => $firstAlphabeticalContactFirstNameBob,
2487 'second_contact' => $secondAlphabeticalContactFirstNameBob,
2489 'first_name_search_no_orderby' => array(
2490 'search_parameters' => array('name' => 'bob', 'field_name' => 'first_name'),
2491 'settings' => array('includeWildCardInName' => TRUE, 'includeOrderByClause' => FALSE),
2492 'first_contact' => $firstByIDContactFirstNameBob,
2493 'second_contact' => $secondByIDContactFirstNameBob,
2495 'email_search_basic' => array(
2496 'search_parameters' => array('name' => 'bob', 'field_name' => 'email', 'table_name' => 'eml'),
2497 'settings' => array('includeWildCardInName' => FALSE, 'includeOrderByClause' => TRUE),
2498 'first_contact' => $firstAlphabeticalContactBySortName,
2499 'second_contact' => $secondAlphabeticalContactWithEmailBySortName,
2505 * Test that getquick returns contacts with an exact first name match first.
2507 public function testGetQuickEmail() {
2508 $this->getQuickSearchSampleData();
2509 $loggedInContactID = $this->createLoggedInUser();
2510 $result = $this->callAPISuccess('contact', 'getquick', array(
2513 $expectedData = array(
2514 'A Bobby, Bobby :: bob@bobby.com',
2515 'Bob, Bob :: bob@bob.com',
2517 'H Bobby, Bobby :: bob@h.com',
2519 $this->callAPISuccessGetValue('Contact', array('id' => $loggedInContactID, 'return' => 'last_name')) . ', Logged In :: anthony_anderson@civicrm.org',
2521 $this->assertEquals(6, $result['count']);
2522 foreach ($expectedData as $index => $value) {
2523 $this->assertEquals($value, $result['values'][$index]['data']);
2525 $result = $this->callAPISuccess('contact', 'getquick', array(
2528 $expectedData = array(
2529 'H Bobby, Bobby :: bob@h.com',
2531 foreach ($expectedData as $index => $value) {
2532 $this->assertEquals($value, $result['values'][$index]['data']);
2534 $this->callAPISuccess('Setting', 'create', array('includeWildCardInName' => FALSE));
2535 $result = $this->callAPISuccess('contact', 'getquick', array(
2538 $this->callAPISuccess('Setting', 'create', array('includeWildCardInName' => TRUE));
2539 $this->assertEquals(0, $result['count']);
2543 * Test that getquick returns contacts with an exact first name match first.
2545 public function testGetQuickEmailACL() {
2546 $this->getQuickSearchSampleData();
2547 $loggedInContactID = $this->createLoggedInUser();
2548 CRM_Core_Config
::singleton()->userPermissionClass
->permissions
= array();
2549 $result = $this->callAPISuccess('contact', 'getquick', array(
2552 $this->assertEquals(0, $result['count']);
2554 $this->hookClass
->setHook('civicrm_aclWhereClause', array($this, 'aclWhereNoBobH'));
2555 CRM_Contact_BAO_Contact_Permission
::cache($loggedInContactID, CRM_Core_Permission
::VIEW
, TRUE);
2556 $result = $this->callAPISuccess('contact', 'getquick', array(
2560 // Without the acl it would be 6 like the previous email getquick test.
2561 $this->assertEquals(5, $result['count']);
2562 $expectedData = array(
2563 'A Bobby, Bobby :: bob@bobby.com',
2564 'Bob, Bob :: bob@bob.com',
2567 $this->callAPISuccessGetValue('Contact', array('id' => $loggedInContactID, 'return' => 'last_name')) . ', Logged In :: anthony_anderson@civicrm.org',
2569 foreach ($expectedData as $index => $value) {
2570 $this->assertEquals($value, $result['values'][$index]['data']);
2575 * Test that getquick returns contacts with an exact first name match first.
2577 public function testGetQuickExternalID() {
2578 $this->getQuickSearchSampleData();
2579 $result = $this->callAPISuccess('contact', 'getquick', array(
2581 'field_name' => 'external_identifier',
2582 'table_name' => 'cc',
2584 $this->assertEquals(0, $result['count']);
2585 $result = $this->callAPISuccess('contact', 'getquick', array(
2587 'field_name' => 'external_identifier',
2588 'table_name' => 'cc',
2590 $this->assertEquals(1, $result['count']);
2591 $this->assertEquals('Bob, Bob', $result['values'][0]['sort_name']);
2595 * Test that getquick returns contacts with an exact first name match first.
2597 public function testGetQuickID() {
2598 $max = CRM_Core_DAO
::singleValueQuery("SELECT max(id) FROM civicrm_contact");
2599 $this->getQuickSearchSampleData();
2600 $result = $this->callAPISuccess('contact', 'getquick', array(
2602 'field_name' => 'id',
2603 'table_name' => 'cc',
2605 $this->assertEquals(1, $result['count']);
2606 $this->assertEquals('E Bobby, Bobby', $result['values'][0]['sort_name']);
2607 $result = $this->callAPISuccess('contact', 'getquick', array(
2609 'field_name' => 'contact_id',
2610 'table_name' => 'cc',
2612 $this->assertEquals(1, $result['count']);
2613 $this->assertEquals('E Bobby, Bobby', $result['values'][0]['sort_name']);
2617 * Test that getquick returns contacts with an exact first name match first.
2619 * Depending on the setting the sort name sort might click in next or not - test!
2621 public function testGetQuickFirstName() {
2622 $this->getQuickSearchSampleData();
2623 $this->callAPISuccess('Setting', 'create', array('includeOrderByClause' => TRUE));
2624 $result = $this->callAPISuccess('contact', 'getquick', array(
2626 'field_name' => 'first_name',
2627 'table_name' => 'cc',
2636 foreach ($expected as $index => $value) {
2637 $this->assertEquals($value, $result['values'][$index]['sort_name']);
2639 $this->callAPISuccess('Setting', 'create', array('includeOrderByClause' => FALSE));
2640 $result = $this->callAPISuccess('contact', 'getquick', array('name' => 'bob'));
2641 $this->assertEquals('Bob, Bob', $result['values'][0]['sort_name']);
2642 $this->assertEquals('E Bobby, Bobby', $result['values'][1]['sort_name']);
2646 * Test that getquick applies ACLs.
2648 public function testGetQuickFirstNameACLs() {
2649 $this->getQuickSearchSampleData();
2650 $userID = $this->createLoggedInUser();
2651 $this->callAPISuccess('Setting', 'create', array('includeOrderByClause' => TRUE, 'search_autocomplete_count' => 15));
2652 CRM_Core_Config
::singleton()->userPermissionClass
->permissions
= array();
2653 $result = $this->callAPISuccess('contact', 'getquick', array(
2655 'field_name' => 'first_name',
2656 'table_name' => 'cc',
2658 $this->assertEquals(0, $result['count']);
2660 $this->hookClass
->setHook('civicrm_aclWhereClause', array($this, 'aclWhereNoBobH'));
2661 CRM_Contact_BAO_Contact_Permission
::cache($userID, CRM_Core_Permission
::VIEW
, TRUE);
2662 $result = $this->callAPISuccess('contact', 'getquick', array(
2664 'field_name' => 'first_name',
2665 'table_name' => 'cc',
2667 $this->assertEquals('K Bobby, Bob', $result['values'][2]['sort_name']);
2668 // Without the ACL 9 would be bob@h.com.
2669 $this->assertEquals('I Bobby, Bobby', $result['values'][10]['sort_name']);
2673 * Full results returned.
2674 * @implements CRM_Utils_Hook::aclWhereClause
2676 * @param string $type
2677 * @param array $tables
2678 * @param array $whereTables
2679 * @param int $contactID
2680 * @param string $where
2682 public function aclWhereNoBobH($type, &$tables, &$whereTables, &$contactID, &$where) {
2683 $where = " (email <> 'bob@h.com' OR email IS NULL) ";
2684 $whereTables['civicrm_email'] = "LEFT JOIN civicrm_email e ON contact_a.id = e.contact_id";
2688 * Test that getquick returns contacts with an exact last name match first.
2690 public function testGetQuickLastName() {
2691 $this->getQuickSearchSampleData();
2692 $this->callAPISuccess('Setting', 'create', array('includeOrderByClause' => TRUE));
2693 $result = $this->callAPISuccess('contact', 'getquick', array(
2695 'field_name' => 'last_name',
2696 'table_name' => 'cc',
2704 foreach ($expected as $index => $value) {
2705 $this->assertEquals($value, $result['values'][$index]['sort_name']);
2707 $this->callAPISuccess('Setting', 'create', array('includeOrderByClause' => FALSE));
2708 $result = $this->callAPISuccess('contact', 'getquick', array('name' => 'bob'));
2709 $this->assertEquals('Bob, Bob :: bob@bob.com', $result['values'][0]['data']);
2713 * Test that getquick returns contacts by city.
2715 public function testGetQuickCity() {
2716 $this->getQuickSearchSampleData();
2717 $result = $this->callAPISuccess('contact', 'getquick', array(
2719 'field_name' => 'city',
2720 'table_name' => 'sts',
2722 $this->assertEquals('B Bobby, Bobby :: Toronto', $result['values'][0]['data']);
2723 $result = $this->callAPISuccess('contact', 'getquick', array(
2725 'field_name' => 'city',
2726 'table_name' => 'sts',
2728 $this->assertEquals('B Bobby, Bobby :: Toronto', $result['values'][0]['data']);
2729 $this->assertEquals('C Bobby, Bobby :: Whanganui', $result['values'][1]['data']);
2733 * Set up some sample data for testing quicksearch.
2735 public function getQuickSearchSampleData() {
2737 array('first_name' => 'Bob', 'last_name' => 'Bob', 'external_identifier' => 'abc', 'email' => 'bob@bob.com'),
2738 array('first_name' => 'Bobby', 'last_name' => 'E Bobby', 'external_identifier' => 'abcd'),
2740 'first_name' => 'Bobby',
2741 'last_name' => 'B Bobby',
2742 'external_identifier' => 'bcd',
2743 'api.address.create' => array(
2744 'street_address' => 'Sesame Street',
2745 'city' => 'Toronto',
2746 'location_type_id' => 1,
2750 'first_name' => 'Bobby',
2751 'last_name' => 'C Bobby',
2752 'external_identifier' => 'bcde',
2753 'api.address.create' => array(
2754 'street_address' => 'Te huarahi',
2755 'city' => 'Whanganui',
2756 'location_type_id' => 1,
2759 array('first_name' => 'Bobby', 'last_name' => 'D Bobby', 'external_identifier' => 'efg'),
2760 array('first_name' => 'Bobby', 'last_name' => 'A Bobby', 'external_identifier' => 'hij', 'email' => 'bob@bobby.com'),
2761 array('first_name' => 'Bobby', 'last_name' => 'F Bobby', 'external_identifier' => 'klm'),
2762 array('first_name' => 'Bobby', 'last_name' => 'G Bobby', 'external_identifier' => 'nop'),
2763 array('first_name' => 'Bobby', 'last_name' => 'H Bobby', 'external_identifier' => 'qrs', 'email' => 'bob@h.com'),
2764 array('first_name' => 'Bobby', 'last_name' => 'I Bobby'),
2765 array('first_name' => 'Bobby', 'last_name' => 'J Bobby'),
2766 array('first_name' => 'Bob', 'last_name' => 'K Bobby', 'external_identifier' => 'bcdef'),
2767 array('first_name' => 'Bob', 'last_name' => 'Aadvark'),
2769 foreach ($contacts as $type => $contact) {
2770 $contact['contact_type'] = 'Individual';
2771 $this->callAPISuccess('Contact', 'create', $contact);
2776 * Test get ref api - gets a list of references to an entity.
2778 public function testGetReferenceCounts() {
2779 $result = $this->callAPISuccess('Contact', 'create', array(
2780 'first_name' => 'Testily',
2781 'last_name' => 'McHaste',
2782 'contact_type' => 'Individual',
2783 'api.Address.replace' => array(
2784 'values' => array(),
2786 'api.Email.replace' => array(
2789 'email' => 'spam@dev.null',
2791 'location_type_id' => 1,
2795 'api.Phone.replace' => array(
2798 'phone' => '234-567-0001',
2800 'location_type_id' => 1,
2803 'phone' => '234-567-0002',
2805 'location_type_id' => 1,
2811 //$dao = new CRM_Contact_BAO_Contact();
2812 //$dao->id = $result['id'];
2813 //$this->assertTrue((bool) $dao->find(TRUE));
2815 //$refCounts = $dao->getReferenceCounts();
2816 //$this->assertTrue(is_array($refCounts));
2817 //$refCountsIdx = CRM_Utils_Array::index(array('name'), $refCounts);
2819 $refCounts = $this->callAPISuccess('Contact', 'getrefcount', array(
2820 'id' => $result['id'],
2822 $refCountsIdx = CRM_Utils_Array
::index(array('name'), $refCounts['values']);
2824 $this->assertEquals(1, $refCountsIdx['sql:civicrm_email:contact_id']['count']);
2825 $this->assertEquals('civicrm_email', $refCountsIdx['sql:civicrm_email:contact_id']['table']);
2826 $this->assertEquals(2, $refCountsIdx['sql:civicrm_phone:contact_id']['count']);
2827 $this->assertEquals('civicrm_phone', $refCountsIdx['sql:civicrm_phone:contact_id']['table']);
2828 $this->assertTrue(!isset($refCountsIdx['sql:civicrm_address:contact_id']));
2832 * Test the use of sql operators.
2834 public function testSQLOperatorsOnContactAPI() {
2835 $this->individualCreate();
2836 $this->organizationCreate();
2837 $this->householdCreate();
2838 $contacts = $this->callAPISuccess('contact', 'get', array('legal_name' => array('IS NOT NULL' => TRUE)));
2839 $this->assertEquals($contacts['count'], CRM_Core_DAO
::singleValueQuery('select count(*) FROM civicrm_contact WHERE legal_name IS NOT NULL'));
2840 $contacts = $this->callAPISuccess('contact', 'get', array('legal_name' => array('IS NULL' => TRUE)));
2841 $this->assertEquals($contacts['count'], CRM_Core_DAO
::singleValueQuery('select count(*) FROM civicrm_contact WHERE legal_name IS NULL'));
2845 * CRM-14743 - test api respects search operators.
2847 public function testGetModifiedDateByOperators() {
2848 $preExistingContactCount = CRM_Core_DAO
::singleValueQuery('select count(*) FROM civicrm_contact');
2849 $contact1 = $this->individualCreate();
2850 $sql = "UPDATE civicrm_contact SET created_date = '2012-01-01', modified_date = '2013-01-01' WHERE id = " . $contact1;
2851 CRM_Core_DAO
::executeQuery($sql);
2852 $contact2 = $this->individualCreate();
2853 $sql = "UPDATE civicrm_contact SET created_date = '2012-02-01', modified_date = '2013-02-01' WHERE id = " . $contact2;
2854 CRM_Core_DAO
::executeQuery($sql);
2855 $contact3 = $this->householdCreate();
2856 $sql = "UPDATE civicrm_contact SET created_date = '2012-03-01', modified_date = '2013-03-01' WHERE id = " . $contact3;
2857 CRM_Core_DAO
::executeQuery($sql);
2858 $contacts = $this->callAPISuccess('contact', 'get', array('modified_date' => array('<' => '2014-01-01')));
2859 $this->assertEquals($contacts['count'], 3);
2860 $contacts = $this->callAPISuccess('contact', 'get', array('modified_date' => array('>' => '2014-01-01')));
2861 $this->assertEquals($contacts['count'], $preExistingContactCount);
2865 * CRM-14743 - test api respects search operators.
2867 public function testGetCreatedDateByOperators() {
2868 $preExistingContactCount = CRM_Core_DAO
::singleValueQuery('select count(*) FROM civicrm_contact');
2869 $contact1 = $this->individualCreate();
2870 $sql = "UPDATE civicrm_contact SET created_date = '2012-01-01' WHERE id = " . $contact1;
2871 CRM_Core_DAO
::executeQuery($sql);
2872 $contact2 = $this->individualCreate();
2873 $sql = "UPDATE civicrm_contact SET created_date = '2012-02-01' WHERE id = " . $contact2;
2874 CRM_Core_DAO
::executeQuery($sql);
2875 $contact3 = $this->householdCreate();
2876 $sql = "UPDATE civicrm_contact SET created_date = '2012-03-01' WHERE id = " . $contact3;
2877 CRM_Core_DAO
::executeQuery($sql);
2878 $contacts = $this->callAPISuccess('contact', 'get', array('created_date' => array('<' => '2014-01-01')));
2879 $this->assertEquals($contacts['count'], 3);
2880 $contacts = $this->callAPISuccess('contact', 'get', array('created_date' => array('>' => '2014-01-01')));
2881 $this->assertEquals($contacts['count'], $preExistingContactCount);
2885 * CRM-14263 check that API is not affected by search profile related bug.
2887 public function testReturnCityProfile() {
2888 $contactID = $this->individualCreate();
2889 CRM_Core_Config
::singleton()->defaultSearchProfileID
= 1;
2890 $this->callAPISuccess('address', 'create', array(
2891 'contact_id' => $contactID,
2892 'city' => 'Cool City',
2893 'location_type_id' => 1,
2895 $result = $this->callAPISuccess('contact', 'get', array('city' => 'Cool City', 'return' => 'contact_type'));
2896 $this->assertEquals(1, $result['count']);
2900 * CRM-15443 - ensure getlist api does not return deleted contacts.
2902 public function testGetlistExcludeConditions() {
2903 $name = md5(time());
2904 $contact = $this->individualCreate(array('last_name' => $name));
2905 $this->individualCreate(array('last_name' => $name, 'is_deceased' => 1));
2906 $this->individualCreate(array('last_name' => $name, 'is_deleted' => 1));
2907 // We should get all but the deleted contact.
2908 $result = $this->callAPISuccess('contact', 'getlist', array('input' => $name));
2909 $this->assertEquals(2, $result['count']);
2910 // Force-exclude the deceased contact.
2911 $result = $this->callAPISuccess('contact', 'getlist', array(
2913 'params' => array('is_deceased' => 0),
2915 $this->assertEquals(1, $result['count']);
2916 $this->assertEquals($contact, $result['values'][0]['id']);
2920 * Test contact getactions.
2922 public function testGetActions() {
2923 $description = "Getting the available actions for an entity.";
2924 $result = $this->callAPIAndDocument($this->_entity
, 'getactions', array(), __FUNCTION__
, __FILE__
, $description);
2944 $deprecated = array(
2948 foreach ($expected as $action) {
2949 $this->assertTrue(in_array($action, $result['values']), "Expected action $action");
2951 foreach ($deprecated as $action) {
2952 $this->assertArrayKeyExists($action, $result['deprecated']);
2957 * Test the duplicate check function.
2959 public function testDuplicateCheck() {
2960 $this->callAPISuccess('Contact', 'create', array(
2961 'first_name' => 'Harry',
2962 'last_name' => 'Potter',
2963 'email' => 'harry@hogwarts.edu',
2964 'contact_type' => 'Individual',
2966 $result = $this->callAPISuccess('Contact', 'duplicatecheck', array(
2968 'first_name' => 'Harry',
2969 'last_name' => 'Potter',
2970 'email' => 'harry@hogwarts.edu',
2971 'contact_type' => 'Individual',
2975 $this->assertEquals(1, $result['count']);
2976 $result = $this->callAPISuccess('Contact', 'duplicatecheck', array(
2978 'first_name' => 'Harry',
2979 'last_name' => 'Potter',
2980 'email' => 'no5@privet.drive',
2981 'contact_type' => 'Individual',
2984 $this->assertEquals(0, $result['count']);
2987 public function testGetByContactType() {
2988 $individual = $this->callAPISuccess('Contact', 'create', array(
2989 'email' => 'individual@test.com',
2990 'contact_type' => 'Individual',
2992 $household = $this->callAPISuccess('Contact', 'create', array(
2993 'household_name' => 'household@test.com',
2994 'contact_type' => 'Household',
2996 $organization = $this->callAPISuccess('Contact', 'create', array(
2997 'organization_name' => 'organization@test.com',
2998 'contact_type' => 'Organization',
3000 // Test with id - getsingle will throw an exception if not found
3001 $this->callAPISuccess('Contact', 'getsingle', array(
3002 'id' => $individual['id'],
3003 'contact_type' => 'Individual',
3005 $this->callAPISuccess('Contact', 'getsingle', array(
3006 'id' => $individual['id'],
3007 'contact_type' => array('IN' => array('Individual')),
3010 $this->callAPISuccess('Contact', 'getsingle', array(
3011 'id' => $organization['id'],
3012 'contact_type' => array('IN' => array('Individual', 'Organization')),
3015 $result = $this->callAPISuccess('Contact', 'get', array(
3016 'contact_type' => array('IN' => array('Individual', 'Organization')),
3017 'options' => array('limit' => 0),
3020 $this->assertContains($organization['id'], array_keys($result['values']));
3021 $this->assertContains($individual['id'], array_keys($result['values']));
3022 $this->assertNotContains($household['id'], array_keys($result['values']));
3024 $result = $this->callAPISuccess('Contact', 'get', array(
3025 'contact_type' => 'Household',
3026 'options' => array('limit' => 0),
3029 $this->assertNotContains($organization['id'], array_keys($result['values']));
3030 $this->assertNotContains($individual['id'], array_keys($result['values']));
3031 $this->assertContains($household['id'], array_keys($result['values']));
3035 * Test merging 2 contacts.
3037 * Someone kindly bequethed us the legacy of mixed up use of main_id & other_id
3038 * in the params for contact.merge api.
3040 * This test protects that legacy.
3042 public function testMergeBizzareOldParams() {
3043 $this->createLoggedInUser();
3044 $otherContact = $this->callAPISuccess('contact', 'create', $this->_params
);
3045 $mainContact = $this->callAPISuccess('contact', 'create', $this->_params
);
3046 $this->callAPISuccess('contact', 'merge', array(
3047 'main_id' => $mainContact['id'],
3048 'other_id' => $otherContact['id'],
3050 $contacts = $this->callAPISuccess('contact', 'get', $this->_params
);
3051 $this->assertEquals($otherContact['id'], $contacts['id']);
3055 * Test merging 2 contacts.
3057 public function testMerge() {
3058 $this->createLoggedInUser();
3059 $otherContact = $this->callAPISuccess('contact', 'create', $this->_params
);
3060 $retainedContact = $this->callAPISuccess('contact', 'create', $this->_params
);
3061 $this->callAPISuccess('contact', 'merge', array(
3062 'to_keep_id' => $retainedContact['id'],
3063 'to_remove_id' => $otherContact['id'],
3064 'auto_flip' => FALSE,
3067 $contacts = $this->callAPISuccess('contact', 'get', $this->_params
);
3068 $this->assertEquals($retainedContact['id'], $contacts['id']);
3069 $activity = $this->callAPISuccess('Activity', 'getsingle', array(
3070 'target_contact_id' => $retainedContact['id'],
3071 'activity_type_id' => 'Contact Merged',
3073 $this->assertEquals(date('Y-m-d'), date('Y-m-d', strtotime($activity['activity_date_time'])));
3074 $activity2 = $this->callAPISuccess('Activity', 'getsingle', array(
3075 'target_contact_id' => $otherContact['id'],
3076 'activity_type_id' => 'Contact Deleted by Merge',
3078 $this->assertEquals($activity['id'], $activity2['parent_id']);
3079 $this->assertEquals('Normal', civicrm_api3('option_value', 'getvalue', array(
3080 'value' => $activity['priority_id'],
3081 'return' => 'label',
3082 'option_group_id' => 'priority',
3088 * Test merging 2 contacts with delete to trash off.
3090 * We are checking that there is no error due to attempting to add an activity for the
3095 public function testMergeNoTrash() {
3096 $this->createLoggedInUser();
3097 $this->callAPISuccess('Setting', 'create', array('contact_undelete' => FALSE));
3098 $otherContact = $this->callAPISuccess('contact', 'create', $this->_params
);
3099 $retainedContact = $this->callAPISuccess('contact', 'create', $this->_params
);
3100 $this->callAPISuccess('contact', 'merge', array(
3101 'to_keep_id' => $retainedContact['id'],
3102 'to_remove_id' => $otherContact['id'],
3103 'auto_flip' => FALSE,
3105 $this->callAPISuccess('Setting', 'create', array('contact_undelete' => TRUE));
3109 * Ensure format with return=group shows comma-separated group IDs.
3113 public function testContactGetReturnGroup() {
3114 // Set up a contact, asser that they were created.
3115 $contact_params = array(
3116 'contact_type' => 'Individual',
3117 'first_name' => 'Test',
3118 'last_name' => 'Groupmember',
3119 'email' => 'test@example.org',
3121 $create_contact = $this->callApiSuccess('Contact', 'create', $contact_params);
3122 $this->assertEquals(0, $create_contact['is_error']);
3123 $this->assertInternalType('int', $create_contact['id']);
3125 $created_contact_id = $create_contact['id'];
3127 // Set up multiple groups, add the contact to the groups.
3128 $test_groups = array('Test group A', 'Test group B');
3129 foreach ($test_groups as $title) {
3130 // Use this contact as group owner, since we know they exist.
3131 $group_params = array(
3133 'created_id' => $created_contact_id,
3135 $create_group = $this->callApiSuccess('Group', 'create', $group_params);
3136 $this->assertEquals(0, $create_group['is_error']);
3137 $this->assertInternalType('int', $create_group['id']);
3139 $created_group_ids[] = $create_group['id'];
3141 // Add contact to the new group.
3142 $group_contact_params = array(
3143 'contact_id' => $created_contact_id,
3144 'group_id' => $create_group['id'],
3146 $create_group_contact = $this->callApiSuccess('GroupContact', 'create', $group_contact_params);
3147 $this->assertEquals(0, $create_group_contact['is_error']);
3148 $this->assertInternalType('int', $create_group_contact['added']);
3151 // Use the Contact,get API to retrieve the contact
3152 $contact_get_params = array(
3153 'id' => $created_contact_id,
3154 'return' => 'group',
3156 $contact_get = $this->callApiSuccess('Contact', 'get', $contact_get_params);
3157 $this->assertInternalType('array', $contact_get['values'][$created_contact_id]);
3158 $this->assertInternalType('string', $contact_get['values'][$created_contact_id]['groups']);
3160 // Ensure they are shown as being in each created group.
3161 $contact_group_ids = explode(',', $contact_get['values'][$created_contact_id]['groups']);
3162 foreach ($created_group_ids as $created_group_id) {
3163 $this->assertContains($created_group_id, $contact_group_ids);
3168 * CRM-20144 Verify that passing title of group works as well as id
3169 * Tests the following formats
3170 * contact.get group='title1'
3171 * contact.get group=id1
3173 public function testContactGetWithGroupTitle() {
3174 // Set up a contact, asser that they were created.
3175 $contact_params = array(
3176 'contact_type' => 'Individual',
3177 'first_name' => 'Test2',
3178 'last_name' => 'Groupmember',
3179 'email' => 'test@example.org',
3181 $create_contact = $this->callApiSuccess('Contact', 'create', $contact_params);
3182 $created_contact_id = $create_contact['id'];
3183 // Set up multiple groups, add the contact to the groups.
3184 $test_groups = array('Test group C', 'Test group D');
3185 foreach ($test_groups as $title) {
3186 $group_params = array(
3188 'created_id' => $created_contact_id,
3190 $create_group = $this->callApiSuccess('Group', 'create', $group_params);
3191 $created_group_id = $create_group['id'];
3193 // Add contact to the new group.
3194 $group_contact_params = array(
3195 'contact_id' => $created_contact_id,
3196 'group_id' => $create_group['id'],
3198 $create_group_contact = $this->callApiSuccess('GroupContact', 'create', $group_contact_params);
3199 $contact_get = $this->callAPISuccess('contact', 'get', array('group' => $title, 'return' => 'group'));
3200 $this->assertEquals(1, $contact_get['count']);
3201 $this->assertEquals($created_contact_id, $contact_get['id']);
3202 $contact_groups = explode(',', $contact_get['values'][$created_contact_id]['groups']);
3203 $this->assertContains((string) $create_group['id'], $contact_groups);
3204 $contact_get2 = $this->callAPISuccess('contact', 'get', array('group' => $created_group_id, 'return' => 'group'));
3205 $this->assertEquals($created_contact_id, $contact_get2['id']);
3206 $contact_groups2 = explode(',', $contact_get2['values'][$created_contact_id]['groups']);
3207 $this->assertContains((string) $create_group['id'], $contact_groups2);
3208 $this->callAPISuccess('group', 'delete', array('id' => $created_group_id));
3210 $this->callAPISuccess('contact', 'delete', array('id' => $created_contact_id, 'skip_undelete' => TRUE));
3214 * CRM-20144 Verify that passing title of group works as well as id
3215 * Tests the following formats
3216 * contact.get group=array('title1', title1)
3217 * contact.get group=array('IN' => array('title1', 'title2)
3219 public function testContactGetWithGroupTitleMultipleGroups() {
3220 $description = "Get all from group and display contacts.";
3221 $subFile = "GroupFilterUsingContactAPI";
3222 // Set up a contact, asser that they were created.
3223 $contact_params = array(
3224 'contact_type' => 'Individual',
3225 'first_name' => 'Test2',
3226 'last_name' => 'Groupmember',
3227 'email' => 'test@example.org',
3229 $create_contact = $this->callApiSuccess('Contact', 'create', $contact_params);
3230 $created_contact_id = $create_contact['id'];
3231 $createdGroupsTitles = $createdGroupsIds = array();
3232 // Set up multiple groups, add the contact to the groups.
3233 $test_groups = array('Test group C', 'Test group D');
3234 foreach ($test_groups as $title) {
3235 $group_params = array(
3237 'created_id' => $created_contact_id,
3239 $create_group = $this->callApiSuccess('Group', 'create', $group_params);
3240 $created_group_id = $create_group['id'];
3241 $createdGroupsIds[] = $create_group['id'];
3242 $createdGroupTitles[] = $title;
3243 // Add contact to the new group.
3244 $group_contact_params = array(
3245 'contact_id' => $created_contact_id,
3246 'group_id' => $create_group['id'],
3248 $create_group_contact = $this->callApiSuccess('GroupContact', 'create', $group_contact_params);
3250 $contact_get = $this->callAPISuccess('contact', 'get', array('group' => $createdGroupTitles, 'return' => 'group'));
3251 $this->assertEquals(1, $contact_get['count']);
3252 $this->assertEquals($created_contact_id, $contact_get['id']);
3253 $contact_groups = explode(',', $contact_get['values'][$created_contact_id]['groups']);
3254 foreach ($createdGroupsIds as $id) {
3255 $this->assertContains((string) $id, $contact_groups);
3257 $contact_get2 = $this->callAPIAndDocument('contact', 'get', array('group' => array('IN' => $createdGroupTitles)), __FUNCTION__
, __FILE__
, $description, $subFile);
3258 $contact_get2 = $this->callAPISuccess('contact', 'get', array('group' => array('IN' => $createdGroupTitles), 'return' => 'group'));
3259 $this->assertEquals($created_contact_id, $contact_get2['id']);
3260 $contact_groups2 = explode(',', $contact_get2['values'][$created_contact_id]['groups']);
3261 foreach ($createdGroupsIds as $id) {
3262 $this->assertContains((string) $id, $contact_groups2);
3264 foreach ($createdGroupsIds as $id) {
3265 $this->callAPISuccess('group', 'delete', array('id' => $id));
3267 $this->callAPISuccess('contact', 'delete', array('id' => $created_contact_id, 'skip_undelete' => TRUE));
3271 * CRM-20144 Verify that passing title of group works as well as id
3272 * Tests the following formats
3273 * contact.get group=array('title1' => 1)
3274 * contact.get group=array('titke1' => 1, 'title2' => 1)
3275 * contact.get group=array('id1' => 1)
3276 * contact.get group=array('id1' => 1, id2 => 1)
3278 public function testContactGetWithGroupTitleMultipleGroupsLegacyFormat() {
3279 // Set up a contact, asser that they were created.
3280 $contact_params = array(
3281 'contact_type' => 'Individual',
3282 'first_name' => 'Test2',
3283 'last_name' => 'Groupmember',
3284 'email' => 'test@example.org',
3286 $create_contact = $this->callApiSuccess('Contact', 'create', $contact_params);
3287 $created_contact_id = $create_contact['id'];
3288 $createdGroupsTitles = $createdGroupsIds = array();
3289 // Set up multiple groups, add the contact to the groups.
3290 $test_groups = array('Test group C', 'Test group D');
3291 foreach ($test_groups as $title) {
3292 $group_params = array(
3294 'created_id' => $created_contact_id,
3296 $create_group = $this->callApiSuccess('Group', 'create', $group_params);
3297 $created_group_id = $create_group['id'];
3298 $createdGroupsIds[] = $create_group['id'];
3299 $createdGroupTitles[] = $title;
3300 // Add contact to the new group.
3301 $group_contact_params = array(
3302 'contact_id' => $created_contact_id,
3303 'group_id' => $create_group['id'],
3305 $create_group_contact = $this->callApiSuccess('GroupContact', 'create', $group_contact_params);
3307 $contact_get = $this->callAPISuccess('contact', 'get', array('group' => array($createdGroupTitles[0] => 1), 'return' => 'group'));
3308 $this->assertEquals(1, $contact_get['count']);
3309 $this->assertEquals($created_contact_id, $contact_get['id']);
3310 $contact_groups = explode(',', $contact_get['values'][$created_contact_id]['groups']);
3311 foreach ($createdGroupsIds as $id) {
3312 $this->assertContains((string) $id, $contact_groups);
3314 $contact_get2 = $this->callAPISuccess('contact', 'get', array('group' => array($createdGroupTitles[0] => 1, $createdGroupTitles[1] => 1), 'return' => 'group'));
3315 $this->assertEquals(1, $contact_get2['count']);
3316 $this->assertEquals($created_contact_id, $contact_get2['id']);
3317 $contact_groups2 = explode(',', $contact_get2['values'][$created_contact_id]['groups']);
3318 foreach ($createdGroupsIds as $id) {
3319 $this->assertContains((string) $id, $contact_groups2);
3321 $contact_get3 = $this->callAPISuccess('contact', 'get', array('group' => array($createdGroupsIds[0] => 1), 'return' => 'group'));
3322 $this->assertEquals($created_contact_id, $contact_get3['id']);
3323 $contact_groups3 = explode(',', $contact_get3['values'][$created_contact_id]['groups']);
3324 foreach ($createdGroupsIds as $id) {
3325 $this->assertContains((string) $id, $contact_groups3);
3327 $contact_get4 = $this->callAPISuccess('contact', 'get', array('group' => array($createdGroupsIds[0] => 1, $createdGroupsIds[1] => 1), 'return' => 'group'));
3328 $this->assertEquals($created_contact_id, $contact_get4['id']);
3329 $contact_groups4 = explode(',', $contact_get4['values'][$created_contact_id]['groups']);
3330 foreach ($createdGroupsIds as $id) {
3331 $this->assertContains((string) $id, $contact_groups4);
3333 foreach ($createdGroupsIds as $id) {
3334 $this->callAPISuccess('group', 'delete', array('id' => $id));
3336 $this->callAPISuccess('contact', 'delete', array('id' => $created_contact_id, 'skip_undelete' => TRUE));