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 attempt to create contact with empty params fails.
205 public function testCreateEmptyContact() {
206 $this->callAPIFailure('contact', 'create', array());
210 * Verify that attempt to create contact with bad contact type fails.
212 public function testCreateBadTypeContact() {
214 'email' => 'man1@yahoo.com',
215 'contact_type' => 'Does not Exist',
217 $this->callAPIFailure('contact', 'create', $params, "'Does not Exist' is not a valid option for field contact_type");
221 * Verify that attempt to create individual contact without required fields fails.
223 public function testCreateBadRequiredFieldsIndividual() {
225 'middle_name' => 'This field is not required',
226 'contact_type' => 'Individual',
228 $this->callAPIFailure('contact', 'create', $params);
232 * Verify that attempt to create household contact without required fields fails.
234 public function testCreateBadRequiredFieldsHousehold() {
236 'middle_name' => 'This field is not required',
237 'contact_type' => 'Household',
239 $this->callAPIFailure('contact', 'create', $params);
243 * Test required field check.
245 * Verify that attempt to create organization contact without required fields fails.
247 public function testCreateBadRequiredFieldsOrganization() {
249 'middle_name' => 'This field is not required',
250 'contact_type' => 'Organization',
253 $this->callAPIFailure('contact', 'create', $params);
257 * Verify that attempt to create individual contact with only an email succeeds.
259 public function testCreateEmailIndividual() {
262 'email' => 'man3@yahoo.com',
263 'contact_type' => 'Individual',
264 'location_type_id' => 1,
267 $contact = $this->callAPISuccess('contact', 'create', $params);
269 $this->assertEquals(3, $contact['id']);
270 $email = $this->callAPISuccess('email', 'get', array('contact_id' => $contact['id']));
271 $this->assertEquals(1, $email['count']);
272 $this->assertEquals('man3@yahoo.com', $email['values'][$email['id']]['email']);
274 $this->callAPISuccess('contact', 'delete', $contact);
278 * Test creating individual by name.
280 * Verify create individual contact with only first and last names succeeds.
282 public function testCreateNameIndividual() {
284 'first_name' => 'abc1',
285 'contact_type' => 'Individual',
286 'last_name' => 'xyz1',
289 $this->callAPISuccess('contact', 'create', $params);
293 * Test creating individual by display_name.
295 * Display name & sort name should be set.
297 public function testCreateDisplayNameIndividual() {
299 'display_name' => 'abc1',
300 'contact_type' => 'Individual',
303 $contact = $this->callAPISuccess('contact', 'create', $params);
304 $params['sort_name'] = 'abc1';
305 $this->getAndCheck($params, $contact['id'], 'contact');
309 * Test old keys still work.
311 * Verify that attempt to create individual contact with
312 * first and last names and old key values works
314 public function testCreateNameIndividualOldKeys() {
316 'individual_prefix' => 'Dr.',
317 'first_name' => 'abc1',
318 'contact_type' => 'Individual',
319 'last_name' => 'xyz1',
320 'individual_suffix' => 'Jr.',
323 $contact = $this->callAPISuccess('contact', 'create', $params);
324 $result = $this->callAPISuccess('contact', 'getsingle', array('id' => $contact['id']));
326 $this->assertArrayKeyExists('prefix_id', $result);
327 $this->assertArrayKeyExists('suffix_id', $result);
328 $this->assertArrayKeyExists('gender_id', $result);
329 $this->assertEquals(4, $result['prefix_id']);
330 $this->assertEquals(1, $result['suffix_id']);
334 * Test preferred keys work.
336 * Verify that attempt to create individual contact with
337 * first and last names and old key values works
339 public function testCreateNameIndividualRecommendedKeys2() {
341 'prefix_id' => 'Dr.',
342 'first_name' => 'abc1',
343 'contact_type' => 'Individual',
344 'last_name' => 'xyz1',
345 'suffix_id' => 'Jr.',
346 'gender_id' => 'Male',
349 $contact = $this->callAPISuccess('contact', 'create', $params);
350 $result = $this->callAPISuccess('contact', 'getsingle', array('id' => $contact['id']));
352 $this->assertArrayKeyExists('prefix_id', $result);
353 $this->assertArrayKeyExists('suffix_id', $result);
354 $this->assertArrayKeyExists('gender_id', $result);
355 $this->assertEquals(4, $result['prefix_id']);
356 $this->assertEquals(1, $result['suffix_id']);
360 * Test household name is sufficient for create.
362 * Verify that attempt to create household contact with only
363 * household name succeeds
365 public function testCreateNameHousehold() {
367 'household_name' => 'The abc Household',
368 'contact_type' => 'Household',
370 $this->callAPISuccess('contact', 'create', $params);
374 * Test organization name is sufficient for create.
376 * Verify that attempt to create organization contact with only
377 * organization name succeeds.
379 public function testCreateNameOrganization() {
381 'organization_name' => 'The abc Organization',
382 'contact_type' => 'Organization',
384 $this->callAPISuccess('contact', 'create', $params);
388 * Verify that attempt to create organization contact without organization name fails.
390 public function testCreateNoNameOrganization() {
392 'first_name' => 'The abc Organization',
393 'contact_type' => 'Organization',
395 $this->callAPIFailure('contact', 'create', $params);
399 * Check with complete array + custom field.
401 * Note that the test is written on purpose without any
402 * variables specific to participant so it can be replicated into other entities
403 * and / or moved to the automated test suite
405 public function testCreateWithCustom() {
406 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__
, __FILE__
);
408 $params = $this->_params
;
409 $params['custom_' . $ids['custom_field_id']] = "custom string";
410 $description = "This demonstrates setting a custom field through the API.";
411 $result = $this->callAPIAndDocument($this->_entity
, 'create', $params, __FUNCTION__
, __FILE__
, $description);
413 $check = $this->callAPISuccess($this->_entity
, 'get', array(
414 'return.custom_' . $ids['custom_field_id'] => 1,
415 'id' => $result['id'],
417 $this->assertEquals("custom string", $check['values'][$check['id']]['custom_' . $ids['custom_field_id']]);
419 $this->customFieldDelete($ids['custom_field_id']);
420 $this->customGroupDelete($ids['custom_group_id']);
424 * CRM-12773 - expectation is that civicrm quietly ignores fields without values.
426 public function testCreateWithNULLCustomCRM12773() {
427 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__
, __FILE__
);
428 $params = $this->_params
;
429 $params['custom_' . $ids['custom_field_id']] = NULL;
430 $this->callAPISuccess('contact', 'create', $params);
431 $this->customFieldDelete($ids['custom_field_id']);
432 $this->customGroupDelete($ids['custom_group_id']);
436 * CRM-14232 test preferred language set to site default if not passed.
438 public function testCreatePreferredLanguageUnset() {
439 $this->callAPISuccess('Contact', 'create', array(
440 'first_name' => 'Snoop',
441 'last_name' => 'Dog',
442 'contact_type' => 'Individual')
444 $result = $this->callAPISuccessGetSingle('Contact', array('last_name' => 'Dog'));
445 $this->assertEquals('en_US', $result['preferred_language']);
449 * CRM-14232 test preferred language returns setting if not passed.
451 public function testCreatePreferredLanguageSet() {
452 $this->callAPISuccess('Setting', 'create', array('contact_default_language' => 'fr_FR'));
453 $this->callAPISuccess('Contact', 'create', array(
454 'first_name' => 'Snoop',
455 'last_name' => 'Dog',
456 'contact_type' => 'Individual',
458 $result = $this->callAPISuccessGetSingle('Contact', array('last_name' => 'Dog'));
459 $this->assertEquals('fr_FR', $result['preferred_language']);
463 * CRM-14232 test preferred language returns setting if not passed where setting is NULL.
465 public function testCreatePreferredLanguageNull() {
466 $this->callAPISuccess('Setting', 'create', array('contact_default_language' => 'null'));
467 $this->callAPISuccess('Contact', 'create', array(
468 'first_name' => 'Snoop',
469 'last_name' => 'Dog',
470 'contact_type' => 'Individual',
473 $result = $this->callAPISuccessGetSingle('Contact', array('last_name' => 'Dog'));
474 $this->assertEquals(NULL, $result['preferred_language']);
478 * CRM-14232 test preferred language returns setting if not passed where setting is NULL.
480 public function testCreatePreferredLanguagePassed() {
481 $this->callAPISuccess('Setting', 'create', array('contact_default_language' => 'null'));
482 $this->callAPISuccess('Contact', 'create', array(
483 'first_name' => 'Snoop',
484 'last_name' => 'Dog',
485 'contact_type' => 'Individual',
486 'preferred_language' => 'en_AU',
488 $result = $this->callAPISuccessGetSingle('Contact', array('last_name' => 'Dog'));
489 $this->assertEquals('en_AU', $result['preferred_language']);
493 * CRM-15792 - create/update datetime field for contact.
495 public function testCreateContactCustomFldDateTime() {
496 $customGroup = $this->customGroupCreate(array('extends' => 'Individual', 'title' => 'datetime_test_group'));
497 $dateTime = CRM_Utils_Date
::currentDBDate();
498 //check date custom field is saved along with time when time_format is set
500 'first_name' => 'abc3',
501 'last_name' => 'xyz3',
502 'contact_type' => 'Individual',
503 'email' => 'man3@yahoo.com',
504 'api.CustomField.create' => array(
505 'custom_group_id' => $customGroup['id'],
506 'name' => 'test_datetime',
507 'label' => 'Demo Date',
508 'html_type' => 'Select Date',
509 'data_type' => 'Date',
513 'is_searchable' => 0,
518 $result = $this->callAPIAndDocument('Contact', 'create', $params, __FUNCTION__
, __FILE__
);
519 $customFldId = $result['values'][$result['id']]['api.CustomField.create']['id'];
520 $this->assertNotNull($result['id']);
521 $this->assertNotNull($customFldId);
524 'id' => $result['id'],
525 "custom_{$customFldId}" => $dateTime,
526 'api.CustomValue.get' => 1,
529 $result = $this->callAPIAndDocument('Contact', 'create', $params, __FUNCTION__
, __FILE__
);
530 $this->assertNotNull($result['id']);
531 $customFldDate = date("YmdHis", strtotime($result['values'][$result['id']]['api.CustomValue.get']['values'][0]['latest']));
532 $this->assertNotNull($customFldDate);
533 $this->assertEquals($dateTime, $customFldDate);
534 $customValueId = $result['values'][$result['id']]['api.CustomValue.get']['values'][0]['id'];
535 $dateTime = date('Ymd');
536 //date custom field should not contain time part when time_format is null
538 'id' => $result['id'],
539 'api.CustomField.create' => array(
540 'id' => $customFldId,
541 'html_type' => 'Select Date',
542 'data_type' => 'Date',
545 'api.CustomValue.create' => array(
546 'id' => $customValueId,
547 'entity_id' => $result['id'],
548 "custom_{$customFldId}" => $dateTime,
550 'api.CustomValue.get' => 1,
552 $result = $this->callAPIAndDocument('Contact', 'create', $params, __FUNCTION__
, __FILE__
);
553 $this->assertNotNull($result['id']);
554 $customFldDate = date("Ymd", strtotime($result['values'][$result['id']]['api.CustomValue.get']['values'][0]['latest']));
555 $customFldTime = date("His", strtotime($result['values'][$result['id']]['api.CustomValue.get']['values'][0]['latest']));
556 $this->assertNotNull($customFldDate);
557 $this->assertEquals($dateTime, $customFldDate);
558 $this->assertEquals(000000, $customFldTime);
559 $this->callAPIAndDocument('Contact', 'create', $params, __FUNCTION__
, __FILE__
);
564 * Test creating a current employer through API.
566 public function testContactCreateCurrentEmployer() {
567 // Here we will just do the get for set-up purposes.
568 $count = $this->callAPISuccess('contact', 'getcount', array(
569 'organization_name' => 'new employer org',
570 'contact_type' => 'Organization',
572 $this->assertEquals(0, $count);
573 $employerResult = $this->callAPISuccess('contact', 'create', array_merge($this->_params
, array(
574 'current_employer' => 'new employer org',
577 // do it again as an update to check it doesn't cause an error
578 $employerResult = $this->callAPISuccess('contact', 'create', array_merge($this->_params
, array(
579 'current_employer' => 'new employer org',
580 'id' => $employerResult['id'],
584 $this->callAPISuccess('contact', 'getcount', array(
585 'organization_name' => 'new employer org',
586 'contact_type' => 'Organization',
590 $result = $this->callAPISuccess('contact', 'getsingle', array(
591 'id' => $employerResult['id'],
594 $this->assertEquals('new employer org', $result['current_employer']);
599 * Test creating a current employer through API.
601 * Check it will re-activate a de-activated employer
603 public function testContactCreateDuplicateCurrentEmployerEnables() {
604 // Set up - create employer relationship.
605 $employerResult = $this->callAPISuccess('contact', 'create', array_merge($this->_params
, array(
606 'current_employer' => 'new employer org',
609 $relationship = $this->callAPISuccess('relationship', 'get', array(
610 'contact_id_a' => $employerResult['id'],
613 //disable & check it is disabled
614 $this->callAPISuccess('relationship', 'create', array('id' => $relationship['id'], 'is_active' => 0));
615 $this->callAPISuccess('relationship', 'getvalue', array(
616 'id' => $relationship['id'],
617 'return' => 'is_active',
620 // Re-set the current employer - thus enabling the relationship.
621 $this->callAPISuccess('contact', 'create', array_merge($this->_params
, array(
622 'current_employer' => 'new employer org',
623 'id' => $employerResult['id'],
626 //check is_active is now 1
627 $relationship = $this->callAPISuccess('relationship', 'getsingle', array(
628 'return' => 'is_active',
630 $this->assertEquals(1, $relationship['is_active']);
634 * Check deceased contacts are not retrieved.
636 * Note at time of writing the default is to return default. This should possibly be changed & test added.
638 public function testGetDeceasedRetrieved() {
639 $this->callAPISuccess($this->_entity
, 'create', $this->_params
);
640 $c2 = $this->callAPISuccess($this->_entity
, 'create', array(
641 'first_name' => 'bb',
642 'last_name' => 'ccc',
643 'contact_type' => 'Individual',
646 $result = $this->callAPISuccess($this->_entity
, 'get', array('is_deceased' => 0));
647 $this->assertFalse(array_key_exists($c2['id'], $result['values']));
651 * Test that sort works - old syntax.
653 public function testGetSort() {
654 $c1 = $this->callAPISuccess($this->_entity
, 'create', $this->_params
);
655 $c2 = $this->callAPISuccess($this->_entity
, 'create', array(
656 'first_name' => 'bb',
657 'last_name' => 'ccc',
658 'contact_type' => 'Individual',
660 $result = $this->callAPISuccess($this->_entity
, 'get', array(
661 'sort' => 'first_name ASC',
662 'return.first_name' => 1,
665 'contact_type' => 'Individual',
668 $this->assertEquals('abc1', $result['values'][0]['first_name']);
669 $result = $this->callAPISuccess($this->_entity
, 'get', array(
670 'sort' => 'first_name DESC',
671 'return.first_name' => 1,
675 $this->assertEquals('bb', $result['values'][0]['first_name']);
677 $this->callAPISuccess($this->_entity
, 'delete', array('id' => $c1['id']));
678 $this->callAPISuccess($this->_entity
, 'delete', array('id' => $c2['id']));
682 * Test that we can retrieve contacts using array syntax.
684 * I.e 'id' => array('IN' => array('3,4')).
686 public function testGetINIDArray() {
687 $c1 = $this->callAPISuccess($this->_entity
, 'create', $this->_params
);
688 $c2 = $this->callAPISuccess($this->_entity
, 'create', array(
689 'first_name' => 'bb',
690 'last_name' => 'ccc',
691 'contact_type' => 'Individual',
693 $c3 = $this->callAPISuccess($this->_entity
, 'create', array(
694 'first_name' => 'hh',
696 'contact_type' => 'Individual',
698 $result = $this->callAPISuccess($this->_entity
, 'get', array('id' => array('IN' => array($c1['id'], $c3['id']))));
699 $this->assertEquals(2, $result['count']);
700 $this->assertEquals(array($c1['id'], $c3['id']), array_keys($result['values']));
701 $this->callAPISuccess($this->_entity
, 'delete', array('id' => $c1['id']));
702 $this->callAPISuccess($this->_entity
, 'delete', array('id' => $c2['id']));
703 $this->callAPISuccess($this->_entity
, 'delete', array('id' => $c3['id']));
707 * Test variants on deleted behaviour.
709 public function testGetDeleted() {
710 $params = $this->_params
;
711 $contact1 = $this->callAPISuccess('contact', 'create', $params);
712 $params['is_deleted'] = 1;
713 $params['last_name'] = 'bcd';
714 $contact2 = $this->callAPISuccess('contact', 'create', $params);
715 $countActive = $this->callAPISuccess('contact', 'getcount', array(
716 'showAll' => 'active',
717 'contact_type' => 'Individual',
719 $countAll = $this->callAPISuccess('contact', 'getcount', array('showAll' => 'all', 'contact_type' => 'Individual'));
720 $countTrash = $this->callAPISuccess('contact', 'getcount', array('showAll' => 'trash', 'contact_type' => 'Individual'));
721 $countDefault = $this->callAPISuccess('contact', 'getcount', array('contact_type' => 'Individual'));
722 $countDeleted = $this->callAPISuccess('contact', 'getcount', array(
723 'contact_type' => 'Individual',
724 'contact_is_deleted' => 1,
726 $countNotDeleted = $this->callAPISuccess('contact', 'getcount', array(
727 'contact_is_deleted' => 0,
728 'contact_type' => 'Individual',
730 $this->callAPISuccess('contact', 'delete', array('id' => $contact1['id']));
731 $this->callAPISuccess('contact', 'delete', array('id' => $contact2['id']));
732 $this->assertEquals(1, $countNotDeleted, 'contact_is_deleted => 0 is respected');
733 $this->assertEquals(1, $countActive);
734 $this->assertEquals(1, $countTrash);
735 $this->assertEquals(2, $countAll);
736 $this->assertEquals(1, $countDeleted);
737 $this->assertEquals(1, $countDefault, 'Only active by default in line');
741 * Test that sort works - new syntax.
743 public function testGetSortNewSyntax() {
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 $result = $this->callAPISuccess($this->_entity
, 'getvalue', array(
751 'return' => 'first_name',
752 'contact_type' => 'Individual',
755 'sort' => 'first_name',
758 $this->assertEquals('abc1', $result);
760 $result = $this->callAPISuccess($this->_entity
, 'getvalue', array(
761 'return' => 'first_name',
762 'contact_type' => 'Individual',
765 'sort' => 'first_name DESC',
768 $this->assertEquals('bb', $result);
770 $this->callAPISuccess($this->_entity
, 'delete', array('id' => $c1['id']));
771 $this->callAPISuccess($this->_entity
, 'delete', array('id' => $c2['id']));
775 * Test sort and limit for chained relationship get.
777 * https://issues.civicrm.org/jira/browse/CRM-15983
779 public function testSortLimitChainedRelationshipGetCRM15983() {
781 $create_result_1 = $this->callAPISuccess('contact', 'create', array(
782 'first_name' => 'Jules',
783 'last_name' => 'Smos',
784 'contact_type' => 'Individual',
787 // Create another contact with two relationships.
788 $create_params = array(
789 'first_name' => 'Jos',
790 'last_name' => 'Smos',
791 'contact_type' => 'Individual',
792 'api.relationship.create' => array(
794 'contact_id_a' => '$value.id',
795 'contact_id_b' => $create_result_1['id'],
797 'relationship_type_id' => 2,
798 'start_date' => '2005-01-12',
799 'end_date' => '2006-01-11',
800 'description' => 'old',
803 'contact_id_a' => '$value.id',
804 'contact_id_b' => $create_result_1['id'],
805 // spouse of (was married twice :))
806 'relationship_type_id' => 2,
807 'start_date' => '2006-07-01',
808 'end_date' => '2010-07-01',
809 'description' => 'new',
813 $create_result = $this->callAPISuccess('contact', 'create', $create_params);
815 // Try to retrieve the contact and the most recent relationship.
818 'id' => $create_result['id'],
819 'api.relationship.get' => array(
820 'contact_id_a' => '$value.id',
823 'sort' => 'start_date DESC',
826 $get_result = $this->callAPISuccess('contact', 'getsingle', $get_params);
829 $this->callAPISuccess('contact', 'delete', array(
830 'id' => $create_result['id'],
834 $this->assertEquals(1, $get_result['api.relationship.get']['count']);
835 $this->assertEquals('new', $get_result['api.relationship.get']['values'][0]['description']);
839 * Test apostrophe works in get & create.
841 public function testGetApostropheCRM10857() {
842 $params = array_merge($this->_params
, array('last_name' => "O'Connor"));
843 $this->callAPISuccess($this->_entity
, 'create', $params);
844 $result = $this->callAPISuccess($this->_entity
, 'getsingle', array(
845 'last_name' => "O'Connor",
848 $this->assertEquals("O'Connor", $result['last_name'], 'in line' . __LINE__
);
852 * Check with complete array + custom field.
854 * Note that the test is written on purpose without any
855 * variables specific to participant so it can be replicated into other entities
856 * and / or moved to the automated test suite
858 public function testGetWithCustom() {
859 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__
, __FILE__
);
861 $params = $this->_params
;
862 $params['custom_' . $ids['custom_field_id']] = "custom string";
863 $description = "This demonstrates setting a custom field through the API.";
864 $subfile = "CustomFieldGet";
865 $result = $this->callAPISuccess($this->_entity
, 'create', $params);
867 $check = $this->callAPIAndDocument($this->_entity
, 'get', array(
868 'return.custom_' . $ids['custom_field_id'] => 1,
869 'id' => $result['id'],
870 ), __FUNCTION__
, __FILE__
, $description, $subfile);
872 $this->assertEquals("custom string", $check['values'][$check['id']]['custom_' . $ids['custom_field_id']]);
873 $fields = ($this->callAPISuccess('contact', 'getfields', $params));
874 $this->assertTrue(is_array($fields['values']['custom_' . $ids['custom_field_id']]));
875 $this->customFieldDelete($ids['custom_field_id']);
876 $this->customGroupDelete($ids['custom_group_id']);
880 * Check with complete array + custom field.
882 * Note that the test is written on purpose without any
883 * variables specific to participant so it can be replicated into other entities
884 * and / or moved to the automated test suite
886 public function testGetWithCustomReturnSyntax() {
887 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__
, __FILE__
);
889 $params = $this->_params
;
890 $params['custom_' . $ids['custom_field_id']] = "custom string";
891 $description = "This demonstrates setting a custom field through the API.";
892 $subfile = "CustomFieldGetReturnSyntaxVariation";
893 $result = $this->callAPISuccess($this->_entity
, 'create', $params);
894 $params = array('return' => 'custom_' . $ids['custom_field_id'], 'id' => $result['id']);
895 $check = $this->callAPIAndDocument($this->_entity
, 'get', $params, __FUNCTION__
, __FILE__
, $description, $subfile);
897 $this->assertEquals("custom string", $check['values'][$check['id']]['custom_' . $ids['custom_field_id']]);
898 $this->customFieldDelete($ids['custom_field_id']);
899 $this->customGroupDelete($ids['custom_group_id']);
903 * Check that address name, ID is returned if required.
905 public function testGetReturnAddress() {
906 $contactID = $this->individualCreate();
907 $result = $this->callAPISuccess('address', 'create', array(
908 'contact_id' => $contactID,
909 'address_name' => 'My house',
910 'location_type_id' => 'Home',
911 'street_address' => '1 my road',
913 $addressID = $result['id'];
915 $result = $this->callAPISuccessGetSingle('contact', array(
916 'return' => 'address_name, street_address, address_id',
919 $this->assertEquals($addressID, $result['address_id']);
920 $this->assertEquals('1 my road', $result['street_address']);
921 $this->assertEquals('My house', $result['address_name']);
926 * Test group filter syntaxes.
928 public function testGetGroupIDFromContact() {
929 $groupId = $this->groupCreate();
930 $description = "Get all from group and display contacts.";
931 $subFile = "GroupFilterUsingContactAPI";
933 'email' => 'man2@yahoo.com',
934 'contact_type' => 'Individual',
935 'location_type_id' => 1,
936 'api.group_contact.create' => array('group_id' => $groupId),
939 $this->callAPISuccess('contact', 'create', $params);
940 // testing as integer
942 'filter.group_id' => $groupId,
943 'contact_type' => 'Individual',
945 $result = $this->callAPIAndDocument('contact', 'get', $params, __FUNCTION__
, __FILE__
, $description, $subFile);
946 $this->assertEquals(1, $result['count']);
947 // group 26 doesn't exist, but we can still search contacts in it.
949 'filter.group_id' => 26,
950 'contact_type' => 'Individual',
952 $this->callAPISuccess('contact', 'get', $params);
955 'filter.group_id' => "$groupId, 26",
956 'contact_type' => 'Individual',
958 $result = $this->callAPIAndDocument('contact', 'get', $params, __FUNCTION__
, __FILE__
, $description, $subFile);
959 $this->assertEquals(1, $result['count']);
961 'filter.group_id' => "26,27",
962 'contact_type' => 'Individual',
964 $this->callAPISuccess('contact', 'get', $params);
968 'filter.group_id' => array($groupId, 26),
969 'contact_type' => 'Individual',
971 $result = $this->callAPIAndDocument('contact', 'get', $params, __FUNCTION__
, __FILE__
, $description, $subFile);
972 $this->assertEquals(1, $result['count']);
974 //test in conjunction with other criteria
976 'filter.group_id' => array($groupId, 26),
977 'contact_type' => 'Organization',
979 $this->callAPISuccess('contact', 'get', $params);
981 'filter.group_id' => array(26, 27),
982 'contact_type' => 'Individual',
984 $result = $this->callAPISuccess('contact', 'get', $params);
985 $this->assertEquals(0, $result['count']);
989 * Verify that attempt to create individual contact with two chained websites succeeds.
991 public function testCreateIndividualWithContributionDottedSyntax() {
992 $description = "This demonstrates the syntax to create 2 chained entities.";
993 $subFile = "ChainTwoWebsites";
995 'first_name' => 'abc3',
996 'last_name' => 'xyz3',
997 'contact_type' => 'Individual',
998 'email' => 'man3@yahoo.com',
999 'api.contribution.create' => array(
1000 'receive_date' => '2010-01-01',
1001 'total_amount' => 100.00,
1002 'financial_type_id' => $this->_financialTypeId
,
1003 'payment_instrument_id' => 1,
1004 'non_deductible_amount' => 10.00,
1005 'fee_amount' => 50.00,
1006 'net_amount' => 90.00,
1008 'invoice_id' => 67990,
1010 'contribution_status_id' => 1,
1012 'api.website.create' => array(
1013 'url' => "http://civicrm.org",
1015 'api.website.create.2' => array(
1016 'url' => "http://chained.org",
1020 $result = $this->callAPIAndDocument('Contact', 'create', $params, __FUNCTION__
, __FILE__
, $description, $subFile);
1022 // checking child function result not covered in callAPIAndDocument
1023 $this->assertAPISuccess($result['values'][$result['id']]['api.website.create']);
1024 $this->assertEquals("http://chained.org", $result['values'][$result['id']]['api.website.create.2']['values'][0]['url']);
1025 $this->assertEquals("http://civicrm.org", $result['values'][$result['id']]['api.website.create']['values'][0]['url']);
1027 // delete the contact
1028 $this->callAPISuccess('contact', 'delete', $result);
1032 * Verify that attempt to create individual contact with chained contribution and website succeeds.
1034 public function testCreateIndividualWithContributionChainedArrays() {
1036 'first_name' => 'abc3',
1037 'last_name' => 'xyz3',
1038 'contact_type' => 'Individual',
1039 'email' => 'man3@yahoo.com',
1040 'api.contribution.create' => array(
1041 'receive_date' => '2010-01-01',
1042 'total_amount' => 100.00,
1043 'financial_type_id' => $this->_financialTypeId
,
1044 'payment_instrument_id' => 1,
1045 'non_deductible_amount' => 10.00,
1046 'fee_amount' => 50.00,
1047 'net_amount' => 90.00,
1049 'invoice_id' => 67890,
1051 'contribution_status_id' => 1,
1053 'api.website.create' => array(
1055 'url' => "http://civicrm.org",
1058 'url' => "http://chained.org",
1059 'website_type_id' => 2,
1064 $description = "Demonstrates creating two websites as an array.";
1065 $subfile = "ChainTwoWebsitesSyntax2";
1066 $result = $this->callAPIAndDocument('Contact', 'create', $params, __FUNCTION__
, __FILE__
, $description, $subfile);
1068 // the callAndDocument doesn't check the chained call
1069 $this->assertEquals(0, $result['values'][$result['id']]['api.website.create'][0]['is_error']);
1070 $this->assertEquals("http://chained.org", $result['values'][$result['id']]['api.website.create'][1]['values'][0]['url']);
1071 $this->assertEquals("http://civicrm.org", $result['values'][$result['id']]['api.website.create'][0]['values'][0]['url']);
1073 $this->callAPISuccess('contact', 'delete', $result);
1077 * Test for direction when chaining relationships.
1079 * https://issues.civicrm.org/jira/browse/CRM-16084
1081 public function testDirectionChainingRelationshipsCRM16084() {
1082 // Some contact, called Jules.
1083 $create_result_1 = $this->callAPISuccess('contact', 'create', array(
1084 'first_name' => 'Jules',
1085 'last_name' => 'Smos',
1086 'contact_type' => 'Individual',
1089 // Another contact: Jos, child of Jules.
1090 $create_params = array(
1091 'first_name' => 'Jos',
1092 'last_name' => 'Smos',
1093 'contact_type' => 'Individual',
1094 'api.relationship.create' => array(
1096 'contact_id_a' => '$value.id',
1097 'contact_id_b' => $create_result_1['id'],
1099 'relationship_type_id' => 1,
1103 $create_result_2 = $this->callAPISuccess('contact', 'create', $create_params);
1105 // Mia is the child of Jos.
1106 $create_params = array(
1107 'first_name' => 'Mia',
1108 'last_name' => 'Smos',
1109 'contact_type' => 'Individual',
1110 'api.relationship.create' => array(
1112 'contact_id_a' => '$value.id',
1113 'contact_id_b' => $create_result_2['id'],
1115 'relationship_type_id' => 1,
1119 $create_result_3 = $this->callAPISuccess('contact', 'create', $create_params);
1121 // Get Jos and his children.
1122 $get_params = array(
1124 'id' => $create_result_2['id'],
1125 'api.relationship.get' => array(
1126 'contact_id_b' => '$value.id',
1127 'relationship_type_id' => 1,
1130 $get_result = $this->callAPISuccess('contact', 'getsingle', $get_params);
1133 $this->callAPISuccess('contact', 'delete', array(
1134 'id' => $create_result_1['id'],
1136 $this->callAPISuccess('contact', 'delete', array(
1137 'id' => $create_result_2['id'],
1139 $this->callAPISuccess('contact', 'delete', array(
1140 'id' => $create_result_2['id'],
1144 $this->assertEquals(1, $get_result['api.relationship.get']['count']);
1145 $this->assertEquals($create_result_3['id'], $get_result['api.relationship.get']['values'][0]['contact_id_a']);
1149 * Verify that attempt to create individual contact with first, and last names and email succeeds.
1151 public function testCreateIndividualWithNameEmail() {
1153 'first_name' => 'abc3',
1154 'last_name' => 'xyz3',
1155 'contact_type' => 'Individual',
1156 'email' => 'man3@yahoo.com',
1159 $contact = $this->callAPISuccess('contact', 'create', $params);
1161 $this->callAPISuccess('contact', 'delete', $contact);
1165 * Verify that attempt to create individual contact with no data fails.
1167 public function testCreateIndividualWithOutNameEmail() {
1169 'contact_type' => 'Individual',
1171 $this->callAPIFailure('contact', 'create', $params);
1175 * Test create individual contact with first &last names, email and location type succeeds.
1177 public function testCreateIndividualWithNameEmailLocationType() {
1179 'first_name' => 'abc4',
1180 'last_name' => 'xyz4',
1181 'email' => 'man4@yahoo.com',
1182 'contact_type' => 'Individual',
1183 'location_type_id' => 1,
1185 $result = $this->callAPISuccess('contact', 'create', $params);
1187 $this->callAPISuccess('contact', 'delete', array('id' => $result['id']));
1191 * Verify that when changing employers the old employer relationship becomes inactive.
1193 public function testCreateIndividualWithEmployer() {
1194 $employer = $this->organizationCreate();
1195 $employer2 = $this->organizationCreate();
1198 'email' => 'man4@yahoo.com',
1199 'contact_type' => 'Individual',
1200 'employer_id' => $employer,
1203 $result = $this->callAPISuccess('contact', 'create', $params);
1204 $relationships = $this->callAPISuccess('relationship', 'get', array(
1205 'contact_id_a' => $result['id'],
1209 $this->assertEquals($employer, $relationships['values'][0]['contact_id_b']);
1211 // Add more random relationships to make the test more realistic
1212 foreach (array('Employee of', 'Volunteer for') as $relationshipType) {
1213 $relTypeId = CRM_Core_DAO
::getFieldValue('CRM_Contact_DAO_RelationshipType', $relationshipType, 'id', 'name_a_b');
1214 $this->callAPISuccess('relationship', 'create', array(
1215 'contact_id_a' => $result['id'],
1216 'contact_id_b' => $this->organizationCreate(),
1218 'relationship_type_id' => $relTypeId,
1222 // Add second employer
1223 $params['employer_id'] = $employer2;
1224 $params['id'] = $result['id'];
1225 $result = $this->callAPISuccess('contact', 'create', $params);
1227 $relationships = $this->callAPISuccess('relationship', 'get', array(
1228 'contact_id_a' => $result['id'],
1233 $this->assertEquals($employer, $relationships['values'][0]['contact_id_b']);
1237 * Verify that attempt to create household contact with details succeeds.
1239 public function testCreateHouseholdDetails() {
1241 'household_name' => 'abc8\'s House',
1242 'nick_name' => 'x House',
1243 'email' => 'man8@yahoo.com',
1244 'contact_type' => 'Household',
1247 $contact = $this->callAPISuccess('contact', 'create', $params);
1249 $this->callAPISuccess('contact', 'delete', $contact);
1253 * Verify that attempt to create household contact with inadequate details fails.
1255 public function testCreateHouseholdInadequateDetails() {
1257 'nick_name' => 'x House',
1258 'email' => 'man8@yahoo.com',
1259 'contact_type' => 'Household',
1261 $this->callAPIFailure('contact', 'create', $params);
1265 * Verify successful update of individual contact.
1267 public function testUpdateIndividualWithAll() {
1268 // Insert a row in civicrm_contact creating individual contact.
1269 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1270 $op->execute($this->_dbconn
,
1271 $this->createXMLDataSet(
1272 dirname(__FILE__
) . '/dataset/contact_ind.xml'
1278 'first_name' => 'abcd',
1279 'contact_type' => 'Individual',
1280 'nick_name' => 'This is nickname first',
1281 'do_not_email' => '1',
1282 'do_not_phone' => '1',
1283 'do_not_mail' => '1',
1284 'do_not_trade' => '1',
1285 'legal_identifier' => 'ABC23853ZZ2235',
1286 'external_identifier' => '1928837465',
1287 'image_URL' => 'http://some.url.com/image.jpg',
1288 'home_url' => 'http://www.example.org',
1292 $this->callAPISuccess('Contact', 'Update', $params);
1293 $getResult = $this->callAPISuccess('Contact', 'Get', $params);
1294 unset($params['contact_id']);
1295 //Todo - neither API v2 or V3 are testing for home_url - not sure if it is being set.
1296 //reducing this test partially back to api v2 level to get it through
1297 unset($params['home_url']);
1298 foreach ($params as $key => $value) {
1299 $this->assertEquals($value, $getResult['values'][23][$key]);
1301 // Check updated civicrm_contact against expected.
1302 $expected = $this->createXMLDataSet(
1303 dirname(__FILE__
) . '/dataset/contact_ind_upd.xml'
1305 $actual = new PHPUnit_Extensions_Database_DataSet_QueryDataSet(
1308 $actual->addTable('civicrm_contact');
1309 $expected->matches($actual);
1313 * Verify successful update of organization contact.
1315 public function testUpdateOrganizationWithAll() {
1316 // Insert a row in civicrm_contact creating organization contact
1317 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1318 $op->execute($this->_dbconn
,
1319 $this->createXMLDataSet(
1320 dirname(__FILE__
) . '/dataset/contact_org.xml'
1326 'organization_name' => 'WebAccess India Pvt Ltd',
1327 'legal_name' => 'WebAccess',
1328 'sic_code' => 'ABC12DEF',
1329 'contact_type' => 'Organization',
1332 $this->callAPISuccess('Contact', 'Update', $params);
1334 // Check updated civicrm_contact against expected.
1335 $expected = $this->createXMLDataSet(
1336 dirname(__FILE__
) . '/dataset/contact_org_upd.xml'
1338 $actual = new PHPUnit_Extensions_Database_DataSet_QueryDataSet(
1341 $actual->addTable('civicrm_contact');
1342 $expected->matches($actual);
1346 * Verify successful update of household contact.
1348 public function testUpdateHouseholdWithAll() {
1349 // Insert a row in civicrm_contact creating household contact
1350 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1351 $op->execute($this->_dbconn
,
1352 $this->createXMLDataSet(
1353 dirname(__FILE__
) . '/dataset/contact_hld.xml'
1359 'household_name' => 'ABC household',
1360 'nick_name' => 'ABC House',
1361 'contact_type' => 'Household',
1364 $result = $this->callAPISuccess('Contact', 'Update', $params);
1367 'contact_type' => 'Household',
1369 'sort_name' => 'ABC household',
1370 'display_name' => 'ABC household',
1371 'nick_name' => 'ABC House',
1373 $this->getAndCheck($expected, $result['id'], 'contact');
1377 * Test civicrm_update() without contact type.
1379 * Deliberately exclude contact_type as it should still cope using civicrm_api.
1383 public function testUpdateCreateWithID() {
1384 // Insert a row in civicrm_contact creating individual contact.
1385 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1386 $op->execute($this->_dbconn
,
1387 $this->createXMLDataSet(
1388 dirname(__FILE__
) . '/dataset/contact_ind.xml'
1394 'first_name' => 'abcd',
1395 'last_name' => 'wxyz',
1397 $this->callAPISuccess('Contact', 'Update', $params);
1401 * Test civicrm_contact_delete() with no contact ID.
1403 public function testContactDeleteNoID() {
1407 $this->callAPIFailure('contact', 'delete', $params);
1411 * Test civicrm_contact_delete() with error.
1413 public function testContactDeleteError() {
1414 $params = array('contact_id' => 999);
1415 $this->callAPIFailure('contact', 'delete', $params);
1419 * Test civicrm_contact_delete().
1421 public function testContactDelete() {
1422 $contactID = $this->individualCreate();
1426 $this->callAPIAndDocument('contact', 'delete', $params, __FUNCTION__
, __FILE__
);
1430 * Test civicrm_contact_get() return only first name.
1432 public function testContactGetRetFirst() {
1433 $contact = $this->callAPISuccess('contact', 'create', $this->_params
);
1435 'contact_id' => $contact['id'],
1436 'return_first_name' => TRUE,
1437 'sort' => 'first_name',
1439 $result = $this->callAPISuccess('contact', 'get', $params);
1440 $this->assertEquals(1, $result['count']);
1441 $this->assertEquals($contact['id'], $result['id']);
1442 $this->assertEquals('abc1', $result['values'][$contact['id']]['first_name']);
1446 * Test civicrm_contact_get() return only first name & last name.
1448 * Use comma separated string return with a space.
1450 public function testContactGetReturnFirstLast() {
1451 $contact = $this->callAPISuccess('contact', 'create', $this->_params
);
1453 'contact_id' => $contact['id'],
1454 'return' => 'first_name, last_name',
1456 $result = $this->callAPISuccess('contact', 'getsingle', $params);
1457 $this->assertEquals('abc1', $result['first_name']);
1458 $this->assertEquals('xyz1', $result['last_name']);
1459 //check that other defaults not returns
1460 $this->assertArrayNotHasKey('sort_name', $result);
1462 'contact_id' => $contact['id'],
1463 'return' => 'first_name,last_name',
1465 $result = $this->callAPISuccess('contact', 'getsingle', $params);
1466 $this->assertEquals('abc1', $result['first_name']);
1467 $this->assertEquals('xyz1', $result['last_name']);
1468 //check that other defaults not returns
1469 $this->assertArrayNotHasKey('sort_name', $result);
1473 * Test civicrm_contact_get() return only first name & last name.
1475 * Use comma separated string return without a space
1477 public function testContactGetReturnFirstLastNoComma() {
1478 $contact = $this->callAPISuccess('contact', 'create', $this->_params
);
1480 'contact_id' => $contact['id'],
1481 'return' => 'first_name,last_name',
1483 $result = $this->callAPISuccess('contact', 'getsingle', $params);
1484 $this->assertEquals('abc1', $result['first_name']);
1485 $this->assertEquals('xyz1', $result['last_name']);
1486 //check that other defaults not returns
1487 $this->assertArrayNotHasKey('sort_name', $result);
1491 * Test civicrm_contact_get() with default return properties.
1493 public function testContactGetRetDefault() {
1494 $contactID = $this->individualCreate();
1496 'contact_id' => $contactID,
1497 'sort' => 'first_name',
1499 $result = $this->callAPISuccess('contact', 'get', $params);
1500 $this->assertEquals($contactID, $result['values'][$contactID]['contact_id']);
1501 $this->assertEquals('Anthony', $result['values'][$contactID]['first_name']);
1505 * Test civicrm_contact_getquick() with empty name param.
1507 public function testContactGetQuick() {
1508 // Insert a row in civicrm_contact creating individual contact.
1509 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1510 $op->execute($this->_dbconn
,
1511 $this->createXMLDataSet(
1512 dirname(__FILE__
) . '/dataset/contact_17.xml'
1515 $op->execute($this->_dbconn
,
1516 $this->createXMLDataSet(
1517 dirname(__FILE__
) . '/dataset/email_contact_17.xml'
1524 $result = $this->callAPISuccess('contact', 'getquick', $params);
1525 $this->assertEquals(17, $result['values'][0]['id']);
1529 * Test civicrm_contact_get) with empty params.
1531 public function testContactGetEmptyParams() {
1532 $this->callAPISuccess('contact', 'get', array());
1536 * Test civicrm_contact_get(,true) with no matches.
1538 public function testContactGetOldParamsNoMatches() {
1539 // Insert a row in civicrm_contact creating contact 17.
1540 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1541 $op->execute($this->_dbconn
,
1542 $this->createXMLDataSet(
1543 dirname(__FILE__
) . '/dataset/contact_17.xml'
1548 'first_name' => 'Fred',
1550 $result = $this->callAPISuccess('contact', 'get', $params);
1551 $this->assertEquals(0, $result['count']);
1555 * Test civicrm_contact_get(,true) with one match.
1557 public function testContactGetOldParamsOneMatch() {
1558 // Insert a row in civicrm_contact creating contact 17
1559 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1560 $op->execute($this->_dbconn
,
1561 $this->createXMLDataSet(dirname(__FILE__
) . '/dataset/contact_17.xml'
1566 'first_name' => 'Test',
1568 $result = $this->callAPISuccess('contact', 'get', $params);
1569 $this->assertEquals(17, $result['values'][17]['contact_id']);
1570 $this->assertEquals(17, $result['id']);
1574 * Test civicrm_contact_search_count().
1576 public function testContactGetEmail() {
1578 'email' => 'man2@yahoo.com',
1579 'contact_type' => 'Individual',
1580 'location_type_id' => 1,
1583 $contact = $this->callAPISuccess('contact', 'create', $params);
1586 'email' => 'man2@yahoo.com',
1588 $result = $this->callAPIAndDocument('contact', 'get', $params, __FUNCTION__
, __FILE__
);
1589 $this->assertEquals('man2@yahoo.com', $result['values'][$result['id']]['email']);
1591 $this->callAPISuccess('contact', 'delete', $contact);
1595 * Test birth date parameters.
1597 * These include value, array & birth_date_high, birth_date_low
1600 public function testContactGetBirthDate() {
1601 $contact1 = $this->callAPISuccess('contact', 'create', array_merge($this->_params
, array('birth_date' => 'first day of next month - 2 years')));
1602 $contact2 = $this->callAPISuccess('contact', 'create', array_merge($this->_params
, array('birth_date' => 'first day of next month - 5 years')));
1603 $contact3 = $this->callAPISuccess('contact', 'create', array_merge($this->_params
, array('birth_date' => 'first day of next month -20 years')));
1605 $result = $this->callAPISuccess('contact', 'get', array());
1606 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -2 years')), $result['values'][$contact1['id']]['birth_date']);
1607 $result = $this->callAPISuccess('contact', 'get', array('birth_date' => 'first day of next month -5 years'));
1608 $this->assertEquals(1, $result['count']);
1609 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -5 years')), $result['values'][$contact2['id']]['birth_date']);
1610 $result = $this->callAPISuccess('contact', 'get', array('birth_date_high' => date('Y-m-d', strtotime('-6 years'))));
1611 $this->assertEquals(1, $result['count']);
1612 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -20 years')), $result['values'][$contact3['id']]['birth_date']);
1613 $result = $this->callAPISuccess('contact', 'get', array(
1614 'birth_date_low' => date('Y-m-d', strtotime('-6 years')),
1615 'birth_date_high' => date('Y-m-d', strtotime('- 3 years')),
1617 $this->assertEquals(1, $result['count']);
1618 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -5 years')), $result['values'][$contact2['id']]['birth_date']);
1619 $result = $this->callAPISuccess('contact', 'get', array(
1620 'birth_date_low' => '-6 years',
1621 'birth_date_high' => '- 3 years',
1623 $this->assertEquals(1, $result['count']);
1624 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -5 years')), $result['values'][$contact2['id']]['birth_date']);
1628 * Test Address parameters
1630 * This include state_province, state_province_name, country
1632 public function testContactGetWithAddressFields() {
1633 $individuals = array(
1635 'first_name' => 'abc1',
1636 'contact_type' => 'Individual',
1637 'last_name' => 'xyz1',
1638 'api.address.create' => array(
1639 'country' => 'United States',
1640 'state_province_id' => 'Michigan',
1641 'location_type_id' => 1,
1645 'first_name' => 'abc2',
1646 'contact_type' => 'Individual',
1647 'last_name' => 'xyz2',
1648 'api.address.create' => array(
1649 'country' => 'United States',
1650 'state_province_id' => 'Alabama',
1651 'location_type_id' => 1,
1655 foreach ($individuals as $params) {
1656 $contact = $this->callAPISuccess('contact', 'create', $params);
1659 // Check whether Contact get API return successfully with below Address params.
1660 $fieldsToTest = array(
1661 'state_province_name' => 'Michigan',
1662 'state_province' => 'Michigan',
1663 'country' => 'United States',
1664 'state_province_name' => array('IN' => array('Michigan', 'Alabama')),
1665 'state_province' => array('IN' => array('Michigan', 'Alabama')),
1667 foreach ($fieldsToTest as $field => $value) {
1669 'id' => $contact['id'],
1672 $result = $this->callAPISuccess('Contact', 'get', $getParams);
1673 $this->assertEquals(1, $result['count']);
1678 * Test Deceased date parameters.
1680 * These include value, array & Deceased_date_high, Deceased date_low
1683 public function testContactGetDeceasedDate() {
1684 $contact1 = $this->callAPISuccess('contact', 'create', array_merge($this->_params
, array('deceased_date' => 'first day of next month - 2 years')));
1685 $contact2 = $this->callAPISuccess('contact', 'create', array_merge($this->_params
, array('deceased_date' => 'first day of next month - 5 years')));
1686 $contact3 = $this->callAPISuccess('contact', 'create', array_merge($this->_params
, array('deceased_date' => 'first day of next month -20 years')));
1688 $result = $this->callAPISuccess('contact', 'get', array());
1689 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -2 years')), $result['values'][$contact1['id']]['deceased_date']);
1690 $result = $this->callAPISuccess('contact', 'get', array('deceased_date' => 'first day of next month -5 years'));
1691 $this->assertEquals(1, $result['count']);
1692 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -5 years')), $result['values'][$contact2['id']]['deceased_date']);
1693 $result = $this->callAPISuccess('contact', 'get', array('deceased_date_high' => date('Y-m-d', strtotime('-6 years'))));
1694 $this->assertEquals(1, $result['count']);
1695 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -20 years')), $result['values'][$contact3['id']]['deceased_date']);
1696 $result = $this->callAPISuccess('contact', 'get', array(
1697 'deceased_date_low' => '-6 years',
1698 'deceased_date_high' => date('Y-m-d', strtotime('- 3 years')),
1700 $this->assertEquals(1, $result['count']);
1701 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -5 years')), $result['values'][$contact2['id']]['deceased_date']);
1705 * Test for Contact.get id=@user:username.
1707 public function testContactGetByUsername() {
1708 // Setup - create contact with a uf-match.
1709 $cid = $this->individualCreate(array(
1710 'contact_type' => 'Individual',
1711 'first_name' => 'testGetByUsername',
1712 'last_name' => 'testGetByUsername',
1715 $ufMatchParams = array(
1716 'domain_id' => CRM_Core_Config
::domainID(),
1718 'uf_name' => 'the-email-matching-key-is-not-really-the-username',
1719 'contact_id' => $cid,
1721 $ufMatch = CRM_Core_BAO_UFMatch
::create($ufMatchParams);
1722 $this->assertTrue(is_numeric($ufMatch->id
));
1724 // setup - mock the calls to CRM_Utils_System_*::getUfId
1725 $userSystem = $this->getMock('CRM_Utils_System_UnitTests', array('getUfId'));
1726 $userSystem->expects($this->once())
1728 ->with($this->equalTo('exampleUser'))
1729 ->will($this->returnValue(99));
1730 CRM_Core_Config
::singleton()->userSystem
= $userSystem;
1733 $result = $this->callAPISuccess('Contact', 'get', array(
1734 'id' => '@user:exampleUser',
1736 $this->assertEquals('testGetByUsername', $result['values'][$cid]['first_name']);
1740 * Test to check return works OK.
1742 public function testContactGetReturnValues() {
1743 $extraParams = array(
1744 'nick_name' => 'Bob',
1746 'email' => 'e@mail.com',
1748 $contactID = $this->individualCreate($extraParams);
1749 //actually it turns out the above doesn't create a phone
1750 $this->callAPISuccess('phone', 'create', array('contact_id' => $contactID, 'phone' => '456'));
1751 $result = $this->callAPISuccess('contact', 'getsingle', array('id' => $contactID));
1752 foreach ($extraParams as $key => $value) {
1753 $this->assertEquals($result[$key], $value);
1755 //now we check they are still returned with 'return' key
1756 $result = $this->callAPISuccess('contact', 'getsingle', array(
1758 'return' => array_keys($extraParams),
1760 foreach ($extraParams as $key => $value) {
1761 $this->assertEquals($result[$key], $value);
1766 * Test creating multiple phones using chaining.
1768 * @throws \Exception
1770 public function testCRM13252MultipleChainedPhones() {
1771 $contactID = $this->householdCreate();
1772 $this->callAPISuccessGetCount('phone', array('contact_id' => $contactID), 0);
1774 'contact_id' => $contactID,
1775 'household_name' => 'Household 1',
1776 'contact_type' => 'Household',
1777 'api.phone.create' => array(
1779 'phone' => '111-111-1111',
1780 'location_type_id' => 1,
1781 'phone_type_id' => 1,
1784 'phone' => '222-222-2222',
1785 'location_type_id' => 1,
1786 'phone_type_id' => 2,
1790 $this->callAPISuccess('contact', 'create', $params);
1791 $this->callAPISuccessGetCount('phone', array('contact_id' => $contactID), 2);
1796 * Test for Contact.get id=@user:username (with an invalid username).
1798 public function testContactGetByUnknownUsername() {
1799 // setup - mock the calls to CRM_Utils_System_*::getUfId
1800 $userSystem = $this->getMock('CRM_Utils_System_UnitTests', array('getUfId'));
1801 $userSystem->expects($this->once())
1803 ->with($this->equalTo('exampleUser'))
1804 ->will($this->returnValue(NULL));
1805 CRM_Core_Config
::singleton()->userSystem
= $userSystem;
1808 $result = $this->callAPIFailure('Contact', 'get', array(
1809 'id' => '@user:exampleUser',
1811 $this->assertRegExp('/cannot be resolved to a contact ID/', $result['error_message']);
1815 * Verify attempt to create individual with chained arrays and sequential.
1817 public function testGetIndividualWithChainedArraysAndSequential() {
1818 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__
, __FILE__
);
1819 $params['custom_' . $ids['custom_field_id']] = "custom string";
1821 $moreIDs = $this->CustomGroupMultipleCreateWithFields();
1824 'first_name' => 'abc3',
1825 'last_name' => 'xyz3',
1826 'contact_type' => 'Individual',
1827 'email' => 'man3@yahoo.com',
1828 'api.website.create' => array(
1830 'url' => "http://civicrm.org",
1833 'url' => "https://civicrm.org",
1838 $result = $this->callAPISuccess('Contact', 'create', $params);
1840 // delete the contact and custom groups
1841 $this->callAPISuccess('contact', 'delete', array('id' => $result['id']));
1842 $this->customGroupDelete($ids['custom_group_id']);
1843 $this->customGroupDelete($moreIDs['custom_group_id']);
1845 $this->assertEquals($result['id'], $result['values'][0]['id']);
1846 $this->assertArrayKeyExists('api.website.create', $result['values'][0]);
1850 * Verify attempt to create individual with chained arrays.
1852 public function testGetIndividualWithChainedArrays() {
1853 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__
, __FILE__
);
1854 $params['custom_' . $ids['custom_field_id']] = "custom string";
1856 $moreIDs = $this->CustomGroupMultipleCreateWithFields();
1857 $description = "This demonstrates the usage of chained api functions.\nIn this case no notes or custom fields have been created.";
1858 $subfile = "APIChainedArray";
1860 'first_name' => 'abc3',
1861 'last_name' => 'xyz3',
1862 'contact_type' => 'Individual',
1863 'email' => 'man3@yahoo.com',
1864 'api.contribution.create' => array(
1865 'receive_date' => '2010-01-01',
1866 'total_amount' => 100.00,
1867 'financial_type_id' => 1,
1868 'payment_instrument_id' => 1,
1869 'non_deductible_amount' => 10.00,
1870 'fee_amount' => 50.00,
1871 'net_amount' => 90.00,
1873 'invoice_id' => 67890,
1875 'contribution_status_id' => 1,
1877 'api.contribution.create.1' => array(
1878 'receive_date' => '2011-01-01',
1879 'total_amount' => 120.00,
1880 'financial_type_id' => $this->_financialTypeId
= 1,
1881 'payment_instrument_id' => 1,
1882 'non_deductible_amount' => 10.00,
1883 'fee_amount' => 50.00,
1884 'net_amount' => 90.00,
1886 'invoice_id' => 67830,
1888 'contribution_status_id' => 1,
1890 'api.website.create' => array(
1892 'url' => "http://civicrm.org",
1897 $result = $this->callAPISuccess('Contact', 'create', $params);
1899 'id' => $result['id'],
1900 'api.website.get' => array(),
1901 'api.Contribution.get' => array(
1902 'total_amount' => '120.00',
1904 'api.CustomValue.get' => 1,
1905 'api.Note.get' => 1,
1907 $result = $this->callAPIAndDocument('Contact', 'Get', $params, __FUNCTION__
, __FILE__
, $description, $subfile);
1908 // delete the contact
1909 $this->callAPISuccess('contact', 'delete', $result);
1910 $this->customGroupDelete($ids['custom_group_id']);
1911 $this->customGroupDelete($moreIDs['custom_group_id']);
1912 $this->assertEquals(0, $result['values'][$result['id']]['api.website.get']['is_error']);
1913 $this->assertEquals("http://civicrm.org", $result['values'][$result['id']]['api.website.get']['values'][0]['url']);
1917 * Verify attempt to create individual with chained arrays and sequential.
1919 * See https://issues.civicrm.org/jira/browse/CRM-15815
1921 public function testCreateIndividualWithChainedArrayAndSequential() {
1924 'first_name' => 'abc5',
1925 'last_name' => 'xyz5',
1926 'contact_type' => 'Individual',
1927 'email' => 'woman5@yahoo.com',
1928 'api.phone.create' => array(
1929 array('phone' => '03-231 07 95'),
1930 array('phone' => '03-232 51 62'),
1932 'api.website.create' => array(
1933 'url' => 'http://civicrm.org',
1936 $result = $this->callAPISuccess('Contact', 'create', $params);
1938 // I could try to parse the result to see whether the two phone numbers
1939 // and the website are there, but I am not sure about the correct format.
1940 // So I will just fetch it again before checking.
1941 // See also http://forum.civicrm.org/index.php/topic,35393.0.html
1944 'id' => $result['id'],
1945 'api.website.get' => array(),
1946 'api.phone.get' => array(),
1948 $result = $this->callAPISuccess('Contact', 'get', $params);
1950 // delete the contact
1951 $this->callAPISuccess('contact', 'delete', $result);
1953 $this->assertEquals(2, $result['values'][0]['api.phone.get']['count']);
1954 $this->assertEquals(1, $result['values'][0]['api.website.get']['count']);
1958 * Test retrieving an individual with chained array syntax.
1960 public function testGetIndividualWithChainedArraysFormats() {
1961 $description = "This demonstrates the usage of chained api functions.\nIn this case no notes or custom fields have been created.";
1962 $subfile = "APIChainedArrayFormats";
1963 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__
, __FILE__
);
1964 $params['custom_' . $ids['custom_field_id']] = "custom string";
1966 $moreIDs = $this->CustomGroupMultipleCreateWithFields();
1968 'first_name' => 'abc3',
1969 'last_name' => 'xyz3',
1970 'contact_type' => 'Individual',
1971 'email' => 'man3@yahoo.com',
1972 'api.contribution.create' => array(
1973 'receive_date' => '2010-01-01',
1974 'total_amount' => 100.00,
1975 'financial_type_id' => $this->_financialTypeId
,
1976 'payment_instrument_id' => 1,
1977 'non_deductible_amount' => 10.00,
1978 'fee_amount' => 50.00,
1979 'net_amount' => 90.00,
1981 'contribution_status_id' => 1,
1983 'api.contribution.create.1' => array(
1984 'receive_date' => '2011-01-01',
1985 'total_amount' => 120.00,
1986 'financial_type_id' => $this->_financialTypeId
,
1987 'payment_instrument_id' => 1,
1988 'non_deductible_amount' => 10.00,
1989 'fee_amount' => 50.00,
1990 'net_amount' => 90.00,
1992 'contribution_status_id' => 1,
1994 'api.website.create' => array(
1996 'url' => "http://civicrm.org",
2001 $result = $this->callAPISuccess('Contact', 'create', $params);
2003 'id' => $result['id'],
2004 'api.website.getValue' => array('return' => 'url'),
2005 'api.Contribution.getCount' => array(),
2006 'api.CustomValue.get' => 1,
2007 'api.Note.get' => 1,
2008 'api.Membership.getCount' => array(),
2010 $result = $this->callAPIAndDocument('Contact', 'Get', $params, __FUNCTION__
, __FILE__
, $description, $subfile);
2011 $this->assertEquals(2, $result['values'][$result['id']]['api.Contribution.getCount']);
2012 $this->assertEquals(0, $result['values'][$result['id']]['api.Note.get']['is_error']);
2013 $this->assertEquals("http://civicrm.org", $result['values'][$result['id']]['api.website.getValue']);
2015 $this->callAPISuccess('contact', 'delete', $result);
2016 $this->customGroupDelete($ids['custom_group_id']);
2017 $this->customGroupDelete($moreIDs['custom_group_id']);
2021 * Test complex chaining.
2023 public function testGetIndividualWithChainedArraysAndMultipleCustom() {
2024 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__
, __FILE__
);
2025 $params['custom_' . $ids['custom_field_id']] = "custom string";
2026 $moreIDs = $this->CustomGroupMultipleCreateWithFields();
2027 $andMoreIDs = $this->CustomGroupMultipleCreateWithFields(array(
2028 'title' => "another group",
2029 'name' => 'another name',
2031 $description = "This demonstrates the usage of chained api functions with multiple custom fields.";
2032 $subfile = "APIChainedArrayMultipleCustom";
2034 'first_name' => 'abc3',
2035 'last_name' => 'xyz3',
2036 'contact_type' => 'Individual',
2037 'email' => 'man3@yahoo.com',
2038 'api.contribution.create' => array(
2039 'receive_date' => '2010-01-01',
2040 'total_amount' => 100.00,
2041 'financial_type_id' => 1,
2042 'payment_instrument_id' => 1,
2043 'non_deductible_amount' => 10.00,
2044 'fee_amount' => 50.00,
2045 'net_amount' => 90.00,
2047 'invoice_id' => 67890,
2049 'contribution_status_id' => 1,
2051 'api.contribution.create.1' => array(
2052 'receive_date' => '2011-01-01',
2053 'total_amount' => 120.00,
2054 'financial_type_id' => 1,
2055 'payment_instrument_id' => 1,
2056 'non_deductible_amount' => 10.00,
2057 'fee_amount' => 50.00,
2058 'net_amount' => 90.00,
2060 'invoice_id' => 67830,
2062 'contribution_status_id' => 1,
2064 'api.website.create' => array(
2066 'url' => "http://civicrm.org",
2069 'custom_' . $ids['custom_field_id'] => "value 1",
2070 'custom_' . $moreIDs['custom_field_id'][0] => "value 2",
2071 'custom_' . $moreIDs['custom_field_id'][1] => "warm beer",
2072 'custom_' . $andMoreIDs['custom_field_id'][1] => "vegemite",
2075 $result = $this->callAPISuccess('Contact', 'create', $params);
2076 $result = $this->callAPISuccess('Contact', 'create', array(
2077 'contact_type' => 'Individual',
2078 'id' => $result['id'],
2080 $moreIDs['custom_field_id'][0] => "value 3",
2082 $ids['custom_field_id'] => "value 4",
2086 'id' => $result['id'],
2087 'api.website.getValue' => array('return' => 'url'),
2088 'api.Contribution.getCount' => array(),
2089 'api.CustomValue.get' => 1,
2091 $result = $this->callAPIAndDocument('Contact', 'Get', $params, __FUNCTION__
, __FILE__
, $description, $subfile);
2093 $this->customGroupDelete($ids['custom_group_id']);
2094 $this->customGroupDelete($moreIDs['custom_group_id']);
2095 $this->customGroupDelete($andMoreIDs['custom_group_id']);
2096 $this->assertEquals(0, $result['values'][$result['id']]['api.CustomValue.get']['is_error']);
2097 $this->assertEquals('http://civicrm.org', $result['values'][$result['id']]['api.website.getValue']);
2101 * Test checks usage of $values to pick & choose inputs.
2103 public function testChainingValuesCreate() {
2104 $description = "This demonstrates the usage of chained api functions. Specifically it has one 'parent function' &
2105 2 child functions - one receives values from the parent (Contact) and the other child (Tag).";
2106 $subfile = "APIChainedArrayValuesFromSiblingFunction";
2108 'display_name' => 'batman',
2109 'contact_type' => 'Individual',
2110 'api.tag.create' => array(
2111 'name' => '$value.id',
2112 'description' => '$value.display_name',
2113 'format.only_id' => 1,
2115 'api.entity_tag.create' => array('tag_id' => '$value.api.tag.create'),
2117 $result = $this->callAPIAndDocument('Contact', 'Create', $params, __FUNCTION__
, __FILE__
, $description, $subfile);
2118 $this->assertEquals(0, $result['values'][$result['id']]['api.entity_tag.create']['is_error']);
2120 $tablesToTruncate = array(
2123 'civicrm_entity_tag',
2126 $this->quickCleanup($tablesToTruncate, TRUE);
2130 * Test TrueFalse format - I couldn't come up with an easy way to get an error on Get.
2132 public function testContactGetFormatIsSuccessTrue() {
2133 $this->createContactFromXML();
2134 $description = "This demonstrates use of the 'format.is_success' param.
2135 This param causes only the success or otherwise of the function to be returned as BOOLEAN";
2136 $subfile = "FormatIsSuccess_True";
2137 $params = array('id' => 17, 'format.is_success' => 1);
2138 $result = $this->callAPIAndDocument('Contact', 'Get', $params, __FUNCTION__
, __FILE__
, $description, $subfile);
2139 $this->assertEquals(1, $result);
2140 $this->callAPISuccess('Contact', 'Delete', $params);
2144 * Test TrueFalse format.
2146 public function testContactCreateFormatIsSuccessFalse() {
2148 $description = "This demonstrates use of the 'format.is_success' param.
2149 This param causes only the success or otherwise of the function to be returned as BOOLEAN";
2150 $subfile = "FormatIsSuccess_Fail";
2151 $params = array('id' => 500, 'format.is_success' => 1);
2152 $result = $this->callAPIAndDocument('Contact', 'Create', $params, __FUNCTION__
, __FILE__
, $description, $subfile);
2153 $this->assertEquals(0, $result);
2157 * Test Single Entity format.
2159 public function testContactGetSingleEntityArray() {
2160 $this->createContactFromXML();
2161 $description = "This demonstrates use of the 'format.single_entity_array' param.
2162 This param causes the only contact to be returned as an array without the other levels.
2163 It will be ignored if there is not exactly 1 result";
2164 $subfile = "GetSingleContact";
2165 $params = array('id' => 17);
2166 $result = $this->callAPIAndDocument('Contact', 'GetSingle', $params, __FUNCTION__
, __FILE__
, $description, $subfile);
2167 $this->assertEquals('Test Contact', $result['display_name']);
2168 $this->callAPISuccess('Contact', 'Delete', $params);
2172 * Test Single Entity format.
2174 public function testContactGetFormatCountOnly() {
2175 $this->createContactFromXML();
2176 $description = "This demonstrates use of the 'getCount' action.
2177 This param causes the count of the only function to be returned as an integer.";
2178 $params = array('id' => 17);
2179 $result = $this->callAPIAndDocument('Contact', 'GetCount', $params, __FUNCTION__
, __FILE__
, $description,
2181 $this->assertEquals('1', $result);
2182 $this->callAPISuccess('Contact', 'Delete', $params);
2186 * Test id only format.
2188 public function testContactGetFormatIDOnly() {
2189 $this->createContactFromXML();
2190 $description = "This demonstrates use of the 'format.id_only' param.
2191 This param causes the id of the only entity to be returned as an integer.
2192 It will be ignored if there is not exactly 1 result";
2193 $subfile = "FormatOnlyID";
2194 $params = array('id' => 17, 'format.only_id' => 1);
2195 $result = $this->callAPIAndDocument('Contact', 'Get', $params, __FUNCTION__
, __FILE__
, $description, $subfile);
2196 $this->assertEquals('17', $result);
2197 $this->callAPISuccess('Contact', 'Delete', $params);
2201 * Test id only format.
2203 public function testContactGetFormatSingleValue() {
2204 $this->createContactFromXML();
2205 $description = "This demonstrates use of the 'format.single_value' param.
2206 This param causes only a single value of the only entity to be returned as an string.
2207 It will be ignored if there is not exactly 1 result";
2208 $subFile = "FormatSingleValue";
2209 $params = array('id' => 17, 'return' => 'display_name');
2210 $result = $this->callAPIAndDocument('Contact', 'getvalue', $params, __FUNCTION__
, __FILE__
, $description, $subFile);
2211 $this->assertEquals('Test Contact', $result);
2212 $this->callAPISuccess('Contact', 'Delete', $params);
2216 * Test that permissions are respected when creating contacts.
2218 public function testContactCreationPermissions() {
2220 'contact_type' => 'Individual',
2221 'first_name' => 'Foo',
2222 'last_name' => 'Bear',
2223 'check_permissions' => TRUE,
2225 $config = CRM_Core_Config
::singleton();
2226 $config->userPermissionClass
->permissions
= array('access CiviCRM');
2227 $result = $this->callAPIFailure('contact', 'create', $params);
2228 $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');
2230 $config->userPermissionClass
->permissions
= array('access CiviCRM', 'add contacts', 'import contacts');
2231 $this->callAPISuccess('contact', 'create', $params);
2235 * Test update with check permissions set.
2237 public function testContactUpdatePermissions() {
2239 'contact_type' => 'Individual',
2240 'first_name' => 'Foo',
2241 'last_name' => 'Bear',
2242 'check_permissions' => TRUE,
2244 $result = $this->callAPISuccess('contact', 'create', $params);
2245 $config = CRM_Core_Config
::singleton();
2247 'id' => $result['id'],
2248 'contact_type' => 'Individual',
2249 'last_name' => 'Bar',
2250 'check_permissions' => TRUE,
2253 $config->userPermissionClass
->permissions
= array('access CiviCRM');
2254 $result = $this->callAPIFailure('contact', 'update', $params);
2255 $this->assertEquals('Permission denied to modify contact record', $result['error_message']);
2257 $config->userPermissionClass
->permissions
= array(
2260 'view all contacts',
2261 'edit all contacts',
2264 $this->callAPISuccess('contact', 'update', $params);
2268 * Set up helper to create a contact.
2270 public function createContactFromXML() {
2271 // Insert a row in civicrm_contact creating contact 17.
2272 $op = new PHPUnit_Extensions_Database_Operation_Insert();
2273 $op->execute($this->_dbconn
,
2274 $this->createXMLDataSet(
2275 dirname(__FILE__
) . '/dataset/contact_17.xml'
2281 * Test contact proximity api.
2283 public function testContactProximity() {
2284 // first create a contact with a SF location with a specific
2286 $contactID = $this->organizationCreate();
2288 // now create the address
2290 'street_address' => '123 Main Street',
2291 'city' => 'San Francisco',
2293 'country_id' => 1228,
2294 'state_province_id' => 1004,
2295 'geo_code_1' => '37.79',
2296 'geo_code_2' => '-122.40',
2297 'location_type_id' => 1,
2298 'contact_id' => $contactID,
2301 $result = $this->callAPISuccess('address', 'create', $params);
2302 $this->assertEquals(1, $result['count']);
2304 // now do a proximity search with a close enough geocode and hope to match
2305 // that specific contact only!
2306 $proxParams = array(
2308 'longitude' => -122.3,
2312 $result = $this->callAPISuccess('contact', 'proximity', $proxParams);
2313 $this->assertEquals(1, $result['count']);
2317 * Test that Ajax API permission is sufficient to access getquick api.
2319 * (note that getquick api is required for autocomplete & has ACL permissions applied)
2321 public function testGetquickPermissionCRM13744() {
2322 CRM_Core_Config
::singleton()->userPermissionClass
->permissions
= array('access CiviEvent');
2323 $this->callAPIFailure('contact', 'getquick', array('name' => 'b', 'check_permissions' => TRUE));
2324 CRM_Core_Config
::singleton()->userPermissionClass
->permissions
= array('access CiviCRM');
2325 $this->callAPISuccess('contact', 'getquick', array('name' => 'b', 'check_permissions' => TRUE));
2326 CRM_Core_Config
::singleton()->userPermissionClass
->permissions
= array('access AJAX API');
2327 $this->callAPISuccess('contact', 'getquick', array('name' => 'b', 'check_permissions' => TRUE));
2331 * Test that getquick returns contacts with an exact first name match first.
2333 * The search string 'b' & 'bob' both return ordered by sort_name if includeOrderByClause
2334 * is true (default) but if it is false then matches are returned in ID order.
2336 public function testGetQuickExactFirst() {
2337 $this->getQuickSearchSampleData();
2338 $result = $this->callAPISuccess('contact', 'getquick', array('name' => 'b'));
2339 $this->assertEquals('A Bobby, Bobby', $result['values'][0]['sort_name']);
2340 $this->assertEquals('B Bobby, Bobby', $result['values'][1]['sort_name']);
2341 $result = $this->callAPISuccess('contact', 'getquick', array('name' => 'bob'));
2342 $this->assertEquals('A Bobby, Bobby', $result['values'][0]['sort_name']);
2343 $this->assertEquals('B Bobby, Bobby', $result['values'][1]['sort_name']);
2344 $this->callAPISuccess('Setting', 'create', array('includeOrderByClause' => FALSE));
2345 $result = $this->callAPISuccess('contact', 'getquick', array('name' => 'bob'));
2346 $this->assertEquals('Bob, Bob', $result['values'][0]['sort_name']);
2347 $this->assertEquals('A Bobby, Bobby', $result['values'][1]['sort_name']);
2351 * Test that getquick returns contacts with an exact first name match first.
2353 public function testGetQuickEmail() {
2354 $this->getQuickSearchSampleData();
2355 $loggedInContactID = $this->createLoggedInUser();
2356 $result = $this->callAPISuccess('contact', 'getquick', array(
2359 $expectedData = array(
2360 'Bob, Bob :: bob@bob.com',
2362 'E Bobby, Bobby :: bob@bobby.com',
2363 'H Bobby, Bobby :: bob@h.com',
2365 $this->callAPISuccessGetValue('Contact', array('id' => $loggedInContactID, 'return' => 'last_name')) . ', Logged In :: anthony_anderson@civicrm.org',
2367 $this->assertEquals(6, $result['count']);
2368 foreach ($expectedData as $index => $value) {
2369 $this->assertEquals($value, $result['values'][$index]['data']);
2371 $result = $this->callAPISuccess('contact', 'getquick', array(
2374 $expectedData = array(
2375 'H Bobby, Bobby :: bob@h.com',
2377 foreach ($expectedData as $index => $value) {
2378 $this->assertEquals($value, $result['values'][$index]['data']);
2380 $this->callAPISuccess('Setting', 'create', array('includeWildCardInName' => FALSE));
2381 $result = $this->callAPISuccess('contact', 'getquick', array(
2384 $this->callAPISuccess('Setting', 'create', array('includeWildCardInName' => TRUE));
2385 $this->assertEquals(0, $result['count']);
2389 * Test that getquick returns contacts with an exact first name match first.
2391 public function testGetQuickEmailACL() {
2392 $this->getQuickSearchSampleData();
2393 $loggedInContactID = $this->createLoggedInUser();
2394 CRM_Core_Config
::singleton()->userPermissionClass
->permissions
= array();
2395 $result = $this->callAPISuccess('contact', 'getquick', array(
2398 $this->assertEquals(0, $result['count']);
2400 $this->hookClass
->setHook('civicrm_aclWhereClause', array($this, 'aclWhereNoBobH'));
2401 CRM_Contact_BAO_Contact_Permission
::cache($loggedInContactID, CRM_Core_Permission
::VIEW
, TRUE);
2402 $result = $this->callAPISuccess('contact', 'getquick', array(
2406 // Without the acl it would be 6 like the previous email getquick test.
2407 $this->assertEquals(5, $result['count']);
2408 $expectedData = array(
2409 'Bob, Bob :: bob@bob.com',
2411 'E Bobby, Bobby :: bob@bobby.com',
2413 $this->callAPISuccessGetValue('Contact', array('id' => $loggedInContactID, 'return' => 'last_name')) . ', Logged In :: anthony_anderson@civicrm.org',
2415 foreach ($expectedData as $index => $value) {
2416 $this->assertEquals($value, $result['values'][$index]['data']);
2421 * Test that getquick returns contacts with an exact first name match first.
2423 public function testGetQuickExternalID() {
2424 $this->getQuickSearchSampleData();
2425 $result = $this->callAPISuccess('contact', 'getquick', array(
2427 'field_name' => 'external_identifier',
2428 'table_name' => 'cc',
2430 $this->assertEquals(0, $result['count']);
2431 $result = $this->callAPISuccess('contact', 'getquick', array(
2433 'field_name' => 'external_identifier',
2434 'table_name' => 'cc',
2436 $this->assertEquals(1, $result['count']);
2437 $this->assertEquals('Bob, Bob', $result['values'][0]['sort_name']);
2441 * Test that getquick returns contacts with an exact first name match first.
2443 public function testGetQuickID() {
2444 $max = CRM_Core_DAO
::singleValueQuery("SELECT max(id) FROM civicrm_contact");
2445 $this->getQuickSearchSampleData();
2446 $result = $this->callAPISuccess('contact', 'getquick', array(
2448 'field_name' => 'id',
2449 'table_name' => 'cc',
2451 $this->assertEquals(1, $result['count']);
2452 $this->assertEquals('A Bobby, Bobby', $result['values'][0]['sort_name']);
2453 $result = $this->callAPISuccess('contact', 'getquick', array(
2455 'field_name' => 'contact_id',
2456 'table_name' => 'cc',
2458 $this->assertEquals(1, $result['count']);
2459 $this->assertEquals('A Bobby, Bobby', $result['values'][0]['sort_name']);
2463 * Test that getquick returns contacts with an exact first name match first.
2465 * Depending on the setting the sort name sort might click in next or not - test!
2467 public function testGetQuickFirstName() {
2468 $this->getQuickSearchSampleData();
2469 $this->callAPISuccess('Setting', 'create', array('includeOrderByClause' => TRUE));
2470 $result = $this->callAPISuccess('contact', 'getquick', array(
2472 'field_name' => 'first_name',
2473 'table_name' => 'cc',
2481 foreach ($expected as $index => $value) {
2482 $this->assertEquals($value, $result['values'][$index]['sort_name']);
2484 $this->callAPISuccess('Setting', 'create', array('includeOrderByClause' => FALSE));
2485 $result = $this->callAPISuccess('contact', 'getquick', array('name' => 'bob'));
2486 $this->assertEquals('Bob, Bob', $result['values'][0]['sort_name']);
2487 $this->assertEquals('A Bobby, Bobby', $result['values'][1]['sort_name']);
2491 * Test that getquick applies ACLs.
2493 public function testGetQuickFirstNameACLs() {
2494 $this->getQuickSearchSampleData();
2495 $userID = $this->createLoggedInUser();
2496 $this->callAPISuccess('Setting', 'create', array('includeOrderByClause' => TRUE));
2497 CRM_Core_Config
::singleton()->userPermissionClass
->permissions
= array();
2498 $result = $this->callAPISuccess('contact', 'getquick', array(
2500 'field_name' => 'first_name',
2501 'table_name' => 'cc',
2503 $this->assertEquals(0, $result['count']);
2505 $this->hookClass
->setHook('civicrm_aclWhereClause', array($this, 'aclWhereNoBobH'));
2506 CRM_Contact_BAO_Contact_Permission
::cache($userID, CRM_Core_Permission
::VIEW
, TRUE);
2507 $result = $this->callAPISuccess('contact', 'getquick', array(
2509 'field_name' => 'first_name',
2510 'table_name' => 'cc',
2512 $this->assertEquals('K Bobby, Bob', $result['values'][1]['sort_name']);
2513 // Without the ACL 9 would be bob@h.com.
2514 $this->assertEquals('I Bobby, Bobby', $result['values'][9]['sort_name']);
2518 * Full results returned.
2519 * @implements CRM_Utils_Hook::aclWhereClause
2521 * @param string $type
2522 * @param array $tables
2523 * @param array $whereTables
2524 * @param int $contactID
2525 * @param string $where
2527 public function aclWhereNoBobH($type, &$tables, &$whereTables, &$contactID, &$where) {
2528 $where = " (email <> 'bob@h.com' OR email IS NULL) ";
2529 $whereTables['civicrm_email'] = "LEFT JOIN civicrm_email e ON contact_a.id = e.contact_id";
2533 * Test that getquick returns contacts with an exact last name match first.
2535 public function testGetQuickLastName() {
2536 $this->getQuickSearchSampleData();
2537 $this->callAPISuccess('Setting', 'create', array('includeOrderByClause' => TRUE));
2538 $result = $this->callAPISuccess('contact', 'getquick', array(
2540 'field_name' => 'last_name',
2541 'table_name' => 'cc',
2549 foreach ($expected as $index => $value) {
2550 $this->assertEquals($value, $result['values'][$index]['sort_name']);
2552 $this->callAPISuccess('Setting', 'create', array('includeOrderByClause' => FALSE));
2553 $result = $this->callAPISuccess('contact', 'getquick', array('name' => 'bob'));
2554 $this->assertEquals('Bob, Bob :: bob@bob.com', $result['values'][0]['data']);
2558 * Test that getquick returns contacts by city.
2560 public function testGetQuickCity() {
2561 $this->getQuickSearchSampleData();
2562 $result = $this->callAPISuccess('contact', 'getquick', array(
2564 'field_name' => 'city',
2565 'table_name' => 'sts',
2567 $this->assertEquals('B Bobby, Bobby :: Toronto', $result['values'][0]['data']);
2568 $result = $this->callAPISuccess('contact', 'getquick', array(
2570 'field_name' => 'city',
2571 'table_name' => 'sts',
2573 $this->assertEquals('B Bobby, Bobby :: Toronto', $result['values'][0]['data']);
2574 $this->assertEquals('C Bobby, Bobby :: Whanganui', $result['values'][1]['data']);
2578 * Set up some sample data for testing quicksearch.
2580 public function getQuickSearchSampleData() {
2582 array('first_name' => 'Bob', 'last_name' => 'Bob', 'external_identifier' => 'abc', 'email' => 'bob@bob.com'),
2583 array('first_name' => 'Bobby', 'last_name' => 'A Bobby', 'external_identifier' => 'abcd'),
2585 'first_name' => 'Bobby',
2586 'last_name' => 'B Bobby',
2587 'external_identifier' => 'bcd',
2588 'api.address.create' => array(
2589 'street_address' => 'Sesame Street',
2590 'city' => 'Toronto',
2591 'location_type_id' => 1,
2595 'first_name' => 'Bobby',
2596 'last_name' => 'C Bobby',
2597 'external_identifier' => 'bcde',
2598 'api.address.create' => array(
2599 'street_address' => 'Te huarahi',
2600 'city' => 'Whanganui',
2601 'location_type_id' => 1,
2604 array('first_name' => 'Bobby', 'last_name' => 'D Bobby', 'external_identifier' => 'efg'),
2605 array('first_name' => 'Bobby', 'last_name' => 'E Bobby', 'external_identifier' => 'hij', 'email' => 'bob@bobby.com'),
2606 array('first_name' => 'Bobby', 'last_name' => 'F Bobby', 'external_identifier' => 'klm'),
2607 array('first_name' => 'Bobby', 'last_name' => 'G Bobby', 'external_identifier' => 'nop'),
2608 array('first_name' => 'Bobby', 'last_name' => 'H Bobby', 'external_identifier' => 'qrs', 'email' => 'bob@h.com'),
2609 array('first_name' => 'Bobby', 'last_name' => 'I Bobby'),
2610 array('first_name' => 'Bobby', 'last_name' => 'J Bobby'),
2611 array('first_name' => 'Bob', 'last_name' => 'K Bobby', 'external_identifier' => 'bcdef'),
2613 foreach ($contacts as $type => $contact) {
2614 $contact['contact_type'] = 'Individual';
2615 $this->callAPISuccess('Contact', 'create', $contact);
2620 * Test get ref api - gets a list of references to an entity.
2622 public function testGetReferenceCounts() {
2623 $result = $this->callAPISuccess('Contact', 'create', array(
2624 'first_name' => 'Testily',
2625 'last_name' => 'McHaste',
2626 'contact_type' => 'Individual',
2627 'api.Address.replace' => array(
2628 'values' => array(),
2630 'api.Email.replace' => array(
2633 'email' => 'spam@dev.null',
2635 'location_type_id' => 1,
2639 'api.Phone.replace' => array(
2642 'phone' => '234-567-0001',
2644 'location_type_id' => 1,
2647 'phone' => '234-567-0002',
2649 'location_type_id' => 1,
2655 //$dao = new CRM_Contact_BAO_Contact();
2656 //$dao->id = $result['id'];
2657 //$this->assertTrue((bool) $dao->find(TRUE));
2659 //$refCounts = $dao->getReferenceCounts();
2660 //$this->assertTrue(is_array($refCounts));
2661 //$refCountsIdx = CRM_Utils_Array::index(array('name'), $refCounts);
2663 $refCounts = $this->callAPISuccess('Contact', 'getrefcount', array(
2664 'id' => $result['id'],
2666 $refCountsIdx = CRM_Utils_Array
::index(array('name'), $refCounts['values']);
2668 $this->assertEquals(1, $refCountsIdx['sql:civicrm_email:contact_id']['count']);
2669 $this->assertEquals('civicrm_email', $refCountsIdx['sql:civicrm_email:contact_id']['table']);
2670 $this->assertEquals(2, $refCountsIdx['sql:civicrm_phone:contact_id']['count']);
2671 $this->assertEquals('civicrm_phone', $refCountsIdx['sql:civicrm_phone:contact_id']['table']);
2672 $this->assertTrue(!isset($refCountsIdx['sql:civicrm_address:contact_id']));
2676 * Test the use of sql operators.
2678 public function testSQLOperatorsOnContactAPI() {
2679 $this->individualCreate();
2680 $this->organizationCreate();
2681 $this->householdCreate();
2682 $contacts = $this->callAPISuccess('contact', 'get', array('legal_name' => array('IS NOT NULL' => TRUE)));
2683 $this->assertEquals($contacts['count'], CRM_Core_DAO
::singleValueQuery('select count(*) FROM civicrm_contact WHERE legal_name IS NOT NULL'));
2684 $contacts = $this->callAPISuccess('contact', 'get', array('legal_name' => array('IS NULL' => TRUE)));
2685 $this->assertEquals($contacts['count'], CRM_Core_DAO
::singleValueQuery('select count(*) FROM civicrm_contact WHERE legal_name IS NULL'));
2689 * CRM-14743 - test api respects search operators.
2691 public function testGetModifiedDateByOperators() {
2692 $preExistingContactCount = CRM_Core_DAO
::singleValueQuery('select count(*) FROM civicrm_contact');
2693 $contact1 = $this->individualCreate();
2694 $sql = "UPDATE civicrm_contact SET created_date = '2012-01-01', modified_date = '2013-01-01' WHERE id = " . $contact1;
2695 CRM_Core_DAO
::executeQuery($sql);
2696 $contact2 = $this->individualCreate();
2697 $sql = "UPDATE civicrm_contact SET created_date = '2012-02-01', modified_date = '2013-02-01' WHERE id = " . $contact2;
2698 CRM_Core_DAO
::executeQuery($sql);
2699 $contact3 = $this->householdCreate();
2700 $sql = "UPDATE civicrm_contact SET created_date = '2012-03-01', modified_date = '2013-03-01' WHERE id = " . $contact3;
2701 CRM_Core_DAO
::executeQuery($sql);
2702 $contacts = $this->callAPISuccess('contact', 'get', array('modified_date' => array('<' => '2014-01-01')));
2703 $this->assertEquals($contacts['count'], 3);
2704 $contacts = $this->callAPISuccess('contact', 'get', array('modified_date' => array('>' => '2014-01-01')));
2705 $this->assertEquals($contacts['count'], $preExistingContactCount);
2709 * CRM-14743 - test api respects search operators.
2711 public function testGetCreatedDateByOperators() {
2712 $preExistingContactCount = CRM_Core_DAO
::singleValueQuery('select count(*) FROM civicrm_contact');
2713 $contact1 = $this->individualCreate();
2714 $sql = "UPDATE civicrm_contact SET created_date = '2012-01-01' WHERE id = " . $contact1;
2715 CRM_Core_DAO
::executeQuery($sql);
2716 $contact2 = $this->individualCreate();
2717 $sql = "UPDATE civicrm_contact SET created_date = '2012-02-01' WHERE id = " . $contact2;
2718 CRM_Core_DAO
::executeQuery($sql);
2719 $contact3 = $this->householdCreate();
2720 $sql = "UPDATE civicrm_contact SET created_date = '2012-03-01' WHERE id = " . $contact3;
2721 CRM_Core_DAO
::executeQuery($sql);
2722 $contacts = $this->callAPISuccess('contact', 'get', array('created_date' => array('<' => '2014-01-01')));
2723 $this->assertEquals($contacts['count'], 3);
2724 $contacts = $this->callAPISuccess('contact', 'get', array('created_date' => array('>' => '2014-01-01')));
2725 $this->assertEquals($contacts['count'], $preExistingContactCount);
2729 * CRM-14263 check that API is not affected by search profile related bug.
2731 public function testReturnCityProfile() {
2732 $contactID = $this->individualCreate();
2733 CRM_Core_Config
::singleton()->defaultSearchProfileID
= 1;
2734 $this->callAPISuccess('address', 'create', array(
2735 'contact_id' => $contactID,
2736 'city' => 'Cool City',
2737 'location_type_id' => 1,
2739 $result = $this->callAPISuccess('contact', 'get', array('city' => 'Cool City', 'return' => 'contact_type'));
2740 $this->assertEquals(1, $result['count']);
2744 * CRM-15443 - ensure getlist api does not return deleted contacts.
2746 public function testGetlistExcludeConditions() {
2747 $name = md5(time());
2748 $contact = $this->individualCreate(array('last_name' => $name));
2749 $this->individualCreate(array('last_name' => $name, 'is_deceased' => 1));
2750 $this->individualCreate(array('last_name' => $name, 'is_deleted' => 1));
2751 // We should get all but the deleted contact.
2752 $result = $this->callAPISuccess('contact', 'getlist', array('input' => $name));
2753 $this->assertEquals(2, $result['count']);
2754 // Force-exclude the deceased contact.
2755 $result = $this->callAPISuccess('contact', 'getlist', array(
2757 'params' => array('is_deceased' => 0),
2759 $this->assertEquals(1, $result['count']);
2760 $this->assertEquals($contact, $result['values'][0]['id']);
2764 * Test contact getactions.
2766 public function testGetActions() {
2767 $description = "Getting the available actions for an entity.";
2768 $result = $this->callAPIAndDocument($this->_entity
, 'getactions', array(), __FUNCTION__
, __FILE__
, $description);
2788 $deprecated = array(
2792 foreach ($expected as $action) {
2793 $this->assertTrue(in_array($action, $result['values']), "Expected action $action");
2795 foreach ($deprecated as $action) {
2796 $this->assertArrayKeyExists($action, $result['deprecated']);
2801 * Test the duplicate check function.
2803 public function testDuplicateCheck() {
2804 $this->callAPISuccess('Contact', 'create', array(
2805 'first_name' => 'Harry',
2806 'last_name' => 'Potter',
2807 'email' => 'harry@hogwarts.edu',
2808 'contact_type' => 'Individual',
2810 $result = $this->callAPISuccess('Contact', 'duplicatecheck', array(
2812 'first_name' => 'Harry',
2813 'last_name' => 'Potter',
2814 'email' => 'harry@hogwarts.edu',
2815 'contact_type' => 'Individual',
2819 $this->assertEquals(1, $result['count']);
2820 $result = $this->callAPISuccess('Contact', 'duplicatecheck', array(
2822 'first_name' => 'Harry',
2823 'last_name' => 'Potter',
2824 'email' => 'no5@privet.drive',
2825 'contact_type' => 'Individual',
2828 $this->assertEquals(0, $result['count']);
2831 public function testGetByContactType() {
2832 $individual = $this->callAPISuccess('Contact', 'create', array(
2833 'email' => 'individual@test.com',
2834 'contact_type' => 'Individual',
2836 $household = $this->callAPISuccess('Contact', 'create', array(
2837 'household_name' => 'household@test.com',
2838 'contact_type' => 'Household',
2840 $organization = $this->callAPISuccess('Contact', 'create', array(
2841 'organization_name' => 'organization@test.com',
2842 'contact_type' => 'Organization',
2844 // Test with id - getsingle will throw an exception if not found
2845 $this->callAPISuccess('Contact', 'getsingle', array(
2846 'id' => $individual['id'],
2847 'contact_type' => 'Individual',
2849 $this->callAPISuccess('Contact', 'getsingle', array(
2850 'id' => $individual['id'],
2851 'contact_type' => array('IN' => array('Individual')),
2854 $this->callAPISuccess('Contact', 'getsingle', array(
2855 'id' => $organization['id'],
2856 'contact_type' => array('IN' => array('Individual', 'Organization')),
2859 $result = $this->callAPISuccess('Contact', 'get', array(
2860 'contact_type' => array('IN' => array('Individual', 'Organization')),
2861 'options' => array('limit' => 0),
2864 $this->assertContains($organization['id'], array_keys($result['values']));
2865 $this->assertContains($individual['id'], array_keys($result['values']));
2866 $this->assertNotContains($household['id'], array_keys($result['values']));
2868 $result = $this->callAPISuccess('Contact', 'get', array(
2869 'contact_type' => 'Household',
2870 'options' => array('limit' => 0),
2873 $this->assertNotContains($organization['id'], array_keys($result['values']));
2874 $this->assertNotContains($individual['id'], array_keys($result['values']));
2875 $this->assertContains($household['id'], array_keys($result['values']));
2879 * Test merging 2 contacts.
2881 * Someone kindly bequethed us the legacy of mixed up use of main_id & other_id
2882 * in the params for contact.merge api.
2884 * This test protects that legacy.
2886 public function testMergeBizzareOldParams() {
2887 $this->createLoggedInUser();
2888 $otherContact = $this->callAPISuccess('contact', 'create', $this->_params
);
2889 $mainContact = $this->callAPISuccess('contact', 'create', $this->_params
);
2890 $this->callAPISuccess('contact', 'merge', array(
2891 'main_id' => $mainContact['id'],
2892 'other_id' => $otherContact['id'],
2894 $contacts = $this->callAPISuccess('contact', 'get', $this->_params
);
2895 $this->assertEquals($otherContact['id'], $contacts['id']);
2899 * Test merging 2 contacts.
2901 public function testMerge() {
2902 $this->createLoggedInUser();
2903 $otherContact = $this->callAPISuccess('contact', 'create', $this->_params
);
2904 $retainedContact = $this->callAPISuccess('contact', 'create', $this->_params
);
2905 $this->callAPISuccess('contact', 'merge', array(
2906 'to_keep_id' => $retainedContact['id'],
2907 'to_remove_id' => $otherContact['id'],
2908 'auto_flip' => FALSE,
2911 $contacts = $this->callAPISuccess('contact', 'get', $this->_params
);
2912 $this->assertEquals($retainedContact['id'], $contacts['id']);
2913 $activity = $this->callAPISuccess('Activity', 'getsingle', array(
2914 'target_contact_id' => $retainedContact['id'],
2915 'activity_type_id' => 'Contact Merged',
2917 $this->assertEquals(date('Y-m-d'), date('Y-m-d', strtotime($activity['activity_date_time'])));
2918 $activity2 = $this->callAPISuccess('Activity', 'getsingle', array(
2919 'target_contact_id' => $otherContact['id'],
2920 'activity_type_id' => 'Contact Deleted by Merge',
2922 $this->assertEquals($activity['id'], $activity2['parent_id']);
2923 $this->assertEquals('Normal', civicrm_api3('option_value', 'getvalue', array(
2924 'value' => $activity['priority_id'],
2925 'return' => 'label',
2926 'option_group_id' => 'priority',
2932 * Test merging 2 contacts with delete to trash off.
2934 * We are checking that there is no error due to attempting to add an activity for the
2939 public function testMergeNoTrash() {
2940 $this->createLoggedInUser();
2941 $this->callAPISuccess('Setting', 'create', array('contact_undelete' => FALSE));
2942 $otherContact = $this->callAPISuccess('contact', 'create', $this->_params
);
2943 $retainedContact = $this->callAPISuccess('contact', 'create', $this->_params
);
2944 $this->callAPISuccess('contact', 'merge', array(
2945 'to_keep_id' => $retainedContact['id'],
2946 'to_remove_id' => $otherContact['id'],
2947 'auto_flip' => FALSE,
2949 $this->callAPISuccess('Setting', 'create', array('contact_undelete' => TRUE));