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 * Include class definitions
35 require_once 'CiviTest/CiviUnitTestCase.php';
39 * Test APIv3 civicrm_contact* functions
41 * @package CiviCRM_APIv3
42 * @subpackage API_Contact
44 class api_v3_ContactTest
extends CiviUnitTestCase
{
45 public $DBResetRequired = FALSE;
46 protected $_apiversion;
50 protected $_contactID;
51 protected $_financialTypeId = 1;
54 * Test setup for every test.
56 * Connect to the database, truncate the tables that will be used
57 * and redirect stdin to a temporary file
59 public function setUp() {
60 // Connect to the database.
62 $this->_apiversion
= 3;
63 $this->_entity
= 'contact';
64 $this->_params
= array(
65 'first_name' => 'abc1',
66 'contact_type' => 'Individual',
67 'last_name' => 'xyz1',
72 * Restore the DB for the next test.
76 public function tearDown() {
77 // truncate a few tables
78 $tablesToTruncate = array(
81 'civicrm_contribution',
84 'civicrm_relationship',
90 $this->quickCleanup($tablesToTruncate, TRUE);
94 * Test civicrm_contact_create.
96 * Verify that attempt to create individual contact with only
97 * first and last names succeeds
99 public function testAddCreateIndividual() {
100 $oldCount = CRM_Core_DAO
::singleValueQuery('select count(*) from civicrm_contact');
102 'first_name' => 'abc1',
103 'contact_type' => 'Individual',
104 'last_name' => 'xyz1',
107 $contact = $this->callAPISuccess('contact', 'create', $params);
108 $this->assertTrue(is_numeric($contact['id']));
109 $this->assertTrue($contact['id'] > 0);
110 $newCount = CRM_Core_DAO
::singleValueQuery('select count(*) from civicrm_contact');
111 $this->assertEquals($oldCount +
1, $newCount);
113 $this->assertDBState('CRM_Contact_DAO_Contact',
120 * Test civicrm_contact_create.
122 * Verify that preferred language can be set.
124 public function testAddCreateIndividualWithPreferredLanguage() {
126 'first_name' => 'abc1',
127 'contact_type' => 'Individual',
128 'last_name' => 'xyz1',
129 'preferred_language' => 'es_ES',
132 $contact = $this->callAPISuccess('contact', 'create', $params);
133 $this->getAndCheck($params, $contact['id'], 'Contact');
137 * Test civicrm_contact_create with sub-types.
139 * Verify that sub-types are created successfully and not deleted by subsequent updates.
141 public function testIndividualSubType() {
143 'first_name' => 'test abc',
144 'contact_type' => 'Individual',
145 'last_name' => 'test xyz',
146 'contact_sub_type' => array('Student', 'Staff'),
148 $contact = $this->callAPISuccess('contact', 'create', $params);
149 $cid = $contact['id'];
153 'middle_name' => 'foo',
155 $this->callAPISuccess('contact', 'create', $params);
156 unset($params['middle_name']);
158 $contact = $this->callAPISuccess('contact', 'get', $params);
160 $this->assertEquals(array('Student', 'Staff'), $contact['values'][$cid]['contact_sub_type']);
164 * Verify that attempt to create contact with empty params fails.
166 public function testCreateEmptyContact() {
167 $this->callAPIFailure('contact', 'create', array());
171 * Verify that attempt to create contact with bad contact type fails.
173 public function testCreateBadTypeContact() {
175 'email' => 'man1@yahoo.com',
176 'contact_type' => 'Does not Exist',
178 $this->callAPIFailure('contact', 'create', $params, "'Does not Exist' is not a valid option for field contact_type");
182 * Verify that attempt to create individual contact without required fields fails.
184 public function testCreateBadRequiredFieldsIndividual() {
186 'middle_name' => 'This field is not required',
187 'contact_type' => 'Individual',
189 $this->callAPIFailure('contact', 'create', $params);
193 * Verify that attempt to create household contact without required fields fails.
195 public function testCreateBadRequiredFieldsHousehold() {
197 'middle_name' => 'This field is not required',
198 'contact_type' => 'Household',
200 $this->callAPIFailure('contact', 'create', $params);
204 * Test required field check.
206 * Verify that attempt to create organization contact without required fields fails.
208 public function testCreateBadRequiredFieldsOrganization() {
210 'middle_name' => 'This field is not required',
211 'contact_type' => 'Organization',
214 $this->callAPIFailure('contact', 'create', $params);
218 * Verify that attempt to create individual contact with only an email succeeds.
220 public function testCreateEmailIndividual() {
223 'email' => 'man3@yahoo.com',
224 'contact_type' => 'Individual',
225 'location_type_id' => 1,
228 $contact = $this->callAPISuccess('contact', 'create', $params);
230 $this->assertEquals(1, $contact['id']);
231 $email = $this->callAPISuccess('email', 'get', array('contact_id' => $contact['id']));
232 $this->assertEquals(1, $email['count']);
233 $this->assertEquals('man3@yahoo.com', $email['values'][$email['id']]['email']);
235 $this->callAPISuccess('contact', 'delete', $contact);
239 * Test creating individual by name.
241 * Verify create individual contact with only first and last names succeeds.
243 public function testCreateNameIndividual() {
245 'first_name' => 'abc1',
246 'contact_type' => 'Individual',
247 'last_name' => 'xyz1',
250 $contact = $this->callAPISuccess('contact', 'create', $params);
251 $this->assertEquals(1, $contact['id']);
255 * Test creating individual by display_name.
257 * Display name & sort name should be set.
259 public function testCreateDisplayNameIndividual() {
261 'display_name' => 'abc1',
262 'contact_type' => 'Individual',
265 $contact = $this->callAPISuccess('contact', 'create', $params);
266 $params['sort_name'] = 'abc1';
267 $this->getAndCheck($params, $contact['id'], 'contact');
271 * Test old keys still work.
273 * Verify that attempt to create individual contact with
274 * first and last names and old key values works
276 public function testCreateNameIndividualOldKeys() {
278 'individual_prefix' => 'Dr.',
279 'first_name' => 'abc1',
280 'contact_type' => 'Individual',
281 'last_name' => 'xyz1',
282 'individual_suffix' => 'Jr.',
285 $contact = $this->callAPISuccess('contact', 'create', $params);
286 $result = $this->callAPISuccess('contact', 'getsingle', array('id' => $contact['id']));
288 $this->assertArrayKeyExists('prefix_id', $result);
289 $this->assertArrayKeyExists('suffix_id', $result);
290 $this->assertArrayKeyExists('gender_id', $result);
291 $this->assertEquals(4, $result['prefix_id']);
292 $this->assertEquals(1, $result['suffix_id']);
296 * Test preferred keys work.
298 * Verify that attempt to create individual contact with
299 * first and last names and old key values works
301 public function testCreateNameIndividualRecommendedKeys2() {
303 'prefix_id' => 'Dr.',
304 'first_name' => 'abc1',
305 'contact_type' => 'Individual',
306 'last_name' => 'xyz1',
307 'suffix_id' => 'Jr.',
308 'gender_id' => 'Male',
311 $contact = $this->callAPISuccess('contact', 'create', $params);
312 $result = $this->callAPISuccess('contact', 'getsingle', array('id' => $contact['id']));
314 $this->assertArrayKeyExists('prefix_id', $result);
315 $this->assertArrayKeyExists('suffix_id', $result);
316 $this->assertArrayKeyExists('gender_id', $result);
317 $this->assertEquals(4, $result['prefix_id']);
318 $this->assertEquals(1, $result['suffix_id']);
322 * Test household name is sufficient for create.
324 * Verify that attempt to create household contact with only
325 * household name succeeds
327 public function testCreateNameHousehold() {
329 'household_name' => 'The abc Household',
330 'contact_type' => 'Household',
332 $contact = $this->callAPISuccess('contact', 'create', $params);
333 $this->assertEquals(1, $contact['id']);
337 * Test organization name is sufficient for create.
339 * Verify that attempt to create organization contact with only
340 * organization name succeeds.
342 public function testCreateNameOrganization() {
344 'organization_name' => 'The abc Organization',
345 'contact_type' => 'Organization',
347 $contact = $this->callAPISuccess('contact', 'create', $params);
348 $this->assertEquals(1, $contact['id']);
352 * Verify that attempt to create organization contact without organization name fails.
354 public function testCreateNoNameOrganization() {
356 'first_name' => 'The abc Organization',
357 'contact_type' => 'Organization',
359 $this->callAPIFailure('contact', 'create', $params);
363 * Check with complete array + custom field.
365 * Note that the test is written on purpose without any
366 * variables specific to participant so it can be replicated into other entities
367 * and / or moved to the automated test suite
369 public function testCreateWithCustom() {
370 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__
, __FILE__
);
372 $params = $this->_params
;
373 $params['custom_' . $ids['custom_field_id']] = "custom string";
374 $description = "This demonstrates setting a custom field through the API.";
375 $result = $this->callAPIAndDocument($this->_entity
, 'create', $params, __FUNCTION__
, __FILE__
, $description);
377 $check = $this->callAPISuccess($this->_entity
, 'get', array(
378 'return.custom_' . $ids['custom_field_id'] => 1,
379 'id' => $result['id'],
381 $this->assertEquals("custom string", $check['values'][$check['id']]['custom_' . $ids['custom_field_id']]);
383 $this->customFieldDelete($ids['custom_field_id']);
384 $this->customGroupDelete($ids['custom_group_id']);
388 * CRM-12773 - expectation is that civicrm quietly ignores fields without values.
390 public function testCreateWithNULLCustomCRM12773() {
391 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__
, __FILE__
);
392 $params = $this->_params
;
393 $params['custom_' . $ids['custom_field_id']] = NULL;
394 $this->callAPISuccess('contact', 'create', $params);
395 $this->customFieldDelete($ids['custom_field_id']);
396 $this->customGroupDelete($ids['custom_group_id']);
400 * CRM-14232 test preferred language set to site default if not passed.
402 public function testCreatePreferredLanguageUnset() {
403 $this->callAPISuccess('Contact', 'create', array(
404 'first_name' => 'Snoop',
405 'last_name' => 'Dog',
406 'contact_type' => 'Individual')
408 $result = $this->callAPISuccessGetSingle('Contact', array('last_name' => 'Dog'));
409 $this->assertEquals('en_US', $result['preferred_language']);
413 * CRM-14232 test preferred language returns setting if not passed.
415 public function testCreatePreferredLanguageSet() {
416 $this->callAPISuccess('Setting', 'create', array('contact_default_language' => 'fr_FR'));
417 $this->callAPISuccess('Contact', 'create', array(
418 'first_name' => 'Snoop',
419 'last_name' => 'Dog',
420 'contact_type' => 'Individual',
422 $result = $this->callAPISuccessGetSingle('Contact', array('last_name' => 'Dog'));
423 $this->assertEquals('fr_FR', $result['preferred_language']);
427 * CRM-14232 test preferred language returns setting if not passed where setting is NULL.
429 public function testCreatePreferredLanguageNull() {
430 $this->callAPISuccess('Setting', 'create', array('contact_default_language' => 'null'));
431 $this->callAPISuccess('Contact', 'create', array(
432 'first_name' => 'Snoop',
433 'last_name' => 'Dog',
434 'contact_type' => 'Individual',
437 $result = $this->callAPISuccessGetSingle('Contact', array('last_name' => 'Dog'));
438 $this->assertEquals(NULL, $result['preferred_language']);
442 * CRM-14232 test preferred language returns setting if not passed where setting is NULL.
444 public function testCreatePreferredLanguagePassed() {
445 $this->callAPISuccess('Setting', 'create', array('contact_default_language' => 'null'));
446 $this->callAPISuccess('Contact', 'create', array(
447 'first_name' => 'Snoop',
448 'last_name' => 'Dog',
449 'contact_type' => 'Individual',
450 'preferred_language' => 'en_AU',
452 $result = $this->callAPISuccessGetSingle('Contact', array('last_name' => 'Dog'));
453 $this->assertEquals('en_AU', $result['preferred_language']);
457 * CRM-15792 - create/update datetime field for contact.
459 public function testCreateContactCustomFldDateTime() {
460 $customGroup = $this->customGroupCreate(array('extends' => 'Individual', 'title' => 'datetime_test_group'));
461 $dateTime = CRM_Utils_Date
::currentDBDate();
462 //check date custom field is saved along with time when time_format is set
464 'first_name' => 'abc3',
465 'last_name' => 'xyz3',
466 'contact_type' => 'Individual',
467 'email' => 'man3@yahoo.com',
468 'api.CustomField.create' => array(
469 'custom_group_id' => $customGroup['id'],
470 'name' => 'test_datetime',
471 'label' => 'Demo Date',
472 'html_type' => 'Select Date',
473 'data_type' => 'Date',
477 'is_searchable' => 0,
482 $result = $this->callAPIAndDocument('Contact', 'create', $params, __FUNCTION__
, __FILE__
);
483 $customFldId = $result['values'][$result['id']]['api.CustomField.create']['id'];
484 $this->assertNotNull($result['id']);
485 $this->assertNotNull($customFldId);
488 'id' => $result['id'],
489 "custom_{$customFldId}" => $dateTime,
490 'api.CustomValue.get' => 1,
493 $result = $this->callAPIAndDocument('Contact', 'create', $params, __FUNCTION__
, __FILE__
);
494 $this->assertNotNull($result['id']);
495 $customFldDate = date("YmdHis", strtotime($result['values'][$result['id']]['api.CustomValue.get']['values'][0]['latest']));
496 $this->assertNotNull($customFldDate);
497 $this->assertEquals($dateTime, $customFldDate);
498 $customValueId = $result['values'][$result['id']]['api.CustomValue.get']['values'][0]['id'];
499 $dateTime = date('Ymd');
500 //date custom field should not contain time part when time_format is null
502 'id' => $result['id'],
503 'api.CustomField.create' => array(
504 'id' => $customFldId,
505 'html_type' => 'Select Date',
506 'data_type' => 'Date',
509 'api.CustomValue.create' => array(
510 'id' => $customValueId,
511 'entity_id' => $result['id'],
512 "custom_{$customFldId}" => $dateTime,
514 'api.CustomValue.get' => 1,
516 $result = $this->callAPIAndDocument('Contact', 'create', $params, __FUNCTION__
, __FILE__
);
517 $this->assertNotNull($result['id']);
518 $customFldDate = date("Ymd", strtotime($result['values'][$result['id']]['api.CustomValue.get']['values'][0]['latest']));
519 $customFldTime = date("His", strtotime($result['values'][$result['id']]['api.CustomValue.get']['values'][0]['latest']));
520 $this->assertNotNull($customFldDate);
521 $this->assertEquals($dateTime, $customFldDate);
522 $this->assertEquals(000000, $customFldTime);
523 $this->callAPIAndDocument('Contact', 'create', $params, __FUNCTION__
, __FILE__
);
528 * Test creating a current employer through API.
530 public function testContactCreateCurrentEmployer() {
531 // Here we will just do the get for set-up purposes.
532 $count = $this->callAPISuccess('contact', 'getcount', array(
533 'organization_name' => 'new employer org',
534 'contact_type' => 'Organization',
536 $this->assertEquals(0, $count);
537 $employerResult = $this->callAPISuccess('contact', 'create', array_merge($this->_params
, array(
538 'current_employer' => 'new employer org',
541 // do it again as an update to check it doesn't cause an error
542 $employerResult = $this->callAPISuccess('contact', 'create', array_merge($this->_params
, array(
543 'current_employer' => 'new employer org',
544 'id' => $employerResult['id'],
548 $this->callAPISuccess('contact', 'getcount', array(
549 'organization_name' => 'new employer org',
550 'contact_type' => 'Organization',
554 $result = $this->callAPISuccess('contact', 'getsingle', array(
555 'id' => $employerResult['id'],
558 $this->assertEquals('new employer org', $result['current_employer']);
563 * Test creating a current employer through API.
565 * Check it will re-activate a de-activated employer
567 public function testContactCreateDuplicateCurrentEmployerEnables() {
568 // Set up - create employer relationship.
569 $employerResult = $this->callAPISuccess('contact', 'create', array_merge($this->_params
, array(
570 'current_employer' => 'new employer org',
573 $relationship = $this->callAPISuccess('relationship', 'get', array(
574 'contact_id_a' => $employerResult['id'],
577 //disable & check it is disabled
578 $this->callAPISuccess('relationship', 'create', array('id' => $relationship['id'], 'is_active' => 0));
579 $this->callAPISuccess('relationship', 'getvalue', array(
580 'id' => $relationship['id'],
581 'return' => 'is_active',
584 // Re-set the current employer - thus enabling the relationship.
585 $this->callAPISuccess('contact', 'create', array_merge($this->_params
, array(
586 'current_employer' => 'new employer org',
587 'id' => $employerResult['id'],
590 //check is_active is now 1
591 $relationship = $this->callAPISuccess('relationship', 'getsingle', array(
592 'return' => 'is_active',
594 $this->assertEquals(1, $relationship['is_active']);
598 * Check deceased contacts are not retrieved.
600 * Note at time of writing the default is to return default. This should possibly be changed & test added.
602 public function testGetDeceasedRetrieved() {
603 $this->callAPISuccess($this->_entity
, 'create', $this->_params
);
604 $c2 = $this->callAPISuccess($this->_entity
, 'create', array(
605 'first_name' => 'bb',
606 'last_name' => 'ccc',
607 'contact_type' => 'Individual',
610 $result = $this->callAPISuccess($this->_entity
, 'get', array('is_deceased' => 0));
611 $this->assertFalse(array_key_exists($c2['id'], $result['values']));
615 * Test that sort works - old syntax.
617 public function testGetSort() {
618 $c1 = $this->callAPISuccess($this->_entity
, 'create', $this->_params
);
619 $c2 = $this->callAPISuccess($this->_entity
, 'create', array(
620 'first_name' => 'bb',
621 'last_name' => 'ccc',
622 'contact_type' => 'Individual',
624 $result = $this->callAPISuccess($this->_entity
, 'get', array(
625 'sort' => 'first_name ASC',
626 'return.first_name' => 1,
631 $this->assertEquals('abc1', $result['values'][0]['first_name']);
632 $result = $this->callAPISuccess($this->_entity
, 'get', array(
633 'sort' => 'first_name DESC',
634 'return.first_name' => 1,
638 $this->assertEquals('bb', $result['values'][0]['first_name']);
640 $this->callAPISuccess($this->_entity
, 'delete', array('id' => $c1['id']));
641 $this->callAPISuccess($this->_entity
, 'delete', array('id' => $c2['id']));
645 * Test that we can retrieve contacts using array syntax.
647 * I.e 'id' => array('IN' => array('3,4')).
649 public function testGetINIDArray() {
650 $c1 = $this->callAPISuccess($this->_entity
, 'create', $this->_params
);
651 $c2 = $this->callAPISuccess($this->_entity
, 'create', array(
652 'first_name' => 'bb',
653 'last_name' => 'ccc',
654 'contact_type' => 'Individual',
656 $c3 = $this->callAPISuccess($this->_entity
, 'create', array(
657 'first_name' => 'hh',
659 'contact_type' => 'Individual',
661 $result = $this->callAPISuccess($this->_entity
, 'get', array('id' => array('IN' => array($c1['id'], $c3['id']))));
662 $this->assertEquals(2, $result['count']);
663 $this->assertEquals(array($c1['id'], $c3['id']), array_keys($result['values']));
664 $this->callAPISuccess($this->_entity
, 'delete', array('id' => $c1['id']));
665 $this->callAPISuccess($this->_entity
, 'delete', array('id' => $c2['id']));
666 $this->callAPISuccess($this->_entity
, 'delete', array('id' => $c3['id']));
670 * Test variants on deleted behaviour.
672 public function testGetDeleted() {
673 $params = $this->_params
;
674 $contact1 = $this->callAPISuccess('contact', 'create', $params);
675 $params['is_deleted'] = 1;
676 $params['last_name'] = 'bcd';
677 $contact2 = $this->callAPISuccess('contact', 'create', $params);
678 $countActive = $this->callAPISuccess('contact', 'getcount', array('showAll' => 'active'));
679 $countAll = $this->callAPISuccess('contact', 'getcount', array('showAll' => 'all'));
680 $countTrash = $this->callAPISuccess('contact', 'getcount', array('showAll' => 'trash'));
681 $countDefault = $this->callAPISuccess('contact', 'getcount', array());
682 $countDeleted = $this->callAPISuccess('contact', 'getcount', array(
683 'contact_is_deleted' => 1,
685 $countNotDeleted = $this->callAPISuccess('contact', 'getcount', array(
686 'contact_is_deleted' => 0,
688 $this->callAPISuccess('contact', 'delete', array('id' => $contact1['id']));
689 $this->callAPISuccess('contact', 'delete', array('id' => $contact2['id']));
690 $this->assertEquals(1, $countNotDeleted, 'contact_is_deleted => 0 is respected in line ' . __LINE__
);
691 $this->assertEquals(1, $countActive);
692 $this->assertEquals(1, $countTrash);
693 $this->assertEquals(2, $countAll);
694 $this->assertEquals(1, $countDeleted);
695 $this->assertEquals(1, $countDefault, 'Only active by default in line ' . __LINE__
);
699 * Test that sort works - new syntax.
701 public function testGetSortNewSyntax() {
702 $c1 = $this->callAPISuccess($this->_entity
, 'create', $this->_params
);
703 $c2 = $this->callAPISuccess($this->_entity
, 'create', array(
704 'first_name' => 'bb',
705 'last_name' => 'ccc',
706 'contact_type' => 'Individual',
708 $result = $this->callAPISuccess($this->_entity
, 'getvalue', array(
709 'return' => 'first_name',
712 'sort' => 'first_name',
715 $this->assertEquals('abc1', $result, 'in line' . __LINE__
);
717 $result = $this->callAPISuccess($this->_entity
, 'getvalue', array(
718 'return' => 'first_name',
721 'sort' => 'first_name DESC',
724 $this->assertEquals('bb', $result);
726 $this->callAPISuccess($this->_entity
, 'delete', array('id' => $c1['id']));
727 $this->callAPISuccess($this->_entity
, 'delete', array('id' => $c2['id']));
731 * Test sort and limit for chained relationship get.
733 * https://issues.civicrm.org/jira/browse/CRM-15983
735 public function testSortLimitChainedRelationshipGetCRM15983() {
737 $create_result_1 = $this->callAPISuccess('contact', 'create', array(
738 'first_name' => 'Jules',
739 'last_name' => 'Smos',
740 'contact_type' => 'Individual',
743 // Create another contact with two relationships.
744 $create_params = array(
745 'first_name' => 'Jos',
746 'last_name' => 'Smos',
747 'contact_type' => 'Individual',
748 'api.relationship.create' => array(
750 'contact_id_a' => '$value.id',
751 'contact_id_b' => $create_result_1['id'],
753 'relationship_type_id' => 2,
754 'start_date' => '2005-01-12',
755 'end_date' => '2006-01-11',
756 'description' => 'old',
759 'contact_id_a' => '$value.id',
760 'contact_id_b' => $create_result_1['id'],
761 // spouse of (was married twice :))
762 'relationship_type_id' => 2,
763 'start_date' => '2006-07-01',
764 'end_date' => '2010-07-01',
765 'description' => 'new',
769 $create_result = $this->callAPISuccess('contact', 'create', $create_params);
771 // Try to retrieve the contact and the most recent relationship.
774 'id' => $create_result['id'],
775 'api.relationship.get' => array(
776 'contact_id_a' => '$value.id',
779 'sort' => 'start_date DESC',
782 $get_result = $this->callAPISuccess('contact', 'getsingle', $get_params);
785 $this->callAPISuccess('contact', 'delete', array(
786 'id' => $create_result['id'],
790 $this->assertEquals(1, $get_result['api.relationship.get']['count']);
791 $this->assertEquals('new', $get_result['api.relationship.get']['values'][0]['description']);
795 * Test apostrophe works in get & create.
797 public function testGetApostropheCRM10857() {
798 $params = array_merge($this->_params
, array('last_name' => "O'Connor"));
799 $this->callAPISuccess($this->_entity
, 'create', $params);
800 $result = $this->callAPISuccess($this->_entity
, 'getsingle', array(
801 'last_name' => "O'Connor",
804 $this->assertEquals("O'Connor", $result['last_name'], 'in line' . __LINE__
);
808 * Check with complete array + custom field.
810 * Note that the test is written on purpose without any
811 * variables specific to participant so it can be replicated into other entities
812 * and / or moved to the automated test suite
814 public function testGetWithCustom() {
815 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__
, __FILE__
);
817 $params = $this->_params
;
818 $params['custom_' . $ids['custom_field_id']] = "custom string";
819 $description = "This demonstrates setting a custom field through the API.";
820 $subfile = "CustomFieldGet";
821 $result = $this->callAPISuccess($this->_entity
, 'create', $params);
823 $check = $this->callAPIAndDocument($this->_entity
, 'get', array(
824 'return.custom_' . $ids['custom_field_id'] => 1,
825 'id' => $result['id'],
826 ), __FUNCTION__
, __FILE__
, $description, $subfile);
828 $this->assertEquals("custom string", $check['values'][$check['id']]['custom_' . $ids['custom_field_id']]);
829 $fields = ($this->callAPISuccess('contact', 'getfields', $params));
830 $this->assertTrue(is_array($fields['values']['custom_' . $ids['custom_field_id']]));
831 $this->customFieldDelete($ids['custom_field_id']);
832 $this->customGroupDelete($ids['custom_group_id']);
836 * Check with complete array + custom field.
838 * Note that the test is written on purpose without any
839 * variables specific to participant so it can be replicated into other entities
840 * and / or moved to the automated test suite
842 public function testGetWithCustomReturnSyntax() {
843 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__
, __FILE__
);
845 $params = $this->_params
;
846 $params['custom_' . $ids['custom_field_id']] = "custom string";
847 $description = "This demonstrates setting a custom field through the API.";
848 $subfile = "CustomFieldGetReturnSyntaxVariation";
849 $result = $this->callAPISuccess($this->_entity
, 'create', $params);
850 $params = array('return' => 'custom_' . $ids['custom_field_id'], 'id' => $result['id']);
851 $check = $this->callAPIAndDocument($this->_entity
, 'get', $params, __FUNCTION__
, __FILE__
, $description, $subfile);
853 $this->assertEquals("custom string", $check['values'][$check['id']]['custom_' . $ids['custom_field_id']]);
854 $this->customFieldDelete($ids['custom_field_id']);
855 $this->customGroupDelete($ids['custom_group_id']);
859 * Check that address name is returned if required.
861 public function testGetReturnAddressName() {
862 $contactID = $this->individualCreate();
863 $this->callAPISuccess('address', 'create', array(
864 'contact_id' => $contactID,
865 'address_name' => 'My house',
866 'location_type_id' => 'Home',
867 'street_address' => '1 my road',
869 $result = $this->callAPISuccessGetSingle('contact', array(
870 'return' => 'address_name, street_address',
873 $this->assertEquals('1 my road', $result['street_address']);
874 $this->assertEquals('My house', $result['address_name']);
879 * Test group filter syntaxes.
881 public function testGetGroupIDFromContact() {
882 $groupId = $this->groupCreate();
883 $description = "Get all from group and display contacts.";
884 $subFile = "GroupFilterUsingContactAPI";
886 'email' => 'man2@yahoo.com',
887 'contact_type' => 'Individual',
888 'location_type_id' => 1,
889 'api.group_contact.create' => array('group_id' => $groupId),
892 $this->callAPISuccess('contact', 'create', $params);
893 // testing as integer
895 'filter.group_id' => $groupId,
896 'contact_type' => 'Individual',
898 $result = $this->callAPIAndDocument('contact', 'get', $params, __FUNCTION__
, __FILE__
, $description, $subFile);
899 $this->assertEquals(1, $result['count']);
900 // group 26 doesn't exist, but we can still search contacts in it.
902 'filter.group_id' => 26,
903 'contact_type' => 'Individual',
905 $this->callAPISuccess('contact', 'get', $params);
908 'filter.group_id' => "$groupId, 26",
909 'contact_type' => 'Individual',
911 $result = $this->callAPIAndDocument('contact', 'get', $params, __FUNCTION__
, __FILE__
, $description, $subFile);
912 $this->assertEquals(1, $result['count']);
914 'filter.group_id' => "26,27",
915 'contact_type' => 'Individual',
917 $this->callAPISuccess('contact', 'get', $params);
921 'filter.group_id' => array($groupId, 26),
922 'contact_type' => 'Individual',
924 $result = $this->callAPIAndDocument('contact', 'get', $params, __FUNCTION__
, __FILE__
, $description, $subFile);
925 $this->assertEquals(1, $result['count']);
927 //test in conjunction with other criteria
929 'filter.group_id' => array($groupId, 26),
930 'contact_type' => 'Organization',
932 $this->callAPISuccess('contact', 'get', $params);
934 'filter.group_id' => array(26, 27),
935 'contact_type' => 'Individual',
937 $result = $this->callAPISuccess('contact', 'get', $params);
938 $this->assertEquals(0, $result['count']);
942 * Verify that attempt to create individual contact with two chained websites succeeds.
944 public function testCreateIndividualWithContributionDottedSyntax() {
945 $description = "This demonstrates the syntax to create 2 chained entities.";
946 $subFile = "ChainTwoWebsites";
948 'first_name' => 'abc3',
949 'last_name' => 'xyz3',
950 'contact_type' => 'Individual',
951 'email' => 'man3@yahoo.com',
952 'api.contribution.create' => array(
953 'receive_date' => '2010-01-01',
954 'total_amount' => 100.00,
955 'financial_type_id' => $this->_financialTypeId
,
956 'payment_instrument_id' => 1,
957 'non_deductible_amount' => 10.00,
958 'fee_amount' => 50.00,
959 'net_amount' => 90.00,
961 'invoice_id' => 67990,
963 'contribution_status_id' => 1,
965 'api.website.create' => array(
966 'url' => "http://civicrm.org",
968 'api.website.create.2' => array(
969 'url' => "http://chained.org",
973 $result = $this->callAPIAndDocument('Contact', 'create', $params, __FUNCTION__
, __FILE__
, $description, $subFile);
975 $this->assertEquals(1, $result['id']);
976 // checking child function result not covered in callAPIAndDocument
977 $this->assertAPISuccess($result['values'][$result['id']]['api.website.create']);
978 $this->assertEquals("http://chained.org", $result['values'][$result['id']]['api.website.create.2']['values'][0]['url']);
979 $this->assertEquals("http://civicrm.org", $result['values'][$result['id']]['api.website.create']['values'][0]['url']);
981 // delete the contact
982 $this->callAPISuccess('contact', 'delete', $result);
986 * Verify that attempt to create individual contact with chained contribution and website succeeds.
988 public function testCreateIndividualWithContributionChainedArrays() {
990 'first_name' => 'abc3',
991 'last_name' => 'xyz3',
992 'contact_type' => 'Individual',
993 'email' => 'man3@yahoo.com',
994 'api.contribution.create' => array(
995 'receive_date' => '2010-01-01',
996 'total_amount' => 100.00,
997 'financial_type_id' => $this->_financialTypeId
,
998 'payment_instrument_id' => 1,
999 'non_deductible_amount' => 10.00,
1000 'fee_amount' => 50.00,
1001 'net_amount' => 90.00,
1003 'invoice_id' => 67890,
1005 'contribution_status_id' => 1,
1007 'api.website.create' => array(
1009 'url' => "http://civicrm.org",
1012 'url' => "http://chained.org",
1013 'website_type_id' => 2,
1018 $description = "Demonstrates creating two websites as an array.";
1019 $subfile = "ChainTwoWebsitesSyntax2";
1020 $result = $this->callAPIAndDocument('Contact', 'create', $params, __FUNCTION__
, __FILE__
, $description, $subfile);
1022 $this->assertEquals(1, $result['id']);
1023 // the callAndDocument doesn't check the chained call
1024 $this->assertEquals(0, $result['values'][$result['id']]['api.website.create'][0]['is_error']);
1025 $this->assertEquals("http://chained.org", $result['values'][$result['id']]['api.website.create'][1]['values'][0]['url']);
1026 $this->assertEquals("http://civicrm.org", $result['values'][$result['id']]['api.website.create'][0]['values'][0]['url']);
1028 $this->callAPISuccess('contact', 'delete', $result);
1032 * Test for direction when chaining relationships.
1034 * https://issues.civicrm.org/jira/browse/CRM-16084
1036 public function testDirectionChainingRelationshipsCRM16084() {
1037 // Some contact, called Jules.
1038 $create_result_1 = $this->callAPISuccess('contact', 'create', array(
1039 'first_name' => 'Jules',
1040 'last_name' => 'Smos',
1041 'contact_type' => 'Individual',
1044 // Another contact: Jos, child of Jules.
1045 $create_params = array(
1046 'first_name' => 'Jos',
1047 'last_name' => 'Smos',
1048 'contact_type' => 'Individual',
1049 'api.relationship.create' => array(
1051 'contact_id_a' => '$value.id',
1052 'contact_id_b' => $create_result_1['id'],
1054 'relationship_type_id' => 1,
1058 $create_result_2 = $this->callAPISuccess('contact', 'create', $create_params);
1060 // Mia is the child of Jos.
1061 $create_params = array(
1062 'first_name' => 'Mia',
1063 'last_name' => 'Smos',
1064 'contact_type' => 'Individual',
1065 'api.relationship.create' => array(
1067 'contact_id_a' => '$value.id',
1068 'contact_id_b' => $create_result_2['id'],
1070 'relationship_type_id' => 1,
1074 $create_result_3 = $this->callAPISuccess('contact', 'create', $create_params);
1076 // Get Jos and his children.
1077 $get_params = array(
1079 'id' => $create_result_2['id'],
1080 'api.relationship.get' => array(
1081 'contact_id_b' => '$value.id',
1082 'relationship_type_id' => 1,
1085 $get_result = $this->callAPISuccess('contact', 'getsingle', $get_params);
1088 $this->callAPISuccess('contact', 'delete', array(
1089 'id' => $create_result_1['id'],
1091 $this->callAPISuccess('contact', 'delete', array(
1092 'id' => $create_result_2['id'],
1094 $this->callAPISuccess('contact', 'delete', array(
1095 'id' => $create_result_2['id'],
1099 $this->assertEquals(1, $get_result['api.relationship.get']['count']);
1100 $this->assertEquals($create_result_3['id'], $get_result['api.relationship.get']['values'][0]['contact_id_a']);
1104 * Verify that attempt to create individual contact with first, and last names and email succeeds.
1106 public function testCreateIndividualWithNameEmail() {
1108 'first_name' => 'abc3',
1109 'last_name' => 'xyz3',
1110 'contact_type' => 'Individual',
1111 'email' => 'man3@yahoo.com',
1114 $contact = $this->callAPISuccess('contact', 'create', $params);
1115 $this->assertEquals(1, $contact['id']);
1117 $this->callAPISuccess('contact', 'delete', $contact);
1121 * Verify that attempt to create individual contact with no data fails.
1123 public function testCreateIndividualWithOutNameEmail() {
1125 'contact_type' => 'Individual',
1127 $this->callAPIFailure('contact', 'create', $params);
1131 * Test create individual contact with first &last names, email and location type succeeds.
1133 public function testCreateIndividualWithNameEmailLocationType() {
1135 'first_name' => 'abc4',
1136 'last_name' => 'xyz4',
1137 'email' => 'man4@yahoo.com',
1138 'contact_type' => 'Individual',
1139 'location_type_id' => 1,
1141 $result = $this->callAPISuccess('contact', 'create', $params);
1143 $this->assertEquals(1, $result['id']);
1145 $this->callAPISuccess('contact', 'delete', array('id' => $result['id']));
1149 * Verify that when changing employers the old employer relationship becomes inactive.
1151 public function testCreateIndividualWithEmployer() {
1152 $employer = $this->organizationCreate();
1153 $employer2 = $this->organizationCreate();
1156 'email' => 'man4@yahoo.com',
1157 'contact_type' => 'Individual',
1158 'employer_id' => $employer,
1161 $result = $this->callAPISuccess('contact', 'create', $params);
1162 $relationships = $this->callAPISuccess('relationship', 'get', array(
1163 'contact_id_a' => $result['id'],
1167 $this->assertEquals($employer, $relationships['values'][0]['contact_id_b']);
1169 // Add more random relationships to make the test more realistic
1170 foreach (array('Employee of', 'Volunteer for') as $relationshipType) {
1171 $relTypeId = CRM_Core_DAO
::getFieldValue('CRM_Contact_DAO_RelationshipType', $relationshipType, 'id', 'name_a_b');
1172 $this->callAPISuccess('relationship', 'create', array(
1173 'contact_id_a' => $result['id'],
1174 'contact_id_b' => $this->organizationCreate(),
1176 'relationship_type_id' => $relTypeId,
1180 // Add second employer
1181 $params['employer_id'] = $employer2;
1182 $params['id'] = $result['id'];
1183 $result = $this->callAPISuccess('contact', 'create', $params);
1185 $relationships = $this->callAPISuccess('relationship', 'get', array(
1186 'contact_id_a' => $result['id'],
1191 $this->assertEquals($employer, $relationships['values'][0]['contact_id_b']);
1195 * Verify that attempt to create household contact with details succeeds.
1197 public function testCreateHouseholdDetails() {
1199 'household_name' => 'abc8\'s House',
1200 'nick_name' => 'x House',
1201 'email' => 'man8@yahoo.com',
1202 'contact_type' => 'Household',
1205 $contact = $this->callAPISuccess('contact', 'create', $params);
1207 $this->assertEquals(1, $contact['id']);
1209 $this->callAPISuccess('contact', 'delete', $contact);
1213 * Verify that attempt to create household contact with inadequate details fails.
1215 public function testCreateHouseholdInadequateDetails() {
1217 'nick_name' => 'x House',
1218 'email' => 'man8@yahoo.com',
1219 'contact_type' => 'Household',
1221 $this->callAPIFailure('contact', 'create', $params);
1225 * Verify successful update of individual contact.
1227 public function testUpdateIndividualWithAll() {
1228 // Insert a row in civicrm_contact creating individual contact.
1229 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1230 $op->execute($this->_dbconn
,
1231 $this->createXMLDataSet(
1232 dirname(__FILE__
) . '/dataset/contact_ind.xml'
1238 'first_name' => 'abcd',
1239 'contact_type' => 'Individual',
1240 'nick_name' => 'This is nickname first',
1241 'do_not_email' => '1',
1242 'do_not_phone' => '1',
1243 'do_not_mail' => '1',
1244 'do_not_trade' => '1',
1245 'legal_identifier' => 'ABC23853ZZ2235',
1246 'external_identifier' => '1928837465',
1247 'image_URL' => 'http://some.url.com/image.jpg',
1248 'home_url' => 'http://www.example.org',
1252 $this->callAPISuccess('Contact', 'Update', $params);
1253 $getResult = $this->callAPISuccess('Contact', 'Get', $params);
1254 unset($params['contact_id']);
1255 //Todo - neither API v2 or V3 are testing for home_url - not sure if it is being set.
1256 //reducing this test partially back to api v2 level to get it through
1257 unset($params['home_url']);
1258 foreach ($params as $key => $value) {
1259 $this->assertEquals($value, $getResult['values'][23][$key]);
1261 // Check updated civicrm_contact against expected.
1262 $expected = $this->createXMLDataSet(
1263 dirname(__FILE__
) . '/dataset/contact_ind_upd.xml'
1265 $actual = new PHPUnit_Extensions_Database_DataSet_QueryDataSet(
1268 $actual->addTable('civicrm_contact');
1269 $expected->matches($actual);
1273 * Verify successful update of organization contact.
1275 public function testUpdateOrganizationWithAll() {
1276 // Insert a row in civicrm_contact creating organization contact
1277 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1278 $op->execute($this->_dbconn
,
1279 $this->createXMLDataSet(
1280 dirname(__FILE__
) . '/dataset/contact_org.xml'
1286 'organization_name' => 'WebAccess India Pvt Ltd',
1287 'legal_name' => 'WebAccess',
1288 'sic_code' => 'ABC12DEF',
1289 'contact_type' => 'Organization',
1292 $this->callAPISuccess('Contact', 'Update', $params);
1294 // Check updated civicrm_contact against expected.
1295 $expected = $this->createXMLDataSet(
1296 dirname(__FILE__
) . '/dataset/contact_org_upd.xml'
1298 $actual = new PHPUnit_Extensions_Database_DataSet_QueryDataSet(
1301 $actual->addTable('civicrm_contact');
1302 $expected->matches($actual);
1306 * Verify successful update of household contact.
1308 public function testUpdateHouseholdWithAll() {
1309 // Insert a row in civicrm_contact creating household contact
1310 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1311 $op->execute($this->_dbconn
,
1312 $this->createXMLDataSet(
1313 dirname(__FILE__
) . '/dataset/contact_hld.xml'
1319 'household_name' => 'ABC household',
1320 'nick_name' => 'ABC House',
1321 'contact_type' => 'Household',
1324 $result = $this->callAPISuccess('Contact', 'Update', $params);
1327 'contact_type' => 'Household',
1329 'sort_name' => 'ABC household',
1330 'display_name' => 'ABC household',
1331 'nick_name' => 'ABC House',
1333 $this->getAndCheck($expected, $result['id'], 'contact');
1337 * Test civicrm_update() without contact type.
1339 * Deliberately exclude contact_type as it should still cope using civicrm_api.
1343 public function testUpdateCreateWithID() {
1344 // Insert a row in civicrm_contact creating individual contact.
1345 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1346 $op->execute($this->_dbconn
,
1347 $this->createXMLDataSet(
1348 dirname(__FILE__
) . '/dataset/contact_ind.xml'
1354 'first_name' => 'abcd',
1355 'last_name' => 'wxyz',
1357 $this->callAPISuccess('Contact', 'Update', $params);
1361 * Test civicrm_contact_delete() with no contact ID.
1363 public function testContactDeleteNoID() {
1367 $this->callAPIFailure('contact', 'delete', $params);
1371 * Test civicrm_contact_delete() with error.
1373 public function testContactDeleteError() {
1374 $params = array('contact_id' => 999);
1375 $this->callAPIFailure('contact', 'delete', $params);
1379 * Test civicrm_contact_delete().
1381 public function testContactDelete() {
1382 $contactID = $this->individualCreate();
1386 $this->callAPIAndDocument('contact', 'delete', $params, __FUNCTION__
, __FILE__
);
1390 * Test civicrm_contact_get() return only first name.
1392 public function testContactGetRetFirst() {
1393 $contact = $this->callAPISuccess('contact', 'create', $this->_params
);
1395 'contact_id' => $contact['id'],
1396 'return_first_name' => TRUE,
1397 'sort' => 'first_name',
1399 $result = $this->callAPISuccess('contact', 'get', $params);
1400 $this->assertEquals(1, $result['count']);
1401 $this->assertEquals($contact['id'], $result['id']);
1402 $this->assertEquals('abc1', $result['values'][$contact['id']]['first_name']);
1406 * Test civicrm_contact_get() return only first name & last name.
1408 * Use comma separated string return with a space.
1410 public function testContactGetReturnFirstLast() {
1411 $contact = $this->callAPISuccess('contact', 'create', $this->_params
);
1413 'contact_id' => $contact['id'],
1414 'return' => 'first_name, last_name',
1416 $result = $this->callAPISuccess('contact', 'getsingle', $params);
1417 $this->assertEquals('abc1', $result['first_name']);
1418 $this->assertEquals('xyz1', $result['last_name']);
1419 //check that other defaults not returns
1420 $this->assertArrayNotHasKey('sort_name', $result);
1422 'contact_id' => $contact['id'],
1423 'return' => 'first_name,last_name',
1425 $result = $this->callAPISuccess('contact', 'getsingle', $params);
1426 $this->assertEquals('abc1', $result['first_name']);
1427 $this->assertEquals('xyz1', $result['last_name']);
1428 //check that other defaults not returns
1429 $this->assertArrayNotHasKey('sort_name', $result);
1433 * Test civicrm_contact_get() return only first name & last name.
1435 * Use comma separated string return without a space
1437 public function testContactGetReturnFirstLastNoComma() {
1438 $contact = $this->callAPISuccess('contact', 'create', $this->_params
);
1440 'contact_id' => $contact['id'],
1441 'return' => 'first_name,last_name',
1443 $result = $this->callAPISuccess('contact', 'getsingle', $params);
1444 $this->assertEquals('abc1', $result['first_name']);
1445 $this->assertEquals('xyz1', $result['last_name']);
1446 //check that other defaults not returns
1447 $this->assertArrayNotHasKey('sort_name', $result);
1451 * Test civicrm_contact_get() with default return properties.
1453 public function testContactGetRetDefault() {
1454 $contactID = $this->individualCreate();
1456 'contact_id' => $contactID,
1457 'sort' => 'first_name',
1459 $result = $this->callAPISuccess('contact', 'get', $params);
1460 $this->assertEquals($contactID, $result['values'][$contactID]['contact_id']);
1461 $this->assertEquals('Anthony', $result['values'][$contactID]['first_name']);
1465 * Test civicrm_contact_getquick() with empty name param.
1467 public function testContactGetQuick() {
1468 // Insert a row in civicrm_contact creating individual contact.
1469 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1470 $op->execute($this->_dbconn
,
1471 $this->createXMLDataSet(
1472 dirname(__FILE__
) . '/dataset/contact_17.xml'
1475 $op->execute($this->_dbconn
,
1476 $this->createXMLDataSet(
1477 dirname(__FILE__
) . '/dataset/email_contact_17.xml'
1484 $result = $this->callAPISuccess('contact', 'getquick', $params);
1485 $this->assertEquals(17, $result['values'][0]['id']);
1489 * Test civicrm_contact_get) with empty params.
1491 public function testContactGetEmptyParams() {
1492 $this->callAPISuccess('contact', 'get', array());
1496 * Test civicrm_contact_get(,true) with no matches.
1498 public function testContactGetOldParamsNoMatches() {
1499 // Insert a row in civicrm_contact creating contact 17.
1500 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1501 $op->execute($this->_dbconn
,
1502 $this->createXMLDataSet(
1503 dirname(__FILE__
) . '/dataset/contact_17.xml'
1508 'first_name' => 'Fred',
1510 $result = $this->callAPISuccess('contact', 'get', $params);
1511 $this->assertEquals(0, $result['count']);
1515 * Test civicrm_contact_get(,true) with one match.
1517 public function testContactGetOldParamsOneMatch() {
1518 // Insert a row in civicrm_contact creating contact 17
1519 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1520 $op->execute($this->_dbconn
,
1521 $this->createXMLDataSet(dirname(__FILE__
) . '/dataset/contact_17.xml'
1526 'first_name' => 'Test',
1528 $result = $this->callAPISuccess('contact', 'get', $params);
1529 $this->assertEquals(17, $result['values'][17]['contact_id']);
1530 $this->assertEquals(17, $result['id']);
1534 * Test civicrm_contact_search_count().
1536 public function testContactGetEmail() {
1538 'email' => 'man2@yahoo.com',
1539 'contact_type' => 'Individual',
1540 'location_type_id' => 1,
1543 $contact = $this->callAPISuccess('contact', 'create', $params);
1545 $this->assertEquals(1, $contact['id']);
1548 'email' => 'man2@yahoo.com',
1550 $result = $this->callAPIAndDocument('contact', 'get', $params, __FUNCTION__
, __FILE__
);
1551 $this->assertEquals(1, $result['values'][1]['contact_id']);
1552 $this->assertEquals('man2@yahoo.com', $result['values'][1]['email']);
1554 // delete the contact
1555 $this->callAPISuccess('contact', 'delete', $contact);
1559 * Test birth date parameters.
1561 * These include value, array & birth_date_high, birth_date_low
1564 public function testContactGetBirthDate() {
1565 $contact1 = $this->callAPISuccess('contact', 'create', array_merge($this->_params
, array('birth_date' => 'first day of next month - 2 years')));
1566 $contact2 = $this->callAPISuccess('contact', 'create', array_merge($this->_params
, array('birth_date' => 'first day of next month - 5 years')));
1567 $contact3 = $this->callAPISuccess('contact', 'create', array_merge($this->_params
, array('birth_date' => 'first day of next month -20 years')));
1569 $result = $this->callAPISuccess('contact', 'get', array());
1570 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -2 years')), $result['values'][$contact1['id']]['birth_date']);
1571 $result = $this->callAPISuccess('contact', 'get', array('birth_date' => 'first day of next month -5 years'));
1572 $this->assertEquals(1, $result['count']);
1573 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -5 years')), $result['values'][$contact2['id']]['birth_date']);
1574 $result = $this->callAPISuccess('contact', 'get', array('birth_date_high' => date('Y-m-d', strtotime('-6 years'))));
1575 $this->assertEquals(1, $result['count']);
1576 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -20 years')), $result['values'][$contact3['id']]['birth_date']);
1577 $result = $this->callAPISuccess('contact', 'get', array(
1578 'birth_date_low' => date('Y-m-d', strtotime('-6 years')),
1579 'birth_date_high' => date('Y-m-d', strtotime('- 3 years')),
1581 $this->assertEquals(1, $result['count']);
1582 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -5 years')), $result['values'][$contact2['id']]['birth_date']);
1583 $result = $this->callAPISuccess('contact', 'get', array(
1584 'birth_date_low' => '-6 years',
1585 'birth_date_high' => '- 3 years',
1587 $this->assertEquals(1, $result['count']);
1588 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -5 years')), $result['values'][$contact2['id']]['birth_date']);
1592 * Test Address parameters
1594 * This include state_province, state_province_name, country
1596 public function testContactGetWithAddressFields() {
1597 $individuals = array(
1599 'first_name' => 'abc1',
1600 'contact_type' => 'Individual',
1601 'last_name' => 'xyz1',
1602 'api.address.create' => array(
1603 'country' => 'United States',
1604 'state_province_id' => 'Michigan',
1605 'location_type_id' => 1,
1609 'first_name' => 'abc2',
1610 'contact_type' => 'Individual',
1611 'last_name' => 'xyz2',
1612 'api.address.create' => array(
1613 'country' => 'United States',
1614 'state_province_id' => 'Alabama',
1615 'location_type_id' => 1,
1619 foreach ($individuals as $params) {
1620 $contact = $this->callAPISuccess('contact', 'create', $params);
1623 // Check whether Contact get API return successfully with below Address params.
1624 $fieldsToTest = array(
1625 'state_province_name' => 'Michigan',
1626 'state_province' => 'Michigan',
1627 'country' => 'United States',
1628 'state_province_name' => array('IN' => array('Michigan', 'Alabama')),
1629 'state_province' => array('IN' => array('Michigan', 'Alabama')),
1631 foreach ($fieldsToTest as $field => $value) {
1633 'id' => $contact['id'],
1636 $result = $this->callAPISuccess('Contact', 'get', $getParams);
1637 $this->assertEquals(1, $result['count']);
1642 * Test Deceased date parameters.
1644 * These include value, array & Deceased_date_high, Deceased date_low
1647 public function testContactGetDeceasedDate() {
1648 $contact1 = $this->callAPISuccess('contact', 'create', array_merge($this->_params
, array('deceased_date' => 'first day of next month - 2 years')));
1649 $contact2 = $this->callAPISuccess('contact', 'create', array_merge($this->_params
, array('deceased_date' => 'first day of next month - 5 years')));
1650 $contact3 = $this->callAPISuccess('contact', 'create', array_merge($this->_params
, array('deceased_date' => 'first day of next month -20 years')));
1652 $result = $this->callAPISuccess('contact', 'get', array());
1653 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -2 years')), $result['values'][$contact1['id']]['deceased_date']);
1654 $result = $this->callAPISuccess('contact', 'get', array('deceased_date' => 'first day of next month -5 years'));
1655 $this->assertEquals(1, $result['count']);
1656 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -5 years')), $result['values'][$contact2['id']]['deceased_date']);
1657 $result = $this->callAPISuccess('contact', 'get', array('deceased_date_high' => date('Y-m-d', strtotime('-6 years'))));
1658 $this->assertEquals(1, $result['count']);
1659 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -20 years')), $result['values'][$contact3['id']]['deceased_date']);
1660 $result = $this->callAPISuccess('contact', 'get', array(
1661 'deceased_date_low' => '-6 years',
1662 'deceased_date_high' => date('Y-m-d', strtotime('- 3 years')),
1664 $this->assertEquals(1, $result['count']);
1665 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -5 years')), $result['values'][$contact2['id']]['deceased_date']);
1669 * Test for Contact.get id=@user:username.
1671 public function testContactGetByUsername() {
1672 // Setup - create contact with a uf-match.
1673 $cid = $this->individualCreate(array(
1674 'contact_type' => 'Individual',
1675 'first_name' => 'testGetByUsername',
1676 'last_name' => 'testGetByUsername',
1679 $ufMatchParams = array(
1680 'domain_id' => CRM_Core_Config
::domainID(),
1682 'uf_name' => 'the-email-matching-key-is-not-really-the-username',
1683 'contact_id' => $cid,
1685 $ufMatch = CRM_Core_BAO_UFMatch
::create($ufMatchParams);
1686 $this->assertTrue(is_numeric($ufMatch->id
));
1688 // setup - mock the calls to CRM_Utils_System_*::getUfId
1689 $userSystem = $this->getMock('CRM_Utils_System_UnitTests', array('getUfId'));
1690 $userSystem->expects($this->once())
1692 ->with($this->equalTo('exampleUser'))
1693 ->will($this->returnValue(99));
1694 CRM_Core_Config
::singleton()->userSystem
= $userSystem;
1697 $result = $this->callAPISuccess('Contact', 'get', array(
1698 'id' => '@user:exampleUser',
1700 $this->assertEquals('testGetByUsername', $result['values'][$cid]['first_name']);
1704 * Test to check return works OK.
1706 public function testContactGetReturnValues() {
1707 $extraParams = array(
1708 'nick_name' => 'Bob',
1710 'email' => 'e@mail.com',
1712 $contactID = $this->individualCreate($extraParams);
1713 //actually it turns out the above doesn't create a phone
1714 $this->callAPISuccess('phone', 'create', array('contact_id' => $contactID, 'phone' => '456'));
1715 $result = $this->callAPISuccess('contact', 'getsingle', array('id' => $contactID));
1716 foreach ($extraParams as $key => $value) {
1717 $this->assertEquals($result[$key], $value);
1719 //now we check they are still returned with 'return' key
1720 $result = $this->callAPISuccess('contact', 'getsingle', array(
1722 'return' => array_keys($extraParams),
1724 foreach ($extraParams as $key => $value) {
1725 $this->assertEquals($result[$key], $value);
1730 * Test creating multiple phones using chaining.
1732 * @throws \Exception
1734 public function testCRM13252MultipleChainedPhones() {
1735 $contactID = $this->householdCreate();
1736 $this->callAPISuccessGetCount('phone', array('contact_id' => $contactID), 0);
1738 'contact_id' => $contactID,
1739 'household_name' => 'Household 1',
1740 'contact_type' => 'Household',
1741 'api.phone.create' => array(
1743 'phone' => '111-111-1111',
1744 'location_type_id' => 1,
1745 'phone_type_id' => 1,
1748 'phone' => '222-222-2222',
1749 'location_type_id' => 1,
1750 'phone_type_id' => 2,
1754 $this->callAPISuccess('contact', 'create', $params);
1755 $this->callAPISuccessGetCount('phone', array('contact_id' => $contactID), 2);
1760 * Test for Contact.get id=@user:username (with an invalid username).
1762 public function testContactGetByUnknownUsername() {
1763 // setup - mock the calls to CRM_Utils_System_*::getUfId
1764 $userSystem = $this->getMock('CRM_Utils_System_UnitTests', array('getUfId'));
1765 $userSystem->expects($this->once())
1767 ->with($this->equalTo('exampleUser'))
1768 ->will($this->returnValue(NULL));
1769 CRM_Core_Config
::singleton()->userSystem
= $userSystem;
1772 $result = $this->callAPIFailure('Contact', 'get', array(
1773 'id' => '@user:exampleUser',
1775 $this->assertRegExp('/cannot be resolved to a contact ID/', $result['error_message']);
1779 * Verify attempt to create individual with chained arrays and sequential.
1781 public function testGetIndividualWithChainedArraysAndSequential() {
1782 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__
, __FILE__
);
1783 $params['custom_' . $ids['custom_field_id']] = "custom string";
1785 $moreIDs = $this->CustomGroupMultipleCreateWithFields();
1788 'first_name' => 'abc3',
1789 'last_name' => 'xyz3',
1790 'contact_type' => 'Individual',
1791 'email' => 'man3@yahoo.com',
1792 'api.website.create' => array(
1794 'url' => "http://civicrm.org",
1797 'url' => "https://civicrm.org",
1802 $result = $this->callAPISuccess('Contact', 'create', $params);
1804 // delete the contact and custom groups
1805 $this->callAPISuccess('contact', 'delete', array('id' => $result['id']));
1806 $this->customGroupDelete($ids['custom_group_id']);
1807 $this->customGroupDelete($moreIDs['custom_group_id']);
1809 $this->assertEquals($result['id'], $result['values'][0]['id']);
1810 $this->assertArrayKeyExists('api.website.create', $result['values'][0]);
1814 * Verify attempt to create individual with chained arrays.
1816 public function testGetIndividualWithChainedArrays() {
1817 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__
, __FILE__
);
1818 $params['custom_' . $ids['custom_field_id']] = "custom string";
1820 $moreIDs = $this->CustomGroupMultipleCreateWithFields();
1821 $description = "This demonstrates the usage of chained api functions.\nIn this case no notes or custom fields have been created.";
1822 $subfile = "APIChainedArray";
1824 'first_name' => 'abc3',
1825 'last_name' => 'xyz3',
1826 'contact_type' => 'Individual',
1827 'email' => 'man3@yahoo.com',
1828 'api.contribution.create' => array(
1829 'receive_date' => '2010-01-01',
1830 'total_amount' => 100.00,
1831 'financial_type_id' => 1,
1832 'payment_instrument_id' => 1,
1833 'non_deductible_amount' => 10.00,
1834 'fee_amount' => 50.00,
1835 'net_amount' => 90.00,
1837 'invoice_id' => 67890,
1839 'contribution_status_id' => 1,
1841 'api.contribution.create.1' => array(
1842 'receive_date' => '2011-01-01',
1843 'total_amount' => 120.00,
1844 'financial_type_id' => $this->_financialTypeId
= 1,
1845 'payment_instrument_id' => 1,
1846 'non_deductible_amount' => 10.00,
1847 'fee_amount' => 50.00,
1848 'net_amount' => 90.00,
1850 'invoice_id' => 67830,
1852 'contribution_status_id' => 1,
1854 'api.website.create' => array(
1856 'url' => "http://civicrm.org",
1861 $result = $this->callAPISuccess('Contact', 'create', $params);
1863 'id' => $result['id'],
1864 'api.website.get' => array(),
1865 'api.Contribution.get' => array(
1866 'total_amount' => '120.00',
1868 'api.CustomValue.get' => 1,
1869 'api.Note.get' => 1,
1871 $result = $this->callAPIAndDocument('Contact', 'Get', $params, __FUNCTION__
, __FILE__
, $description, $subfile);
1872 // delete the contact
1873 $this->callAPISuccess('contact', 'delete', $result);
1874 $this->customGroupDelete($ids['custom_group_id']);
1875 $this->customGroupDelete($moreIDs['custom_group_id']);
1876 $this->assertEquals(1, $result['id']);
1877 $this->assertEquals(0, $result['values'][$result['id']]['api.website.get']['is_error']);
1878 $this->assertEquals("http://civicrm.org", $result['values'][$result['id']]['api.website.get']['values'][0]['url']);
1882 * Verify attempt to create individual with chained arrays and sequential.
1884 * See https://issues.civicrm.org/jira/browse/CRM-15815
1886 public function testCreateIndividualWithChainedArrayAndSequential() {
1889 'first_name' => 'abc5',
1890 'last_name' => 'xyz5',
1891 'contact_type' => 'Individual',
1892 'email' => 'woman5@yahoo.com',
1893 'api.phone.create' => array(
1894 array('phone' => '03-231 07 95'),
1895 array('phone' => '03-232 51 62'),
1897 'api.website.create' => array(
1898 'url' => 'http://civicrm.org',
1901 $result = $this->callAPISuccess('Contact', 'create', $params);
1903 // I could try to parse the result to see whether the two phone numbers
1904 // and the website are there, but I am not sure about the correct format.
1905 // So I will just fetch it again before checking.
1906 // See also http://forum.civicrm.org/index.php/topic,35393.0.html
1909 'id' => $result['id'],
1910 'api.website.get' => array(),
1911 'api.phone.get' => array(),
1913 $result = $this->callAPISuccess('Contact', 'get', $params);
1915 // delete the contact
1916 $this->callAPISuccess('contact', 'delete', $result);
1918 $this->assertEquals(2, $result['values'][0]['api.phone.get']['count']);
1919 $this->assertEquals(1, $result['values'][0]['api.website.get']['count']);
1923 * Test retrieving an individual with chained array syntax.
1925 public function testGetIndividualWithChainedArraysFormats() {
1926 $description = "This demonstrates the usage of chained api functions.\nIn this case no notes or custom fields have been created.";
1927 $subfile = "APIChainedArrayFormats";
1928 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__
, __FILE__
);
1929 $params['custom_' . $ids['custom_field_id']] = "custom string";
1931 $moreIDs = $this->CustomGroupMultipleCreateWithFields();
1933 'first_name' => 'abc3',
1934 'last_name' => 'xyz3',
1935 'contact_type' => 'Individual',
1936 'email' => 'man3@yahoo.com',
1937 'api.contribution.create' => array(
1938 'receive_date' => '2010-01-01',
1939 'total_amount' => 100.00,
1940 'financial_type_id' => $this->_financialTypeId
,
1941 'payment_instrument_id' => 1,
1942 'non_deductible_amount' => 10.00,
1943 'fee_amount' => 50.00,
1944 'net_amount' => 90.00,
1946 'contribution_status_id' => 1,
1948 'api.contribution.create.1' => array(
1949 'receive_date' => '2011-01-01',
1950 'total_amount' => 120.00,
1951 'financial_type_id' => $this->_financialTypeId
,
1952 'payment_instrument_id' => 1,
1953 'non_deductible_amount' => 10.00,
1954 'fee_amount' => 50.00,
1955 'net_amount' => 90.00,
1957 'contribution_status_id' => 1,
1959 'api.website.create' => array(
1961 'url' => "http://civicrm.org",
1966 $result = $this->callAPISuccess('Contact', 'create', $params);
1968 'id' => $result['id'],
1969 'api.website.getValue' => array('return' => 'url'),
1970 'api.Contribution.getCount' => array(),
1971 'api.CustomValue.get' => 1,
1972 'api.Note.get' => 1,
1973 'api.Membership.getCount' => array(),
1975 $result = $this->callAPIAndDocument('Contact', 'Get', $params, __FUNCTION__
, __FILE__
, $description, $subfile);
1976 $this->assertEquals(1, $result['id']);
1977 $this->assertEquals(2, $result['values'][$result['id']]['api.Contribution.getCount']);
1978 $this->assertEquals(0, $result['values'][$result['id']]['api.Note.get']['is_error']);
1979 $this->assertEquals("http://civicrm.org", $result['values'][$result['id']]['api.website.getValue']);
1981 $this->callAPISuccess('contact', 'delete', $result);
1982 $this->customGroupDelete($ids['custom_group_id']);
1983 $this->customGroupDelete($moreIDs['custom_group_id']);
1987 * Test complex chaining.
1989 public function testGetIndividualWithChainedArraysAndMultipleCustom() {
1990 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__
, __FILE__
);
1991 $params['custom_' . $ids['custom_field_id']] = "custom string";
1992 $moreIDs = $this->CustomGroupMultipleCreateWithFields();
1993 $andMoreIDs = $this->CustomGroupMultipleCreateWithFields(array(
1994 'title' => "another group",
1995 'name' => 'another name',
1997 $description = "This demonstrates the usage of chained api functions with multiple custom fields.";
1998 $subfile = "APIChainedArrayMultipleCustom";
2000 'first_name' => 'abc3',
2001 'last_name' => 'xyz3',
2002 'contact_type' => 'Individual',
2003 'email' => 'man3@yahoo.com',
2004 'api.contribution.create' => array(
2005 'receive_date' => '2010-01-01',
2006 'total_amount' => 100.00,
2007 'financial_type_id' => 1,
2008 'payment_instrument_id' => 1,
2009 'non_deductible_amount' => 10.00,
2010 'fee_amount' => 50.00,
2011 'net_amount' => 90.00,
2013 'invoice_id' => 67890,
2015 'contribution_status_id' => 1,
2017 'api.contribution.create.1' => array(
2018 'receive_date' => '2011-01-01',
2019 'total_amount' => 120.00,
2020 'financial_type_id' => 1,
2021 'payment_instrument_id' => 1,
2022 'non_deductible_amount' => 10.00,
2023 'fee_amount' => 50.00,
2024 'net_amount' => 90.00,
2026 'invoice_id' => 67830,
2028 'contribution_status_id' => 1,
2030 'api.website.create' => array(
2032 'url' => "http://civicrm.org",
2035 'custom_' . $ids['custom_field_id'] => "value 1",
2036 'custom_' . $moreIDs['custom_field_id'][0] => "value 2",
2037 'custom_' . $moreIDs['custom_field_id'][1] => "warm beer",
2038 'custom_' . $andMoreIDs['custom_field_id'][1] => "vegemite",
2041 $result = $this->callAPISuccess('Contact', 'create', $params);
2042 $result = $this->callAPISuccess('Contact', 'create', array(
2043 'contact_type' => 'Individual',
2044 'id' => $result['id'],
2046 $moreIDs['custom_field_id'][0] => "value 3",
2048 $ids['custom_field_id'] => "value 4",
2052 'id' => $result['id'],
2053 'api.website.getValue' => array('return' => 'url'),
2054 'api.Contribution.getCount' => array(),
2055 'api.CustomValue.get' => 1,
2057 $result = $this->callAPIAndDocument('Contact', 'Get', $params, __FUNCTION__
, __FILE__
, $description, $subfile);
2059 $this->customGroupDelete($ids['custom_group_id']);
2060 $this->customGroupDelete($moreIDs['custom_group_id']);
2061 $this->customGroupDelete($andMoreIDs['custom_group_id']);
2062 $this->assertEquals(1, $result['id']);
2063 $this->assertEquals(0, $result['values'][$result['id']]['api.CustomValue.get']['is_error']);
2064 $this->assertEquals('http://civicrm.org', $result['values'][$result['id']]['api.website.getValue']);
2068 * Test checks usage of $values to pick & choose inputs.
2070 public function testChainingValuesCreate() {
2071 $description = "This demonstrates the usage of chained api functions. Specifically it has one 'parent function' &
2072 2 child functions - one receives values from the parent (Contact) and the other child (Tag).";
2073 $subfile = "APIChainedArrayValuesFromSiblingFunction";
2075 'display_name' => 'batman',
2076 'contact_type' => 'Individual',
2077 'api.tag.create' => array(
2078 'name' => '$value.id',
2079 'description' => '$value.display_name',
2080 'format.only_id' => 1,
2082 'api.entity_tag.create' => array('tag_id' => '$value.api.tag.create'),
2084 $result = $this->callAPIAndDocument('Contact', 'Create', $params, __FUNCTION__
, __FILE__
, $description, $subfile);
2085 $this->assertEquals(0, $result['values'][$result['id']]['api.entity_tag.create']['is_error']);
2087 $tablesToTruncate = array(
2090 'civicrm_entity_tag',
2093 $this->quickCleanup($tablesToTruncate, TRUE);
2097 * Test TrueFalse format - I couldn't come up with an easy way to get an error on Get.
2099 public function testContactGetFormatIsSuccessTrue() {
2100 $this->createContactFromXML();
2101 $description = "This demonstrates use of the 'format.is_success' param.
2102 This param causes only the success or otherwise of the function to be returned as BOOLEAN";
2103 $subfile = "FormatIsSuccess_True";
2104 $params = array('id' => 17, 'format.is_success' => 1);
2105 $result = $this->callAPIAndDocument('Contact', 'Get', $params, __FUNCTION__
, __FILE__
, $description, $subfile);
2106 $this->assertEquals(1, $result);
2107 $this->callAPISuccess('Contact', 'Delete', $params);
2111 * Test TrueFalse format.
2113 public function testContactCreateFormatIsSuccessFalse() {
2115 $description = "This demonstrates use of the 'format.is_success' param.
2116 This param causes only the success or otherwise of the function to be returned as BOOLEAN";
2117 $subfile = "FormatIsSuccess_Fail";
2118 $params = array('id' => 500, 'format.is_success' => 1);
2119 $result = $this->callAPIAndDocument('Contact', 'Create', $params, __FUNCTION__
, __FILE__
, $description, $subfile);
2120 $this->assertEquals(0, $result);
2124 * Test Single Entity format.
2126 public function testContactGetSingleEntityArray() {
2127 $this->createContactFromXML();
2128 $description = "This demonstrates use of the 'format.single_entity_array' param.
2129 This param causes the only contact to be returned as an array without the other levels.
2130 It will be ignored if there is not exactly 1 result";
2131 $subfile = "GetSingleContact";
2132 $params = array('id' => 17);
2133 $result = $this->callAPIAndDocument('Contact', 'GetSingle', $params, __FUNCTION__
, __FILE__
, $description, $subfile);
2134 $this->assertEquals('Test Contact', $result['display_name']);
2135 $this->callAPISuccess('Contact', 'Delete', $params);
2139 * Test Single Entity format.
2141 public function testContactGetFormatCountOnly() {
2142 $this->createContactFromXML();
2143 $description = "This demonstrates use of the 'getCount' action.
2144 This param causes the count of the only function to be returned as an integer.";
2145 $params = array('id' => 17);
2146 $result = $this->callAPIAndDocument('Contact', 'GetCount', $params, __FUNCTION__
, __FILE__
, $description,
2148 $this->assertEquals('1', $result);
2149 $this->callAPISuccess('Contact', 'Delete', $params);
2153 * Test id only format.
2155 public function testContactGetFormatIDOnly() {
2156 $this->createContactFromXML();
2157 $description = "This demonstrates use of the 'format.id_only' param.
2158 This param causes the id of the only entity to be returned as an integer.
2159 It will be ignored if there is not exactly 1 result";
2160 $subfile = "FormatOnlyID";
2161 $params = array('id' => 17, 'format.only_id' => 1);
2162 $result = $this->callAPIAndDocument('Contact', 'Get', $params, __FUNCTION__
, __FILE__
, $description, $subfile);
2163 $this->assertEquals('17', $result);
2164 $this->callAPISuccess('Contact', 'Delete', $params);
2168 * Test id only format.
2170 public function testContactGetFormatSingleValue() {
2171 $this->createContactFromXML();
2172 $description = "This demonstrates use of the 'format.single_value' param.
2173 This param causes only a single value of the only entity to be returned as an string.
2174 It will be ignored if there is not exactly 1 result";
2175 $subFile = "FormatSingleValue";
2176 $params = array('id' => 17, 'return' => 'display_name');
2177 $result = $this->callAPIAndDocument('Contact', 'getvalue', $params, __FUNCTION__
, __FILE__
, $description, $subFile);
2178 $this->assertEquals('Test Contact', $result);
2179 $this->callAPISuccess('Contact', 'Delete', $params);
2183 * Test that permissions are respected when creating contacts.
2185 public function testContactCreationPermissions() {
2187 'contact_type' => 'Individual',
2188 'first_name' => 'Foo',
2189 'last_name' => 'Bear',
2190 'check_permissions' => TRUE,
2192 $config = CRM_Core_Config
::singleton();
2193 $config->userPermissionClass
->permissions
= array('access CiviCRM');
2194 $result = $this->callAPIFailure('contact', 'create', $params);
2195 $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');
2197 $config->userPermissionClass
->permissions
= array('access CiviCRM', 'add contacts', 'import contacts');
2198 $this->callAPISuccess('contact', 'create', $params);
2202 * Test update with check permissions set.
2204 public function testContactUpdatePermissions() {
2206 'contact_type' => 'Individual',
2207 'first_name' => 'Foo',
2208 'last_name' => 'Bear',
2209 'check_permissions' => TRUE,
2211 $result = $this->callAPISuccess('contact', 'create', $params);
2212 $config = CRM_Core_Config
::singleton();
2214 'id' => $result['id'],
2215 'contact_type' => 'Individual',
2216 'last_name' => 'Bar',
2217 'check_permissions' => TRUE,
2220 $config->userPermissionClass
->permissions
= array('access CiviCRM');
2221 $result = $this->callAPIFailure('contact', 'update', $params);
2222 $this->assertEquals('Permission denied to modify contact record', $result['error_message']);
2224 $config->userPermissionClass
->permissions
= array(
2227 'view all contacts',
2228 'edit all contacts',
2231 $this->callAPISuccess('contact', 'update', $params);
2235 * Set up helper to create a contact.
2237 public function createContactFromXML() {
2238 // Insert a row in civicrm_contact creating contact 17.
2239 $op = new PHPUnit_Extensions_Database_Operation_Insert();
2240 $op->execute($this->_dbconn
,
2241 $this->createXMLDataSet(
2242 dirname(__FILE__
) . '/dataset/contact_17.xml'
2248 * Test contact proximity api.
2250 public function testContactProximity() {
2251 // first create a contact with a SF location with a specific
2253 $contactID = $this->organizationCreate();
2255 // now create the address
2257 'street_address' => '123 Main Street',
2258 'city' => 'San Francisco',
2260 'country_id' => 1228,
2261 'state_province_id' => 1004,
2262 'geo_code_1' => '37.79',
2263 'geo_code_2' => '-122.40',
2264 'location_type_id' => 1,
2265 'contact_id' => $contactID,
2268 $result = $this->callAPISuccess('address', 'create', $params);
2269 $this->assertEquals(1, $result['count']);
2271 // now do a proximity search with a close enough geocode and hope to match
2272 // that specific contact only!
2273 $proxParams = array(
2275 'longitude' => -122.3,
2279 $result = $this->callAPISuccess('contact', 'proximity', $proxParams);
2280 $this->assertEquals(1, $result['count']);
2284 * Test that Ajax API permission is sufficient to access getquick api.
2286 * (note that getquick api is required for autocomplete & has ACL permissions applied)
2288 public function testGetquickPermissionCRM13744() {
2289 CRM_Core_Config
::singleton()->userPermissionClass
->permissions
= array('access CiviEvent');
2290 $this->callAPIFailure('contact', 'getquick', array('name' => 'b', 'check_permissions' => TRUE));
2291 CRM_Core_Config
::singleton()->userPermissionClass
->permissions
= array('access CiviCRM');
2292 $this->callAPISuccess('contact', 'getquick', array('name' => 'b', 'check_permissions' => TRUE));
2293 CRM_Core_Config
::singleton()->userPermissionClass
->permissions
= array('access AJAX API');
2294 $this->callAPISuccess('contact', 'getquick', array('name' => 'b', 'check_permissions' => TRUE));
2298 * Test that getquick returns contacts with an exact first name match first.
2300 * The search string 'b' & 'bob' both return ordered by sort_name if includeOrderByClause
2301 * is true (default) but if it is false then matches are returned in ID order.
2303 public function testGetQuickExactFirst() {
2304 $this->getQuickSearchSampleData();
2305 $result = $this->callAPISuccess('contact', 'getquick', array('name' => 'b'));
2306 $this->assertEquals('A Bobby, Bobby', $result['values'][0]['sort_name']);
2307 $this->assertEquals('B Bobby, Bobby', $result['values'][1]['sort_name']);
2308 $result = $this->callAPISuccess('contact', 'getquick', array('name' => 'bob'));
2309 $this->assertEquals('A Bobby, Bobby', $result['values'][0]['sort_name']);
2310 $this->assertEquals('B Bobby, Bobby', $result['values'][1]['sort_name']);
2311 $this->callAPISuccess('Setting', 'create', array('includeOrderByClause' => FALSE));
2312 $result = $this->callAPISuccess('contact', 'getquick', array('name' => 'bob'));
2313 $this->assertEquals('Bob, Bob', $result['values'][0]['sort_name']);
2314 $this->assertEquals('A Bobby, Bobby', $result['values'][1]['sort_name']);
2318 * Test that getquick returns contacts with an exact first name match first.
2320 public function testGetQuickEmail() {
2321 $this->getQuickSearchSampleData();
2322 $userID = $this->createLoggedInUser();
2323 $result = $this->callAPISuccess('contact', 'getquick', array(
2326 $expectedData = array(
2327 'Bob, Bob :: bob@bob.com',
2329 'E Bobby, Bobby :: bob@bobby.com',
2330 'H Bobby, Bobby :: bob@h.com',
2332 $this->assertEquals(5, $result['count']);
2333 foreach ($expectedData as $index => $value) {
2334 $this->assertEquals($value, $result['values'][$index]['data']);
2336 $result = $this->callAPISuccess('contact', 'getquick', array(
2339 $expectedData = array(
2340 'H Bobby, Bobby :: bob@h.com',
2342 foreach ($expectedData as $index => $value) {
2343 $this->assertEquals($value, $result['values'][$index]['data']);
2345 $this->callAPISuccess('Setting', 'create', array('includeWildCardInName' => FALSE));
2346 $result = $this->callAPISuccess('contact', 'getquick', array(
2349 $this->callAPISuccess('Setting', 'create', array('includeWildCardInName' => TRUE));
2350 $this->assertEquals(0, $result['count']);
2354 * Test that getquick returns contacts with an exact first name match first.
2356 public function testGetQuickEmailACL() {
2357 $this->getQuickSearchSampleData();
2358 $userID = $this->createLoggedInUser();
2359 CRM_Core_Config
::singleton()->userPermissionClass
->permissions
= array();
2360 $result = $this->callAPISuccess('contact', 'getquick', array(
2363 $this->assertEquals(0, $result['count']);
2365 $this->hookClass
->setHook('civicrm_aclWhereClause', array($this, 'aclWhereNoBobH'));
2366 CRM_Contact_BAO_Contact_Permission
::cache($userID, CRM_Core_Permission
::VIEW
, TRUE);
2367 $result = $this->callAPISuccess('contact', 'getquick', array(
2370 // Without the acl it would be 5 like the previous email getquick test.
2371 $this->assertEquals(4, $result['count']);
2372 $expectedData = array(
2373 'Bob, Bob :: bob@bob.com',
2375 'E Bobby, Bobby :: bob@bobby.com',
2377 foreach ($expectedData as $index => $value) {
2378 $this->assertEquals($value, $result['values'][$index]['data']);
2383 * Test that getquick returns contacts with an exact first name match first.
2385 public function testGetQuickExternalID() {
2386 $this->getQuickSearchSampleData();
2387 $result = $this->callAPISuccess('contact', 'getquick', array(
2389 'field_name' => 'external_identifier',
2390 'table_name' => 'cc',
2392 $this->assertEquals(0, $result['count']);
2393 $result = $this->callAPISuccess('contact', 'getquick', array(
2395 'field_name' => 'external_identifier',
2396 'table_name' => 'cc',
2398 $this->assertEquals(1, $result['count']);
2399 $this->assertEquals('Bob, Bob', $result['values'][0]['sort_name']);
2403 * Test that getquick returns contacts with an exact first name match first.
2405 public function testGetQuickID() {
2406 $this->getQuickSearchSampleData();
2407 $result = $this->callAPISuccess('contact', 'getquick', array(
2409 'field_name' => 'id',
2410 'table_name' => 'cc',
2412 $this->assertEquals(1, $result['count']);
2413 $this->assertEquals('A Bobby, Bobby', $result['values'][0]['sort_name']);
2414 $result = $this->callAPISuccess('contact', 'getquick', array(
2416 'field_name' => 'contact_id',
2417 'table_name' => 'cc',
2419 $this->assertEquals(1, $result['count']);
2420 $this->assertEquals('A Bobby, Bobby', $result['values'][0]['sort_name']);
2424 * Test that getquick returns contacts with an exact first name match first.
2426 * Depending on the setting the sort name sort might click in next or not - test!
2428 public function testGetQuickFirstName() {
2429 $this->getQuickSearchSampleData();
2430 $this->callAPISuccess('Setting', 'create', array('includeOrderByClause' => TRUE));
2431 $result = $this->callAPISuccess('contact', 'getquick', array(
2433 'field_name' => 'first_name',
2434 'table_name' => 'cc',
2442 foreach ($expected as $index => $value) {
2443 $this->assertEquals($value, $result['values'][$index]['sort_name']);
2445 $this->callAPISuccess('Setting', 'create', array('includeOrderByClause' => FALSE));
2446 $result = $this->callAPISuccess('contact', 'getquick', array('name' => 'bob'));
2447 $this->assertEquals('Bob, Bob', $result['values'][0]['sort_name']);
2448 $this->assertEquals('A Bobby, Bobby', $result['values'][1]['sort_name']);
2452 * Test that getquick applies ACLs.
2454 public function testGetQuickFirstNameACLs() {
2455 $this->getQuickSearchSampleData();
2456 $userID = $this->createLoggedInUser();
2457 $this->callAPISuccess('Setting', 'create', array('includeOrderByClause' => TRUE));
2458 CRM_Core_Config
::singleton()->userPermissionClass
->permissions
= array();
2459 $result = $this->callAPISuccess('contact', 'getquick', array(
2461 'field_name' => 'first_name',
2462 'table_name' => 'cc',
2464 $this->assertEquals(0, $result['count']);
2466 $this->hookClass
->setHook('civicrm_aclWhereClause', array($this, 'aclWhereNoBobH'));
2467 CRM_Contact_BAO_Contact_Permission
::cache($userID, CRM_Core_Permission
::VIEW
, TRUE);
2468 $result = $this->callAPISuccess('contact', 'getquick', array(
2470 'field_name' => 'first_name',
2471 'table_name' => 'cc',
2473 $this->assertEquals('K Bobby, Bob', $result['values'][1]['sort_name']);
2474 // Without the ACL 9 would be bob@h.com.
2475 $this->assertEquals('I Bobby, Bobby', $result['values'][9]['sort_name']);
2479 * Full results returned.
2480 * @implements CRM_Utils_Hook::aclWhereClause
2482 * @param string $type
2483 * @param array $tables
2484 * @param array $whereTables
2485 * @param int $contactID
2486 * @param string $where
2488 public function aclWhereNoBobH($type, &$tables, &$whereTables, &$contactID, &$where) {
2489 $where = " (email <> 'bob@h.com' OR email IS NULL) ";
2490 $whereTables['civicrm_email'] = "LEFT JOIN civicrm_email e ON contact_a.id = e.contact_id";
2494 * Test that getquick returns contacts with an exact last name match first.
2496 public function testGetQuickLastName() {
2497 $this->getQuickSearchSampleData();
2498 $this->callAPISuccess('Setting', 'create', array('includeOrderByClause' => TRUE));
2499 $result = $this->callAPISuccess('contact', 'getquick', array(
2501 'field_name' => 'last_name',
2502 'table_name' => 'cc',
2510 foreach ($expected as $index => $value) {
2511 $this->assertEquals($value, $result['values'][$index]['sort_name']);
2513 $this->callAPISuccess('Setting', 'create', array('includeOrderByClause' => FALSE));
2514 $result = $this->callAPISuccess('contact', 'getquick', array('name' => 'bob'));
2515 $this->assertEquals('Bob, Bob :: bob@bob.com', $result['values'][0]['data']);
2519 * Test that getquick returns contacts by city.
2521 public function testGetQuickCity() {
2522 $this->getQuickSearchSampleData();
2523 $result = $this->callAPISuccess('contact', 'getquick', array(
2525 'field_name' => 'city',
2526 'table_name' => 'sts',
2528 $this->assertEquals('B Bobby, Bobby :: Toronto', $result['values'][0]['data']);
2529 $result = $this->callAPISuccess('contact', 'getquick', array(
2531 'field_name' => 'city',
2532 'table_name' => 'sts',
2534 $this->assertEquals('B Bobby, Bobby :: Toronto', $result['values'][0]['data']);
2535 $this->assertEquals('C Bobby, Bobby :: Whanganui', $result['values'][1]['data']);
2539 * Set up some sample data for testing quicksearch.
2541 public function getQuickSearchSampleData() {
2543 array('first_name' => 'Bob', 'last_name' => 'Bob', 'external_identifier' => 'abc', 'email' => 'bob@bob.com'),
2544 array('first_name' => 'Bobby', 'last_name' => 'A Bobby', 'external_identifier' => 'abcd'),
2546 'first_name' => 'Bobby',
2547 'last_name' => 'B Bobby',
2548 'external_identifier' => 'bcd',
2549 'api.address.create' => array(
2550 'street_address' => 'Sesame Street',
2551 'city' => 'Toronto',
2552 'location_type_id' => 1,
2556 'first_name' => 'Bobby',
2557 'last_name' => 'C Bobby',
2558 'external_identifier' => 'bcde',
2559 'api.address.create' => array(
2560 'street_address' => 'Te huarahi',
2561 'city' => 'Whanganui',
2562 'location_type_id' => 1,
2565 array('first_name' => 'Bobby', 'last_name' => 'D Bobby', 'external_identifier' => 'efg'),
2566 array('first_name' => 'Bobby', 'last_name' => 'E Bobby', 'external_identifier' => 'hij', 'email' => 'bob@bobby.com'),
2567 array('first_name' => 'Bobby', 'last_name' => 'F Bobby', 'external_identifier' => 'klm'),
2568 array('first_name' => 'Bobby', 'last_name' => 'G Bobby', 'external_identifier' => 'nop'),
2569 array('first_name' => 'Bobby', 'last_name' => 'H Bobby', 'external_identifier' => 'qrs', 'email' => 'bob@h.com'),
2570 array('first_name' => 'Bobby', 'last_name' => 'I Bobby'),
2571 array('first_name' => 'Bobby', 'last_name' => 'J Bobby'),
2572 array('first_name' => 'Bob', 'last_name' => 'K Bobby', 'external_identifier' => 'bcdef'),
2574 foreach ($contacts as $type => $contact) {
2575 $contact['contact_type'] = 'Individual';
2576 $this->callAPISuccess('Contact', 'create', $contact);
2581 * Test get ref api - gets a list of references to an entity.
2583 public function testGetReferenceCounts() {
2584 $result = $this->callAPISuccess('Contact', 'create', array(
2585 'first_name' => 'Testily',
2586 'last_name' => 'McHaste',
2587 'contact_type' => 'Individual',
2588 'api.Address.replace' => array(
2589 'values' => array(),
2591 'api.Email.replace' => array(
2594 'email' => 'spam@dev.null',
2596 'location_type_id' => 1,
2600 'api.Phone.replace' => array(
2603 'phone' => '234-567-0001',
2605 'location_type_id' => 1,
2608 'phone' => '234-567-0002',
2610 'location_type_id' => 1,
2616 //$dao = new CRM_Contact_BAO_Contact();
2617 //$dao->id = $result['id'];
2618 //$this->assertTrue((bool) $dao->find(TRUE));
2620 //$refCounts = $dao->getReferenceCounts();
2621 //$this->assertTrue(is_array($refCounts));
2622 //$refCountsIdx = CRM_Utils_Array::index(array('name'), $refCounts);
2624 $refCounts = $this->callAPISuccess('Contact', 'getrefcount', array(
2625 'id' => $result['id'],
2627 $refCountsIdx = CRM_Utils_Array
::index(array('name'), $refCounts['values']);
2629 $this->assertEquals(1, $refCountsIdx['sql:civicrm_email:contact_id']['count']);
2630 $this->assertEquals('civicrm_email', $refCountsIdx['sql:civicrm_email:contact_id']['table']);
2631 $this->assertEquals(2, $refCountsIdx['sql:civicrm_phone:contact_id']['count']);
2632 $this->assertEquals('civicrm_phone', $refCountsIdx['sql:civicrm_phone:contact_id']['table']);
2633 $this->assertTrue(!isset($refCountsIdx['sql:civicrm_address:contact_id']));
2637 * Test the use of sql operators.
2639 public function testSQLOperatorsOnContactAPI() {
2640 $this->individualCreate();
2641 $this->organizationCreate();
2642 $this->householdCreate();
2643 $contacts = $this->callAPISuccess('contact', 'get', array('legal_name' => array('IS NOT NULL' => TRUE)));
2644 $this->assertEquals($contacts['count'], CRM_Core_DAO
::singleValueQuery('select count(*) FROM civicrm_contact WHERE legal_name IS NOT NULL'));
2645 $contacts = $this->callAPISuccess('contact', 'get', array('legal_name' => array('IS NULL' => TRUE)));
2646 $this->assertEquals($contacts['count'], CRM_Core_DAO
::singleValueQuery('select count(*) FROM civicrm_contact WHERE legal_name IS NULL'));
2650 * CRM-14743 - test api respects search operators.
2652 public function testGetModifiedDateByOperators() {
2653 $preExistingContactCount = CRM_Core_DAO
::singleValueQuery('select count(*) FROM civicrm_contact');
2654 $contact1 = $this->individualCreate();
2655 $sql = "UPDATE civicrm_contact SET created_date = '2012-01-01', modified_date = '2013-01-01' WHERE id = " . $contact1;
2656 CRM_Core_DAO
::executeQuery($sql);
2657 $contact2 = $this->individualCreate();
2658 $sql = "UPDATE civicrm_contact SET created_date = '2012-02-01', modified_date = '2013-02-01' WHERE id = " . $contact2;
2659 CRM_Core_DAO
::executeQuery($sql);
2660 $contact3 = $this->householdCreate();
2661 $sql = "UPDATE civicrm_contact SET created_date = '2012-03-01', modified_date = '2013-03-01' WHERE id = " . $contact3;
2662 CRM_Core_DAO
::executeQuery($sql);
2663 $contacts = $this->callAPISuccess('contact', 'get', array('modified_date' => array('<' => '2014-01-01')));
2664 $this->assertEquals($contacts['count'], 3);
2665 $contacts = $this->callAPISuccess('contact', 'get', array('modified_date' => array('>' => '2014-01-01')));
2666 $this->assertEquals($contacts['count'], $preExistingContactCount);
2670 * CRM-14743 - test api respects search operators.
2672 public function testGetCreatedDateByOperators() {
2673 $preExistingContactCount = CRM_Core_DAO
::singleValueQuery('select count(*) FROM civicrm_contact');
2674 $contact1 = $this->individualCreate();
2675 $sql = "UPDATE civicrm_contact SET created_date = '2012-01-01' WHERE id = " . $contact1;
2676 CRM_Core_DAO
::executeQuery($sql);
2677 $contact2 = $this->individualCreate();
2678 $sql = "UPDATE civicrm_contact SET created_date = '2012-02-01' WHERE id = " . $contact2;
2679 CRM_Core_DAO
::executeQuery($sql);
2680 $contact3 = $this->householdCreate();
2681 $sql = "UPDATE civicrm_contact SET created_date = '2012-03-01' WHERE id = " . $contact3;
2682 CRM_Core_DAO
::executeQuery($sql);
2683 $contacts = $this->callAPISuccess('contact', 'get', array('created_date' => array('<' => '2014-01-01')));
2684 $this->assertEquals($contacts['count'], 3);
2685 $contacts = $this->callAPISuccess('contact', 'get', array('created_date' => array('>' => '2014-01-01')));
2686 $this->assertEquals($contacts['count'], $preExistingContactCount);
2690 * CRM-14263 check that API is not affected by search profile related bug.
2692 public function testReturnCityProfile() {
2693 $contactID = $this->individualCreate();
2694 CRM_Core_Config
::singleton()->defaultSearchProfileID
= 1;
2695 $this->callAPISuccess('address', 'create', array(
2696 'contact_id' => $contactID,
2697 'city' => 'Cool City',
2698 'location_type_id' => 1,
2700 $result = $this->callAPISuccess('contact', 'get', array('city' => 'Cool City', 'return' => 'contact_type'));
2701 $this->assertEquals(1, $result['count']);
2705 * CRM-15443 - ensure getlist api does not return deleted contacts.
2707 public function testGetlistExcludeConditions() {
2708 $name = md5(time());
2709 $contact = $this->individualCreate(array('last_name' => $name));
2710 $this->individualCreate(array('last_name' => $name, 'is_deceased' => 1));
2711 $this->individualCreate(array('last_name' => $name, 'is_deleted' => 1));
2712 // We should get all but the deleted contact.
2713 $result = $this->callAPISuccess('contact', 'getlist', array('input' => $name));
2714 $this->assertEquals(2, $result['count']);
2715 // Force-exclude the deceased contact.
2716 $result = $this->callAPISuccess('contact', 'getlist', array(
2718 'params' => array('is_deceased' => 0),
2720 $this->assertEquals(1, $result['count']);
2721 $this->assertEquals($contact, $result['values'][0]['id']);
2725 * Test contact getactions.
2727 public function testGetActions() {
2728 $description = "Getting the available actions for an entity.";
2729 $result = $this->callAPIAndDocument($this->_entity
, 'getactions', array(), __FUNCTION__
, __FILE__
, $description);
2749 $deprecated = array(
2753 foreach ($expected as $action) {
2754 $this->assertTrue(in_array($action, $result['values']), "Expected action $action");
2756 foreach ($deprecated as $action) {
2757 $this->assertArrayKeyExists($action, $result['deprecated']);
2762 * Test the duplicate check function.
2764 public function testDuplicateCheck() {
2765 $this->callAPISuccess('Contact', 'create', array(
2766 'first_name' => 'Harry',
2767 'last_name' => 'Potter',
2768 'email' => 'harry@hogwarts.edu',
2769 'contact_type' => 'Individual',
2771 $result = $this->callAPISuccess('Contact', 'duplicatecheck', array(
2773 'first_name' => 'Harry',
2774 'last_name' => 'Potter',
2775 'email' => 'harry@hogwarts.edu',
2776 'contact_type' => 'Individual',
2780 $this->assertEquals(1, $result['count']);
2781 $result = $this->callAPISuccess('Contact', 'duplicatecheck', array(
2783 'first_name' => 'Harry',
2784 'last_name' => 'Potter',
2785 'email' => 'no5@privet.drive',
2786 'contact_type' => 'Individual',
2789 $this->assertEquals(0, $result['count']);
2792 public function testGetByContactType() {
2793 $individual = $this->callAPISuccess('Contact', 'create', array(
2794 'email' => 'individual@test.com',
2795 'contact_type' => 'Individual',
2797 $household = $this->callAPISuccess('Contact', 'create', array(
2798 'household_name' => 'household@test.com',
2799 'contact_type' => 'Household',
2801 $organization = $this->callAPISuccess('Contact', 'create', array(
2802 'organization_name' => 'organization@test.com',
2803 'contact_type' => 'Organization',
2805 // Test with id - getsingle will throw an exception if not found
2806 $this->callAPISuccess('Contact', 'getsingle', array(
2807 'id' => $individual['id'],
2808 'contact_type' => 'Individual',
2810 $this->callAPISuccess('Contact', 'getsingle', array(
2811 'id' => $individual['id'],
2812 'contact_type' => array('IN' => array('Individual')),
2815 $this->callAPISuccess('Contact', 'getsingle', array(
2816 'id' => $organization['id'],
2817 'contact_type' => array('IN' => array('Individual', 'Organization')),
2820 $result = $this->callAPISuccess('Contact', 'get', array(
2821 'contact_type' => array('IN' => array('Individual', 'Organization')),
2822 'options' => array('limit' => 0),
2825 $this->assertContains($organization['id'], array_keys($result['values']));
2826 $this->assertContains($individual['id'], array_keys($result['values']));
2827 $this->assertNotContains($household['id'], array_keys($result['values']));
2829 $result = $this->callAPISuccess('Contact', 'get', array(
2830 'contact_type' => 'Household',
2831 'options' => array('limit' => 0),
2834 $this->assertNotContains($organization['id'], array_keys($result['values']));
2835 $this->assertNotContains($individual['id'], array_keys($result['values']));
2836 $this->assertContains($household['id'], array_keys($result['values']));
2840 * Test merging 2 contacts.
2842 public function testMerge() {
2843 $otherContact = $this->callAPISuccess('contact', 'create', $this->_params
);
2844 $mainContact = $this->callAPISuccess('contact', 'create', $this->_params
);
2845 $this->callAPISuccess('contact', 'merge', array('main_id' => $mainContact['id'], 'other_id' => $otherContact['id']));
2846 $contacts = $this->callAPISuccess('contact', 'get', $this->_params
);
2847 $this->assertEquals($otherContact['id'], $contacts['id']);