4 * File for the TestContact class.
8 * @author Walt Haas <walt@dharmatech.org> (801) 534-1262
9 * @copyright Copyright CiviCRM LLC (C) 2009
10 * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html
11 * GNU Affero General Public License version 3
12 * @version $Id: ContactTest.php 31254 2010-12-15 10:09:29Z eileen $
15 * This file is part of CiviCRM
17 * CiviCRM is free software; you can redistribute it and/or
18 * modify it under the terms of the GNU Affero General Public License
19 * as published by the Free Software Foundation; either version 3 of
20 * the License, or (at your option) any later version.
22 * CiviCRM is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 * GNU Affero General Public License for more details.
27 * You should have received a copy of the GNU Affero General Public
28 * License along with this program. If not, see
29 * <http://www.gnu.org/licenses/>.
33 * Test APIv3 civicrm_contact* functions
35 * @package CiviCRM_APIv3
36 * @subpackage API_Contact
39 class api_v3_ContactTest
extends CiviUnitTestCase
{
40 public $DBResetRequired = FALSE;
41 protected $_apiversion;
45 protected $_contactID;
46 protected $_financialTypeId = 1;
49 * Test setup for every test.
51 * Connect to the database, truncate the tables that will be used
52 * and redirect stdin to a temporary file
54 public function setUp() {
55 // Connect to the database.
57 $this->_apiversion
= 3;
58 $this->_entity
= 'contact';
59 $this->_params
= array(
60 'first_name' => 'abc1',
61 'contact_type' => 'Individual',
62 'last_name' => 'xyz1',
67 * Restore the DB for the next test.
71 public function tearDown() {
72 $this->callAPISuccess('Setting', 'create', array('includeOrderByClause' => TRUE));
73 // truncate a few tables
74 $tablesToTruncate = array(
76 'civicrm_contribution',
79 'civicrm_relationship',
83 'civicrm_acl_contact_cache',
84 'civicrm_activity_contact',
88 $this->quickCleanup($tablesToTruncate, TRUE);
93 * Test civicrm_contact_create.
95 * Verify that attempt to create individual contact with only
96 * first and last names succeeds
98 public function testAddCreateIndividual() {
99 $oldCount = CRM_Core_DAO
::singleValueQuery('select count(*) from civicrm_contact');
101 'first_name' => 'abc1',
102 'contact_type' => 'Individual',
103 'last_name' => 'xyz1',
106 $contact = $this->callAPISuccess('contact', 'create', $params);
107 $this->assertTrue(is_numeric($contact['id']));
108 $this->assertTrue($contact['id'] > 0);
109 $newCount = CRM_Core_DAO
::singleValueQuery('select count(*) from civicrm_contact');
110 $this->assertEquals($oldCount +
1, $newCount);
112 $this->assertDBState('CRM_Contact_DAO_Contact',
119 * Test civicrm_contact_create.
121 * Verify that preferred language can be set.
123 public function testAddCreateIndividualWithPreferredLanguage() {
125 'first_name' => 'abc1',
126 'contact_type' => 'Individual',
127 'last_name' => 'xyz1',
128 'preferred_language' => 'es_ES',
131 $contact = $this->callAPISuccess('contact', 'create', $params);
132 $this->getAndCheck($params, $contact['id'], 'Contact');
136 * Test civicrm_contact_create with sub-types.
138 * Verify that sub-types are created successfully and not deleted by subsequent updates.
140 public function testIndividualSubType() {
142 'first_name' => 'test abc',
143 'contact_type' => 'Individual',
144 'last_name' => 'test xyz',
145 'contact_sub_type' => array('Student', 'Staff'),
147 $contact = $this->callAPISuccess('contact', 'create', $params);
148 $cid = $contact['id'];
152 'middle_name' => 'foo',
154 $this->callAPISuccess('contact', 'create', $params);
155 unset($params['middle_name']);
157 $contact = $this->callAPISuccess('contact', 'get', $params);
159 $this->assertEquals(array('Student', 'Staff'), $contact['values'][$cid]['contact_sub_type']);
163 * Verify that attempt to create contact with empty params fails.
165 public function testCreateEmptyContact() {
166 $this->callAPIFailure('contact', 'create', array());
170 * Verify that attempt to create contact with bad contact type fails.
172 public function testCreateBadTypeContact() {
174 'email' => 'man1@yahoo.com',
175 'contact_type' => 'Does not Exist',
177 $this->callAPIFailure('contact', 'create', $params, "'Does not Exist' is not a valid option for field contact_type");
181 * Verify that attempt to create individual contact without required fields fails.
183 public function testCreateBadRequiredFieldsIndividual() {
185 'middle_name' => 'This field is not required',
186 'contact_type' => 'Individual',
188 $this->callAPIFailure('contact', 'create', $params);
192 * Verify that attempt to create household contact without required fields fails.
194 public function testCreateBadRequiredFieldsHousehold() {
196 'middle_name' => 'This field is not required',
197 'contact_type' => 'Household',
199 $this->callAPIFailure('contact', 'create', $params);
203 * Test required field check.
205 * Verify that attempt to create organization contact without required fields fails.
207 public function testCreateBadRequiredFieldsOrganization() {
209 'middle_name' => 'This field is not required',
210 'contact_type' => 'Organization',
213 $this->callAPIFailure('contact', 'create', $params);
217 * Verify that attempt to create individual contact with only an email succeeds.
219 public function testCreateEmailIndividual() {
222 'email' => 'man3@yahoo.com',
223 'contact_type' => 'Individual',
224 'location_type_id' => 1,
227 $contact = $this->callAPISuccess('contact', 'create', $params);
229 $this->assertEquals(3, $contact['id']);
230 $email = $this->callAPISuccess('email', 'get', array('contact_id' => $contact['id']));
231 $this->assertEquals(1, $email['count']);
232 $this->assertEquals('man3@yahoo.com', $email['values'][$email['id']]['email']);
234 $this->callAPISuccess('contact', 'delete', $contact);
238 * Test creating individual by name.
240 * Verify create individual contact with only first and last names succeeds.
242 public function testCreateNameIndividual() {
244 'first_name' => 'abc1',
245 'contact_type' => 'Individual',
246 'last_name' => 'xyz1',
249 $this->callAPISuccess('contact', 'create', $params);
253 * Test creating individual by display_name.
255 * Display name & sort name should be set.
257 public function testCreateDisplayNameIndividual() {
259 'display_name' => 'abc1',
260 'contact_type' => 'Individual',
263 $contact = $this->callAPISuccess('contact', 'create', $params);
264 $params['sort_name'] = 'abc1';
265 $this->getAndCheck($params, $contact['id'], 'contact');
269 * Test old keys still work.
271 * Verify that attempt to create individual contact with
272 * first and last names and old key values works
274 public function testCreateNameIndividualOldKeys() {
276 'individual_prefix' => 'Dr.',
277 'first_name' => 'abc1',
278 'contact_type' => 'Individual',
279 'last_name' => 'xyz1',
280 'individual_suffix' => 'Jr.',
283 $contact = $this->callAPISuccess('contact', 'create', $params);
284 $result = $this->callAPISuccess('contact', 'getsingle', array('id' => $contact['id']));
286 $this->assertArrayKeyExists('prefix_id', $result);
287 $this->assertArrayKeyExists('suffix_id', $result);
288 $this->assertArrayKeyExists('gender_id', $result);
289 $this->assertEquals(4, $result['prefix_id']);
290 $this->assertEquals(1, $result['suffix_id']);
294 * Test preferred keys work.
296 * Verify that attempt to create individual contact with
297 * first and last names and old key values works
299 public function testCreateNameIndividualRecommendedKeys2() {
301 'prefix_id' => 'Dr.',
302 'first_name' => 'abc1',
303 'contact_type' => 'Individual',
304 'last_name' => 'xyz1',
305 'suffix_id' => 'Jr.',
306 'gender_id' => 'Male',
309 $contact = $this->callAPISuccess('contact', 'create', $params);
310 $result = $this->callAPISuccess('contact', 'getsingle', array('id' => $contact['id']));
312 $this->assertArrayKeyExists('prefix_id', $result);
313 $this->assertArrayKeyExists('suffix_id', $result);
314 $this->assertArrayKeyExists('gender_id', $result);
315 $this->assertEquals(4, $result['prefix_id']);
316 $this->assertEquals(1, $result['suffix_id']);
320 * Test household name is sufficient for create.
322 * Verify that attempt to create household contact with only
323 * household name succeeds
325 public function testCreateNameHousehold() {
327 'household_name' => 'The abc Household',
328 'contact_type' => 'Household',
330 $this->callAPISuccess('contact', 'create', $params);
334 * Test organization name is sufficient for create.
336 * Verify that attempt to create organization contact with only
337 * organization name succeeds.
339 public function testCreateNameOrganization() {
341 'organization_name' => 'The abc Organization',
342 'contact_type' => 'Organization',
344 $this->callAPISuccess('contact', 'create', $params);
348 * Verify that attempt to create organization contact without organization name fails.
350 public function testCreateNoNameOrganization() {
352 'first_name' => 'The abc Organization',
353 'contact_type' => 'Organization',
355 $this->callAPIFailure('contact', 'create', $params);
359 * Check with complete array + custom field.
361 * Note that the test is written on purpose without any
362 * variables specific to participant so it can be replicated into other entities
363 * and / or moved to the automated test suite
365 public function testCreateWithCustom() {
366 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__
, __FILE__
);
368 $params = $this->_params
;
369 $params['custom_' . $ids['custom_field_id']] = "custom string";
370 $description = "This demonstrates setting a custom field through the API.";
371 $result = $this->callAPIAndDocument($this->_entity
, 'create', $params, __FUNCTION__
, __FILE__
, $description);
373 $check = $this->callAPISuccess($this->_entity
, 'get', array(
374 'return.custom_' . $ids['custom_field_id'] => 1,
375 'id' => $result['id'],
377 $this->assertEquals("custom string", $check['values'][$check['id']]['custom_' . $ids['custom_field_id']]);
379 $this->customFieldDelete($ids['custom_field_id']);
380 $this->customGroupDelete($ids['custom_group_id']);
384 * CRM-12773 - expectation is that civicrm quietly ignores fields without values.
386 public function testCreateWithNULLCustomCRM12773() {
387 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__
, __FILE__
);
388 $params = $this->_params
;
389 $params['custom_' . $ids['custom_field_id']] = NULL;
390 $this->callAPISuccess('contact', 'create', $params);
391 $this->customFieldDelete($ids['custom_field_id']);
392 $this->customGroupDelete($ids['custom_group_id']);
396 * CRM-14232 test preferred language set to site default if not passed.
398 public function testCreatePreferredLanguageUnset() {
399 $this->callAPISuccess('Contact', 'create', array(
400 'first_name' => 'Snoop',
401 'last_name' => 'Dog',
402 'contact_type' => 'Individual')
404 $result = $this->callAPISuccessGetSingle('Contact', array('last_name' => 'Dog'));
405 $this->assertEquals('en_US', $result['preferred_language']);
409 * CRM-14232 test preferred language returns setting if not passed.
411 public function testCreatePreferredLanguageSet() {
412 $this->callAPISuccess('Setting', 'create', array('contact_default_language' => 'fr_FR'));
413 $this->callAPISuccess('Contact', 'create', array(
414 'first_name' => 'Snoop',
415 'last_name' => 'Dog',
416 'contact_type' => 'Individual',
418 $result = $this->callAPISuccessGetSingle('Contact', array('last_name' => 'Dog'));
419 $this->assertEquals('fr_FR', $result['preferred_language']);
423 * CRM-14232 test preferred language returns setting if not passed where setting is NULL.
425 public function testCreatePreferredLanguageNull() {
426 $this->callAPISuccess('Setting', 'create', array('contact_default_language' => 'null'));
427 $this->callAPISuccess('Contact', 'create', array(
428 'first_name' => 'Snoop',
429 'last_name' => 'Dog',
430 'contact_type' => 'Individual',
433 $result = $this->callAPISuccessGetSingle('Contact', array('last_name' => 'Dog'));
434 $this->assertEquals(NULL, $result['preferred_language']);
438 * CRM-14232 test preferred language returns setting if not passed where setting is NULL.
440 public function testCreatePreferredLanguagePassed() {
441 $this->callAPISuccess('Setting', 'create', array('contact_default_language' => 'null'));
442 $this->callAPISuccess('Contact', 'create', array(
443 'first_name' => 'Snoop',
444 'last_name' => 'Dog',
445 'contact_type' => 'Individual',
446 'preferred_language' => 'en_AU',
448 $result = $this->callAPISuccessGetSingle('Contact', array('last_name' => 'Dog'));
449 $this->assertEquals('en_AU', $result['preferred_language']);
453 * CRM-15792 - create/update datetime field for contact.
455 public function testCreateContactCustomFldDateTime() {
456 $customGroup = $this->customGroupCreate(array('extends' => 'Individual', 'title' => 'datetime_test_group'));
457 $dateTime = CRM_Utils_Date
::currentDBDate();
458 //check date custom field is saved along with time when time_format is set
460 'first_name' => 'abc3',
461 'last_name' => 'xyz3',
462 'contact_type' => 'Individual',
463 'email' => 'man3@yahoo.com',
464 'api.CustomField.create' => array(
465 'custom_group_id' => $customGroup['id'],
466 'name' => 'test_datetime',
467 'label' => 'Demo Date',
468 'html_type' => 'Select Date',
469 'data_type' => 'Date',
473 'is_searchable' => 0,
478 $result = $this->callAPIAndDocument('Contact', 'create', $params, __FUNCTION__
, __FILE__
);
479 $customFldId = $result['values'][$result['id']]['api.CustomField.create']['id'];
480 $this->assertNotNull($result['id']);
481 $this->assertNotNull($customFldId);
484 'id' => $result['id'],
485 "custom_{$customFldId}" => $dateTime,
486 'api.CustomValue.get' => 1,
489 $result = $this->callAPIAndDocument('Contact', 'create', $params, __FUNCTION__
, __FILE__
);
490 $this->assertNotNull($result['id']);
491 $customFldDate = date("YmdHis", strtotime($result['values'][$result['id']]['api.CustomValue.get']['values'][0]['latest']));
492 $this->assertNotNull($customFldDate);
493 $this->assertEquals($dateTime, $customFldDate);
494 $customValueId = $result['values'][$result['id']]['api.CustomValue.get']['values'][0]['id'];
495 $dateTime = date('Ymd');
496 //date custom field should not contain time part when time_format is null
498 'id' => $result['id'],
499 'api.CustomField.create' => array(
500 'id' => $customFldId,
501 'html_type' => 'Select Date',
502 'data_type' => 'Date',
505 'api.CustomValue.create' => array(
506 'id' => $customValueId,
507 'entity_id' => $result['id'],
508 "custom_{$customFldId}" => $dateTime,
510 'api.CustomValue.get' => 1,
512 $result = $this->callAPIAndDocument('Contact', 'create', $params, __FUNCTION__
, __FILE__
);
513 $this->assertNotNull($result['id']);
514 $customFldDate = date("Ymd", strtotime($result['values'][$result['id']]['api.CustomValue.get']['values'][0]['latest']));
515 $customFldTime = date("His", strtotime($result['values'][$result['id']]['api.CustomValue.get']['values'][0]['latest']));
516 $this->assertNotNull($customFldDate);
517 $this->assertEquals($dateTime, $customFldDate);
518 $this->assertEquals(000000, $customFldTime);
519 $this->callAPIAndDocument('Contact', 'create', $params, __FUNCTION__
, __FILE__
);
524 * Test creating a current employer through API.
526 public function testContactCreateCurrentEmployer() {
527 // Here we will just do the get for set-up purposes.
528 $count = $this->callAPISuccess('contact', 'getcount', array(
529 'organization_name' => 'new employer org',
530 'contact_type' => 'Organization',
532 $this->assertEquals(0, $count);
533 $employerResult = $this->callAPISuccess('contact', 'create', array_merge($this->_params
, array(
534 'current_employer' => 'new employer org',
537 // do it again as an update to check it doesn't cause an error
538 $employerResult = $this->callAPISuccess('contact', 'create', array_merge($this->_params
, array(
539 'current_employer' => 'new employer org',
540 'id' => $employerResult['id'],
544 $this->callAPISuccess('contact', 'getcount', array(
545 'organization_name' => 'new employer org',
546 'contact_type' => 'Organization',
550 $result = $this->callAPISuccess('contact', 'getsingle', array(
551 'id' => $employerResult['id'],
554 $this->assertEquals('new employer org', $result['current_employer']);
559 * Test creating a current employer through API.
561 * Check it will re-activate a de-activated employer
563 public function testContactCreateDuplicateCurrentEmployerEnables() {
564 // Set up - create employer relationship.
565 $employerResult = $this->callAPISuccess('contact', 'create', array_merge($this->_params
, array(
566 'current_employer' => 'new employer org',
569 $relationship = $this->callAPISuccess('relationship', 'get', array(
570 'contact_id_a' => $employerResult['id'],
573 //disable & check it is disabled
574 $this->callAPISuccess('relationship', 'create', array('id' => $relationship['id'], 'is_active' => 0));
575 $this->callAPISuccess('relationship', 'getvalue', array(
576 'id' => $relationship['id'],
577 'return' => 'is_active',
580 // Re-set the current employer - thus enabling the relationship.
581 $this->callAPISuccess('contact', 'create', array_merge($this->_params
, array(
582 'current_employer' => 'new employer org',
583 'id' => $employerResult['id'],
586 //check is_active is now 1
587 $relationship = $this->callAPISuccess('relationship', 'getsingle', array(
588 'return' => 'is_active',
590 $this->assertEquals(1, $relationship['is_active']);
594 * Check deceased contacts are not retrieved.
596 * Note at time of writing the default is to return default. This should possibly be changed & test added.
598 public function testGetDeceasedRetrieved() {
599 $this->callAPISuccess($this->_entity
, 'create', $this->_params
);
600 $c2 = $this->callAPISuccess($this->_entity
, 'create', array(
601 'first_name' => 'bb',
602 'last_name' => 'ccc',
603 'contact_type' => 'Individual',
606 $result = $this->callAPISuccess($this->_entity
, 'get', array('is_deceased' => 0));
607 $this->assertFalse(array_key_exists($c2['id'], $result['values']));
611 * Test that sort works - old syntax.
613 public function testGetSort() {
614 $c1 = $this->callAPISuccess($this->_entity
, 'create', $this->_params
);
615 $c2 = $this->callAPISuccess($this->_entity
, 'create', array(
616 'first_name' => 'bb',
617 'last_name' => 'ccc',
618 'contact_type' => 'Individual',
620 $result = $this->callAPISuccess($this->_entity
, 'get', array(
621 'sort' => 'first_name ASC',
622 'return.first_name' => 1,
625 'contact_type' => 'Individual',
628 $this->assertEquals('abc1', $result['values'][0]['first_name']);
629 $result = $this->callAPISuccess($this->_entity
, 'get', array(
630 'sort' => 'first_name DESC',
631 'return.first_name' => 1,
635 $this->assertEquals('bb', $result['values'][0]['first_name']);
637 $this->callAPISuccess($this->_entity
, 'delete', array('id' => $c1['id']));
638 $this->callAPISuccess($this->_entity
, 'delete', array('id' => $c2['id']));
642 * Test that we can retrieve contacts using array syntax.
644 * I.e 'id' => array('IN' => array('3,4')).
646 public function testGetINIDArray() {
647 $c1 = $this->callAPISuccess($this->_entity
, 'create', $this->_params
);
648 $c2 = $this->callAPISuccess($this->_entity
, 'create', array(
649 'first_name' => 'bb',
650 'last_name' => 'ccc',
651 'contact_type' => 'Individual',
653 $c3 = $this->callAPISuccess($this->_entity
, 'create', array(
654 'first_name' => 'hh',
656 'contact_type' => 'Individual',
658 $result = $this->callAPISuccess($this->_entity
, 'get', array('id' => array('IN' => array($c1['id'], $c3['id']))));
659 $this->assertEquals(2, $result['count']);
660 $this->assertEquals(array($c1['id'], $c3['id']), array_keys($result['values']));
661 $this->callAPISuccess($this->_entity
, 'delete', array('id' => $c1['id']));
662 $this->callAPISuccess($this->_entity
, 'delete', array('id' => $c2['id']));
663 $this->callAPISuccess($this->_entity
, 'delete', array('id' => $c3['id']));
667 * Test variants on deleted behaviour.
669 public function testGetDeleted() {
670 $params = $this->_params
;
671 $contact1 = $this->callAPISuccess('contact', 'create', $params);
672 $params['is_deleted'] = 1;
673 $params['last_name'] = 'bcd';
674 $contact2 = $this->callAPISuccess('contact', 'create', $params);
675 $countActive = $this->callAPISuccess('contact', 'getcount', array(
676 'showAll' => 'active',
677 'contact_type' => 'Individual',
679 $countAll = $this->callAPISuccess('contact', 'getcount', array('showAll' => 'all', 'contact_type' => 'Individual'));
680 $countTrash = $this->callAPISuccess('contact', 'getcount', array('showAll' => 'trash', 'contact_type' => 'Individual'));
681 $countDefault = $this->callAPISuccess('contact', 'getcount', array('contact_type' => 'Individual'));
682 $countDeleted = $this->callAPISuccess('contact', 'getcount', array(
683 'contact_type' => 'Individual',
684 'contact_is_deleted' => 1,
686 $countNotDeleted = $this->callAPISuccess('contact', 'getcount', array(
687 'contact_is_deleted' => 0,
688 'contact_type' => 'Individual',
690 $this->callAPISuccess('contact', 'delete', array('id' => $contact1['id']));
691 $this->callAPISuccess('contact', 'delete', array('id' => $contact2['id']));
692 $this->assertEquals(1, $countNotDeleted, 'contact_is_deleted => 0 is respected');
693 $this->assertEquals(1, $countActive);
694 $this->assertEquals(1, $countTrash);
695 $this->assertEquals(2, $countAll);
696 $this->assertEquals(1, $countDeleted);
697 $this->assertEquals(1, $countDefault, 'Only active by default in line');
701 * Test that sort works - new syntax.
703 public function testGetSortNewSyntax() {
704 $c1 = $this->callAPISuccess($this->_entity
, 'create', $this->_params
);
705 $c2 = $this->callAPISuccess($this->_entity
, 'create', array(
706 'first_name' => 'bb',
707 'last_name' => 'ccc',
708 'contact_type' => 'Individual',
710 $result = $this->callAPISuccess($this->_entity
, 'getvalue', array(
711 'return' => 'first_name',
712 'contact_type' => 'Individual',
715 'sort' => 'first_name',
718 $this->assertEquals('abc1', $result);
720 $result = $this->callAPISuccess($this->_entity
, 'getvalue', array(
721 'return' => 'first_name',
722 'contact_type' => 'Individual',
725 'sort' => 'first_name DESC',
728 $this->assertEquals('bb', $result);
730 $this->callAPISuccess($this->_entity
, 'delete', array('id' => $c1['id']));
731 $this->callAPISuccess($this->_entity
, 'delete', array('id' => $c2['id']));
735 * Test sort and limit for chained relationship get.
737 * https://issues.civicrm.org/jira/browse/CRM-15983
739 public function testSortLimitChainedRelationshipGetCRM15983() {
741 $create_result_1 = $this->callAPISuccess('contact', 'create', array(
742 'first_name' => 'Jules',
743 'last_name' => 'Smos',
744 'contact_type' => 'Individual',
747 // Create another contact with two relationships.
748 $create_params = array(
749 'first_name' => 'Jos',
750 'last_name' => 'Smos',
751 'contact_type' => 'Individual',
752 'api.relationship.create' => array(
754 'contact_id_a' => '$value.id',
755 'contact_id_b' => $create_result_1['id'],
757 'relationship_type_id' => 2,
758 'start_date' => '2005-01-12',
759 'end_date' => '2006-01-11',
760 'description' => 'old',
763 'contact_id_a' => '$value.id',
764 'contact_id_b' => $create_result_1['id'],
765 // spouse of (was married twice :))
766 'relationship_type_id' => 2,
767 'start_date' => '2006-07-01',
768 'end_date' => '2010-07-01',
769 'description' => 'new',
773 $create_result = $this->callAPISuccess('contact', 'create', $create_params);
775 // Try to retrieve the contact and the most recent relationship.
778 'id' => $create_result['id'],
779 'api.relationship.get' => array(
780 'contact_id_a' => '$value.id',
783 'sort' => 'start_date DESC',
786 $get_result = $this->callAPISuccess('contact', 'getsingle', $get_params);
789 $this->callAPISuccess('contact', 'delete', array(
790 'id' => $create_result['id'],
794 $this->assertEquals(1, $get_result['api.relationship.get']['count']);
795 $this->assertEquals('new', $get_result['api.relationship.get']['values'][0]['description']);
799 * Test apostrophe works in get & create.
801 public function testGetApostropheCRM10857() {
802 $params = array_merge($this->_params
, array('last_name' => "O'Connor"));
803 $this->callAPISuccess($this->_entity
, 'create', $params);
804 $result = $this->callAPISuccess($this->_entity
, 'getsingle', array(
805 'last_name' => "O'Connor",
808 $this->assertEquals("O'Connor", $result['last_name'], 'in line' . __LINE__
);
812 * Check with complete array + custom field.
814 * Note that the test is written on purpose without any
815 * variables specific to participant so it can be replicated into other entities
816 * and / or moved to the automated test suite
818 public function testGetWithCustom() {
819 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__
, __FILE__
);
821 $params = $this->_params
;
822 $params['custom_' . $ids['custom_field_id']] = "custom string";
823 $description = "This demonstrates setting a custom field through the API.";
824 $subfile = "CustomFieldGet";
825 $result = $this->callAPISuccess($this->_entity
, 'create', $params);
827 $check = $this->callAPIAndDocument($this->_entity
, 'get', array(
828 'return.custom_' . $ids['custom_field_id'] => 1,
829 'id' => $result['id'],
830 ), __FUNCTION__
, __FILE__
, $description, $subfile);
832 $this->assertEquals("custom string", $check['values'][$check['id']]['custom_' . $ids['custom_field_id']]);
833 $fields = ($this->callAPISuccess('contact', 'getfields', $params));
834 $this->assertTrue(is_array($fields['values']['custom_' . $ids['custom_field_id']]));
835 $this->customFieldDelete($ids['custom_field_id']);
836 $this->customGroupDelete($ids['custom_group_id']);
840 * Check with complete array + custom field.
842 * Note that the test is written on purpose without any
843 * variables specific to participant so it can be replicated into other entities
844 * and / or moved to the automated test suite
846 public function testGetWithCustomReturnSyntax() {
847 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__
, __FILE__
);
849 $params = $this->_params
;
850 $params['custom_' . $ids['custom_field_id']] = "custom string";
851 $description = "This demonstrates setting a custom field through the API.";
852 $subfile = "CustomFieldGetReturnSyntaxVariation";
853 $result = $this->callAPISuccess($this->_entity
, 'create', $params);
854 $params = array('return' => 'custom_' . $ids['custom_field_id'], 'id' => $result['id']);
855 $check = $this->callAPIAndDocument($this->_entity
, 'get', $params, __FUNCTION__
, __FILE__
, $description, $subfile);
857 $this->assertEquals("custom string", $check['values'][$check['id']]['custom_' . $ids['custom_field_id']]);
858 $this->customFieldDelete($ids['custom_field_id']);
859 $this->customGroupDelete($ids['custom_group_id']);
863 * Check that address name, ID is returned if required.
865 public function testGetReturnAddress() {
866 $contactID = $this->individualCreate();
867 $result = $this->callAPISuccess('address', 'create', array(
868 'contact_id' => $contactID,
869 'address_name' => 'My house',
870 'location_type_id' => 'Home',
871 'street_address' => '1 my road',
873 $addressID = $result['id'];
875 $result = $this->callAPISuccessGetSingle('contact', array(
876 'return' => 'address_name, street_address, address_id',
879 $this->assertEquals($addressID, $result['address_id']);
880 $this->assertEquals('1 my road', $result['street_address']);
881 $this->assertEquals('My house', $result['address_name']);
886 * Test group filter syntaxes.
888 public function testGetGroupIDFromContact() {
889 $groupId = $this->groupCreate();
890 $description = "Get all from group and display contacts.";
891 $subFile = "GroupFilterUsingContactAPI";
893 'email' => 'man2@yahoo.com',
894 'contact_type' => 'Individual',
895 'location_type_id' => 1,
896 'api.group_contact.create' => array('group_id' => $groupId),
899 $this->callAPISuccess('contact', 'create', $params);
900 // testing as integer
902 'filter.group_id' => $groupId,
903 'contact_type' => 'Individual',
905 $result = $this->callAPIAndDocument('contact', 'get', $params, __FUNCTION__
, __FILE__
, $description, $subFile);
906 $this->assertEquals(1, $result['count']);
907 // group 26 doesn't exist, but we can still search contacts in it.
909 'filter.group_id' => 26,
910 'contact_type' => 'Individual',
912 $this->callAPISuccess('contact', 'get', $params);
915 'filter.group_id' => "$groupId, 26",
916 'contact_type' => 'Individual',
918 $result = $this->callAPIAndDocument('contact', 'get', $params, __FUNCTION__
, __FILE__
, $description, $subFile);
919 $this->assertEquals(1, $result['count']);
921 'filter.group_id' => "26,27",
922 'contact_type' => 'Individual',
924 $this->callAPISuccess('contact', 'get', $params);
928 'filter.group_id' => array($groupId, 26),
929 'contact_type' => 'Individual',
931 $result = $this->callAPIAndDocument('contact', 'get', $params, __FUNCTION__
, __FILE__
, $description, $subFile);
932 $this->assertEquals(1, $result['count']);
934 //test in conjunction with other criteria
936 'filter.group_id' => array($groupId, 26),
937 'contact_type' => 'Organization',
939 $this->callAPISuccess('contact', 'get', $params);
941 'filter.group_id' => array(26, 27),
942 'contact_type' => 'Individual',
944 $result = $this->callAPISuccess('contact', 'get', $params);
945 $this->assertEquals(0, $result['count']);
949 * Verify that attempt to create individual contact with two chained websites succeeds.
951 public function testCreateIndividualWithContributionDottedSyntax() {
952 $description = "This demonstrates the syntax to create 2 chained entities.";
953 $subFile = "ChainTwoWebsites";
955 'first_name' => 'abc3',
956 'last_name' => 'xyz3',
957 'contact_type' => 'Individual',
958 'email' => 'man3@yahoo.com',
959 'api.contribution.create' => array(
960 'receive_date' => '2010-01-01',
961 'total_amount' => 100.00,
962 'financial_type_id' => $this->_financialTypeId
,
963 'payment_instrument_id' => 1,
964 'non_deductible_amount' => 10.00,
965 'fee_amount' => 50.00,
966 'net_amount' => 90.00,
968 'invoice_id' => 67990,
970 'contribution_status_id' => 1,
972 'api.website.create' => array(
973 'url' => "http://civicrm.org",
975 'api.website.create.2' => array(
976 'url' => "http://chained.org",
980 $result = $this->callAPIAndDocument('Contact', 'create', $params, __FUNCTION__
, __FILE__
, $description, $subFile);
982 // checking child function result not covered in callAPIAndDocument
983 $this->assertAPISuccess($result['values'][$result['id']]['api.website.create']);
984 $this->assertEquals("http://chained.org", $result['values'][$result['id']]['api.website.create.2']['values'][0]['url']);
985 $this->assertEquals("http://civicrm.org", $result['values'][$result['id']]['api.website.create']['values'][0]['url']);
987 // delete the contact
988 $this->callAPISuccess('contact', 'delete', $result);
992 * Verify that attempt to create individual contact with chained contribution and website succeeds.
994 public function testCreateIndividualWithContributionChainedArrays() {
996 'first_name' => 'abc3',
997 'last_name' => 'xyz3',
998 'contact_type' => 'Individual',
999 'email' => 'man3@yahoo.com',
1000 'api.contribution.create' => array(
1001 'receive_date' => '2010-01-01',
1002 'total_amount' => 100.00,
1003 'financial_type_id' => $this->_financialTypeId
,
1004 'payment_instrument_id' => 1,
1005 'non_deductible_amount' => 10.00,
1006 'fee_amount' => 50.00,
1007 'net_amount' => 90.00,
1009 'invoice_id' => 67890,
1011 'contribution_status_id' => 1,
1013 'api.website.create' => array(
1015 'url' => "http://civicrm.org",
1018 'url' => "http://chained.org",
1019 'website_type_id' => 2,
1024 $description = "Demonstrates creating two websites as an array.";
1025 $subfile = "ChainTwoWebsitesSyntax2";
1026 $result = $this->callAPIAndDocument('Contact', 'create', $params, __FUNCTION__
, __FILE__
, $description, $subfile);
1028 // the callAndDocument doesn't check the chained call
1029 $this->assertEquals(0, $result['values'][$result['id']]['api.website.create'][0]['is_error']);
1030 $this->assertEquals("http://chained.org", $result['values'][$result['id']]['api.website.create'][1]['values'][0]['url']);
1031 $this->assertEquals("http://civicrm.org", $result['values'][$result['id']]['api.website.create'][0]['values'][0]['url']);
1033 $this->callAPISuccess('contact', 'delete', $result);
1037 * Test for direction when chaining relationships.
1039 * https://issues.civicrm.org/jira/browse/CRM-16084
1041 public function testDirectionChainingRelationshipsCRM16084() {
1042 // Some contact, called Jules.
1043 $create_result_1 = $this->callAPISuccess('contact', 'create', array(
1044 'first_name' => 'Jules',
1045 'last_name' => 'Smos',
1046 'contact_type' => 'Individual',
1049 // Another contact: Jos, child of Jules.
1050 $create_params = array(
1051 'first_name' => 'Jos',
1052 'last_name' => 'Smos',
1053 'contact_type' => 'Individual',
1054 'api.relationship.create' => array(
1056 'contact_id_a' => '$value.id',
1057 'contact_id_b' => $create_result_1['id'],
1059 'relationship_type_id' => 1,
1063 $create_result_2 = $this->callAPISuccess('contact', 'create', $create_params);
1065 // Mia is the child of Jos.
1066 $create_params = array(
1067 'first_name' => 'Mia',
1068 'last_name' => 'Smos',
1069 'contact_type' => 'Individual',
1070 'api.relationship.create' => array(
1072 'contact_id_a' => '$value.id',
1073 'contact_id_b' => $create_result_2['id'],
1075 'relationship_type_id' => 1,
1079 $create_result_3 = $this->callAPISuccess('contact', 'create', $create_params);
1081 // Get Jos and his children.
1082 $get_params = array(
1084 'id' => $create_result_2['id'],
1085 'api.relationship.get' => array(
1086 'contact_id_b' => '$value.id',
1087 'relationship_type_id' => 1,
1090 $get_result = $this->callAPISuccess('contact', 'getsingle', $get_params);
1093 $this->callAPISuccess('contact', 'delete', array(
1094 'id' => $create_result_1['id'],
1096 $this->callAPISuccess('contact', 'delete', array(
1097 'id' => $create_result_2['id'],
1099 $this->callAPISuccess('contact', 'delete', array(
1100 'id' => $create_result_2['id'],
1104 $this->assertEquals(1, $get_result['api.relationship.get']['count']);
1105 $this->assertEquals($create_result_3['id'], $get_result['api.relationship.get']['values'][0]['contact_id_a']);
1109 * Verify that attempt to create individual contact with first, and last names and email succeeds.
1111 public function testCreateIndividualWithNameEmail() {
1113 'first_name' => 'abc3',
1114 'last_name' => 'xyz3',
1115 'contact_type' => 'Individual',
1116 'email' => 'man3@yahoo.com',
1119 $contact = $this->callAPISuccess('contact', 'create', $params);
1121 $this->callAPISuccess('contact', 'delete', $contact);
1125 * Verify that attempt to create individual contact with no data fails.
1127 public function testCreateIndividualWithOutNameEmail() {
1129 'contact_type' => 'Individual',
1131 $this->callAPIFailure('contact', 'create', $params);
1135 * Test create individual contact with first &last names, email and location type succeeds.
1137 public function testCreateIndividualWithNameEmailLocationType() {
1139 'first_name' => 'abc4',
1140 'last_name' => 'xyz4',
1141 'email' => 'man4@yahoo.com',
1142 'contact_type' => 'Individual',
1143 'location_type_id' => 1,
1145 $result = $this->callAPISuccess('contact', 'create', $params);
1147 $this->callAPISuccess('contact', 'delete', array('id' => $result['id']));
1151 * Verify that when changing employers the old employer relationship becomes inactive.
1153 public function testCreateIndividualWithEmployer() {
1154 $employer = $this->organizationCreate();
1155 $employer2 = $this->organizationCreate();
1158 'email' => 'man4@yahoo.com',
1159 'contact_type' => 'Individual',
1160 'employer_id' => $employer,
1163 $result = $this->callAPISuccess('contact', 'create', $params);
1164 $relationships = $this->callAPISuccess('relationship', 'get', array(
1165 'contact_id_a' => $result['id'],
1169 $this->assertEquals($employer, $relationships['values'][0]['contact_id_b']);
1171 // Add more random relationships to make the test more realistic
1172 foreach (array('Employee of', 'Volunteer for') as $relationshipType) {
1173 $relTypeId = CRM_Core_DAO
::getFieldValue('CRM_Contact_DAO_RelationshipType', $relationshipType, 'id', 'name_a_b');
1174 $this->callAPISuccess('relationship', 'create', array(
1175 'contact_id_a' => $result['id'],
1176 'contact_id_b' => $this->organizationCreate(),
1178 'relationship_type_id' => $relTypeId,
1182 // Add second employer
1183 $params['employer_id'] = $employer2;
1184 $params['id'] = $result['id'];
1185 $result = $this->callAPISuccess('contact', 'create', $params);
1187 $relationships = $this->callAPISuccess('relationship', 'get', array(
1188 'contact_id_a' => $result['id'],
1193 $this->assertEquals($employer, $relationships['values'][0]['contact_id_b']);
1197 * Verify that attempt to create household contact with details succeeds.
1199 public function testCreateHouseholdDetails() {
1201 'household_name' => 'abc8\'s House',
1202 'nick_name' => 'x House',
1203 'email' => 'man8@yahoo.com',
1204 'contact_type' => 'Household',
1207 $contact = $this->callAPISuccess('contact', 'create', $params);
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);
1546 'email' => 'man2@yahoo.com',
1548 $result = $this->callAPIAndDocument('contact', 'get', $params, __FUNCTION__
, __FILE__
);
1549 $this->assertEquals('man2@yahoo.com', $result['values'][$result['id']]['email']);
1551 $this->callAPISuccess('contact', 'delete', $contact);
1555 * Test birth date parameters.
1557 * These include value, array & birth_date_high, birth_date_low
1560 public function testContactGetBirthDate() {
1561 $contact1 = $this->callAPISuccess('contact', 'create', array_merge($this->_params
, array('birth_date' => 'first day of next month - 2 years')));
1562 $contact2 = $this->callAPISuccess('contact', 'create', array_merge($this->_params
, array('birth_date' => 'first day of next month - 5 years')));
1563 $contact3 = $this->callAPISuccess('contact', 'create', array_merge($this->_params
, array('birth_date' => 'first day of next month -20 years')));
1565 $result = $this->callAPISuccess('contact', 'get', array());
1566 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -2 years')), $result['values'][$contact1['id']]['birth_date']);
1567 $result = $this->callAPISuccess('contact', 'get', array('birth_date' => 'first day of next month -5 years'));
1568 $this->assertEquals(1, $result['count']);
1569 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -5 years')), $result['values'][$contact2['id']]['birth_date']);
1570 $result = $this->callAPISuccess('contact', 'get', array('birth_date_high' => date('Y-m-d', strtotime('-6 years'))));
1571 $this->assertEquals(1, $result['count']);
1572 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -20 years')), $result['values'][$contact3['id']]['birth_date']);
1573 $result = $this->callAPISuccess('contact', 'get', array(
1574 'birth_date_low' => date('Y-m-d', strtotime('-6 years')),
1575 'birth_date_high' => date('Y-m-d', strtotime('- 3 years')),
1577 $this->assertEquals(1, $result['count']);
1578 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -5 years')), $result['values'][$contact2['id']]['birth_date']);
1579 $result = $this->callAPISuccess('contact', 'get', array(
1580 'birth_date_low' => '-6 years',
1581 'birth_date_high' => '- 3 years',
1583 $this->assertEquals(1, $result['count']);
1584 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -5 years')), $result['values'][$contact2['id']]['birth_date']);
1588 * Test Address parameters
1590 * This include state_province, state_province_name, country
1592 public function testContactGetWithAddressFields() {
1593 $individuals = array(
1595 'first_name' => 'abc1',
1596 'contact_type' => 'Individual',
1597 'last_name' => 'xyz1',
1598 'api.address.create' => array(
1599 'country' => 'United States',
1600 'state_province_id' => 'Michigan',
1601 'location_type_id' => 1,
1605 'first_name' => 'abc2',
1606 'contact_type' => 'Individual',
1607 'last_name' => 'xyz2',
1608 'api.address.create' => array(
1609 'country' => 'United States',
1610 'state_province_id' => 'Alabama',
1611 'location_type_id' => 1,
1615 foreach ($individuals as $params) {
1616 $contact = $this->callAPISuccess('contact', 'create', $params);
1619 // Check whether Contact get API return successfully with below Address params.
1620 $fieldsToTest = array(
1621 'state_province_name' => 'Michigan',
1622 'state_province' => 'Michigan',
1623 'country' => 'United States',
1624 'state_province_name' => array('IN' => array('Michigan', 'Alabama')),
1625 'state_province' => array('IN' => array('Michigan', 'Alabama')),
1627 foreach ($fieldsToTest as $field => $value) {
1629 'id' => $contact['id'],
1632 $result = $this->callAPISuccess('Contact', 'get', $getParams);
1633 $this->assertEquals(1, $result['count']);
1638 * Test Deceased date parameters.
1640 * These include value, array & Deceased_date_high, Deceased date_low
1643 public function testContactGetDeceasedDate() {
1644 $contact1 = $this->callAPISuccess('contact', 'create', array_merge($this->_params
, array('deceased_date' => 'first day of next month - 2 years')));
1645 $contact2 = $this->callAPISuccess('contact', 'create', array_merge($this->_params
, array('deceased_date' => 'first day of next month - 5 years')));
1646 $contact3 = $this->callAPISuccess('contact', 'create', array_merge($this->_params
, array('deceased_date' => 'first day of next month -20 years')));
1648 $result = $this->callAPISuccess('contact', 'get', array());
1649 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -2 years')), $result['values'][$contact1['id']]['deceased_date']);
1650 $result = $this->callAPISuccess('contact', 'get', array('deceased_date' => 'first day of next month -5 years'));
1651 $this->assertEquals(1, $result['count']);
1652 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -5 years')), $result['values'][$contact2['id']]['deceased_date']);
1653 $result = $this->callAPISuccess('contact', 'get', array('deceased_date_high' => date('Y-m-d', strtotime('-6 years'))));
1654 $this->assertEquals(1, $result['count']);
1655 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -20 years')), $result['values'][$contact3['id']]['deceased_date']);
1656 $result = $this->callAPISuccess('contact', 'get', array(
1657 'deceased_date_low' => '-6 years',
1658 'deceased_date_high' => date('Y-m-d', strtotime('- 3 years')),
1660 $this->assertEquals(1, $result['count']);
1661 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -5 years')), $result['values'][$contact2['id']]['deceased_date']);
1665 * Test for Contact.get id=@user:username.
1667 public function testContactGetByUsername() {
1668 // Setup - create contact with a uf-match.
1669 $cid = $this->individualCreate(array(
1670 'contact_type' => 'Individual',
1671 'first_name' => 'testGetByUsername',
1672 'last_name' => 'testGetByUsername',
1675 $ufMatchParams = array(
1676 'domain_id' => CRM_Core_Config
::domainID(),
1678 'uf_name' => 'the-email-matching-key-is-not-really-the-username',
1679 'contact_id' => $cid,
1681 $ufMatch = CRM_Core_BAO_UFMatch
::create($ufMatchParams);
1682 $this->assertTrue(is_numeric($ufMatch->id
));
1684 // setup - mock the calls to CRM_Utils_System_*::getUfId
1685 $userSystem = $this->getMock('CRM_Utils_System_UnitTests', array('getUfId'));
1686 $userSystem->expects($this->once())
1688 ->with($this->equalTo('exampleUser'))
1689 ->will($this->returnValue(99));
1690 CRM_Core_Config
::singleton()->userSystem
= $userSystem;
1693 $result = $this->callAPISuccess('Contact', 'get', array(
1694 'id' => '@user:exampleUser',
1696 $this->assertEquals('testGetByUsername', $result['values'][$cid]['first_name']);
1700 * Test to check return works OK.
1702 public function testContactGetReturnValues() {
1703 $extraParams = array(
1704 'nick_name' => 'Bob',
1706 'email' => 'e@mail.com',
1708 $contactID = $this->individualCreate($extraParams);
1709 //actually it turns out the above doesn't create a phone
1710 $this->callAPISuccess('phone', 'create', array('contact_id' => $contactID, 'phone' => '456'));
1711 $result = $this->callAPISuccess('contact', 'getsingle', array('id' => $contactID));
1712 foreach ($extraParams as $key => $value) {
1713 $this->assertEquals($result[$key], $value);
1715 //now we check they are still returned with 'return' key
1716 $result = $this->callAPISuccess('contact', 'getsingle', array(
1718 'return' => array_keys($extraParams),
1720 foreach ($extraParams as $key => $value) {
1721 $this->assertEquals($result[$key], $value);
1726 * Test creating multiple phones using chaining.
1728 * @throws \Exception
1730 public function testCRM13252MultipleChainedPhones() {
1731 $contactID = $this->householdCreate();
1732 $this->callAPISuccessGetCount('phone', array('contact_id' => $contactID), 0);
1734 'contact_id' => $contactID,
1735 'household_name' => 'Household 1',
1736 'contact_type' => 'Household',
1737 'api.phone.create' => array(
1739 'phone' => '111-111-1111',
1740 'location_type_id' => 1,
1741 'phone_type_id' => 1,
1744 'phone' => '222-222-2222',
1745 'location_type_id' => 1,
1746 'phone_type_id' => 2,
1750 $this->callAPISuccess('contact', 'create', $params);
1751 $this->callAPISuccessGetCount('phone', array('contact_id' => $contactID), 2);
1756 * Test for Contact.get id=@user:username (with an invalid username).
1758 public function testContactGetByUnknownUsername() {
1759 // setup - mock the calls to CRM_Utils_System_*::getUfId
1760 $userSystem = $this->getMock('CRM_Utils_System_UnitTests', array('getUfId'));
1761 $userSystem->expects($this->once())
1763 ->with($this->equalTo('exampleUser'))
1764 ->will($this->returnValue(NULL));
1765 CRM_Core_Config
::singleton()->userSystem
= $userSystem;
1768 $result = $this->callAPIFailure('Contact', 'get', array(
1769 'id' => '@user:exampleUser',
1771 $this->assertRegExp('/cannot be resolved to a contact ID/', $result['error_message']);
1775 * Verify attempt to create individual with chained arrays and sequential.
1777 public function testGetIndividualWithChainedArraysAndSequential() {
1778 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__
, __FILE__
);
1779 $params['custom_' . $ids['custom_field_id']] = "custom string";
1781 $moreIDs = $this->CustomGroupMultipleCreateWithFields();
1784 'first_name' => 'abc3',
1785 'last_name' => 'xyz3',
1786 'contact_type' => 'Individual',
1787 'email' => 'man3@yahoo.com',
1788 'api.website.create' => array(
1790 'url' => "http://civicrm.org",
1793 'url' => "https://civicrm.org",
1798 $result = $this->callAPISuccess('Contact', 'create', $params);
1800 // delete the contact and custom groups
1801 $this->callAPISuccess('contact', 'delete', array('id' => $result['id']));
1802 $this->customGroupDelete($ids['custom_group_id']);
1803 $this->customGroupDelete($moreIDs['custom_group_id']);
1805 $this->assertEquals($result['id'], $result['values'][0]['id']);
1806 $this->assertArrayKeyExists('api.website.create', $result['values'][0]);
1810 * Verify attempt to create individual with chained arrays.
1812 public function testGetIndividualWithChainedArrays() {
1813 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__
, __FILE__
);
1814 $params['custom_' . $ids['custom_field_id']] = "custom string";
1816 $moreIDs = $this->CustomGroupMultipleCreateWithFields();
1817 $description = "This demonstrates the usage of chained api functions.\nIn this case no notes or custom fields have been created.";
1818 $subfile = "APIChainedArray";
1820 'first_name' => 'abc3',
1821 'last_name' => 'xyz3',
1822 'contact_type' => 'Individual',
1823 'email' => 'man3@yahoo.com',
1824 'api.contribution.create' => array(
1825 'receive_date' => '2010-01-01',
1826 'total_amount' => 100.00,
1827 'financial_type_id' => 1,
1828 'payment_instrument_id' => 1,
1829 'non_deductible_amount' => 10.00,
1830 'fee_amount' => 50.00,
1831 'net_amount' => 90.00,
1833 'invoice_id' => 67890,
1835 'contribution_status_id' => 1,
1837 'api.contribution.create.1' => array(
1838 'receive_date' => '2011-01-01',
1839 'total_amount' => 120.00,
1840 'financial_type_id' => $this->_financialTypeId
= 1,
1841 'payment_instrument_id' => 1,
1842 'non_deductible_amount' => 10.00,
1843 'fee_amount' => 50.00,
1844 'net_amount' => 90.00,
1846 'invoice_id' => 67830,
1848 'contribution_status_id' => 1,
1850 'api.website.create' => array(
1852 'url' => "http://civicrm.org",
1857 $result = $this->callAPISuccess('Contact', 'create', $params);
1859 'id' => $result['id'],
1860 'api.website.get' => array(),
1861 'api.Contribution.get' => array(
1862 'total_amount' => '120.00',
1864 'api.CustomValue.get' => 1,
1865 'api.Note.get' => 1,
1867 $result = $this->callAPIAndDocument('Contact', 'Get', $params, __FUNCTION__
, __FILE__
, $description, $subfile);
1868 // delete the contact
1869 $this->callAPISuccess('contact', 'delete', $result);
1870 $this->customGroupDelete($ids['custom_group_id']);
1871 $this->customGroupDelete($moreIDs['custom_group_id']);
1872 $this->assertEquals(0, $result['values'][$result['id']]['api.website.get']['is_error']);
1873 $this->assertEquals("http://civicrm.org", $result['values'][$result['id']]['api.website.get']['values'][0]['url']);
1877 * Verify attempt to create individual with chained arrays and sequential.
1879 * See https://issues.civicrm.org/jira/browse/CRM-15815
1881 public function testCreateIndividualWithChainedArrayAndSequential() {
1884 'first_name' => 'abc5',
1885 'last_name' => 'xyz5',
1886 'contact_type' => 'Individual',
1887 'email' => 'woman5@yahoo.com',
1888 'api.phone.create' => array(
1889 array('phone' => '03-231 07 95'),
1890 array('phone' => '03-232 51 62'),
1892 'api.website.create' => array(
1893 'url' => 'http://civicrm.org',
1896 $result = $this->callAPISuccess('Contact', 'create', $params);
1898 // I could try to parse the result to see whether the two phone numbers
1899 // and the website are there, but I am not sure about the correct format.
1900 // So I will just fetch it again before checking.
1901 // See also http://forum.civicrm.org/index.php/topic,35393.0.html
1904 'id' => $result['id'],
1905 'api.website.get' => array(),
1906 'api.phone.get' => array(),
1908 $result = $this->callAPISuccess('Contact', 'get', $params);
1910 // delete the contact
1911 $this->callAPISuccess('contact', 'delete', $result);
1913 $this->assertEquals(2, $result['values'][0]['api.phone.get']['count']);
1914 $this->assertEquals(1, $result['values'][0]['api.website.get']['count']);
1918 * Test retrieving an individual with chained array syntax.
1920 public function testGetIndividualWithChainedArraysFormats() {
1921 $description = "This demonstrates the usage of chained api functions.\nIn this case no notes or custom fields have been created.";
1922 $subfile = "APIChainedArrayFormats";
1923 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__
, __FILE__
);
1924 $params['custom_' . $ids['custom_field_id']] = "custom string";
1926 $moreIDs = $this->CustomGroupMultipleCreateWithFields();
1928 'first_name' => 'abc3',
1929 'last_name' => 'xyz3',
1930 'contact_type' => 'Individual',
1931 'email' => 'man3@yahoo.com',
1932 'api.contribution.create' => array(
1933 'receive_date' => '2010-01-01',
1934 'total_amount' => 100.00,
1935 'financial_type_id' => $this->_financialTypeId
,
1936 'payment_instrument_id' => 1,
1937 'non_deductible_amount' => 10.00,
1938 'fee_amount' => 50.00,
1939 'net_amount' => 90.00,
1941 'contribution_status_id' => 1,
1943 'api.contribution.create.1' => array(
1944 'receive_date' => '2011-01-01',
1945 'total_amount' => 120.00,
1946 'financial_type_id' => $this->_financialTypeId
,
1947 'payment_instrument_id' => 1,
1948 'non_deductible_amount' => 10.00,
1949 'fee_amount' => 50.00,
1950 'net_amount' => 90.00,
1952 'contribution_status_id' => 1,
1954 'api.website.create' => array(
1956 'url' => "http://civicrm.org",
1961 $result = $this->callAPISuccess('Contact', 'create', $params);
1963 'id' => $result['id'],
1964 'api.website.getValue' => array('return' => 'url'),
1965 'api.Contribution.getCount' => array(),
1966 'api.CustomValue.get' => 1,
1967 'api.Note.get' => 1,
1968 'api.Membership.getCount' => array(),
1970 $result = $this->callAPIAndDocument('Contact', 'Get', $params, __FUNCTION__
, __FILE__
, $description, $subfile);
1971 $this->assertEquals(2, $result['values'][$result['id']]['api.Contribution.getCount']);
1972 $this->assertEquals(0, $result['values'][$result['id']]['api.Note.get']['is_error']);
1973 $this->assertEquals("http://civicrm.org", $result['values'][$result['id']]['api.website.getValue']);
1975 $this->callAPISuccess('contact', 'delete', $result);
1976 $this->customGroupDelete($ids['custom_group_id']);
1977 $this->customGroupDelete($moreIDs['custom_group_id']);
1981 * Test complex chaining.
1983 public function testGetIndividualWithChainedArraysAndMultipleCustom() {
1984 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__
, __FILE__
);
1985 $params['custom_' . $ids['custom_field_id']] = "custom string";
1986 $moreIDs = $this->CustomGroupMultipleCreateWithFields();
1987 $andMoreIDs = $this->CustomGroupMultipleCreateWithFields(array(
1988 'title' => "another group",
1989 'name' => 'another name',
1991 $description = "This demonstrates the usage of chained api functions with multiple custom fields.";
1992 $subfile = "APIChainedArrayMultipleCustom";
1994 'first_name' => 'abc3',
1995 'last_name' => 'xyz3',
1996 'contact_type' => 'Individual',
1997 'email' => 'man3@yahoo.com',
1998 'api.contribution.create' => array(
1999 'receive_date' => '2010-01-01',
2000 'total_amount' => 100.00,
2001 'financial_type_id' => 1,
2002 'payment_instrument_id' => 1,
2003 'non_deductible_amount' => 10.00,
2004 'fee_amount' => 50.00,
2005 'net_amount' => 90.00,
2007 'invoice_id' => 67890,
2009 'contribution_status_id' => 1,
2011 'api.contribution.create.1' => array(
2012 'receive_date' => '2011-01-01',
2013 'total_amount' => 120.00,
2014 'financial_type_id' => 1,
2015 'payment_instrument_id' => 1,
2016 'non_deductible_amount' => 10.00,
2017 'fee_amount' => 50.00,
2018 'net_amount' => 90.00,
2020 'invoice_id' => 67830,
2022 'contribution_status_id' => 1,
2024 'api.website.create' => array(
2026 'url' => "http://civicrm.org",
2029 'custom_' . $ids['custom_field_id'] => "value 1",
2030 'custom_' . $moreIDs['custom_field_id'][0] => "value 2",
2031 'custom_' . $moreIDs['custom_field_id'][1] => "warm beer",
2032 'custom_' . $andMoreIDs['custom_field_id'][1] => "vegemite",
2035 $result = $this->callAPISuccess('Contact', 'create', $params);
2036 $result = $this->callAPISuccess('Contact', 'create', array(
2037 'contact_type' => 'Individual',
2038 'id' => $result['id'],
2040 $moreIDs['custom_field_id'][0] => "value 3",
2042 $ids['custom_field_id'] => "value 4",
2046 'id' => $result['id'],
2047 'api.website.getValue' => array('return' => 'url'),
2048 'api.Contribution.getCount' => array(),
2049 'api.CustomValue.get' => 1,
2051 $result = $this->callAPIAndDocument('Contact', 'Get', $params, __FUNCTION__
, __FILE__
, $description, $subfile);
2053 $this->customGroupDelete($ids['custom_group_id']);
2054 $this->customGroupDelete($moreIDs['custom_group_id']);
2055 $this->customGroupDelete($andMoreIDs['custom_group_id']);
2056 $this->assertEquals(0, $result['values'][$result['id']]['api.CustomValue.get']['is_error']);
2057 $this->assertEquals('http://civicrm.org', $result['values'][$result['id']]['api.website.getValue']);
2061 * Test checks usage of $values to pick & choose inputs.
2063 public function testChainingValuesCreate() {
2064 $description = "This demonstrates the usage of chained api functions. Specifically it has one 'parent function' &
2065 2 child functions - one receives values from the parent (Contact) and the other child (Tag).";
2066 $subfile = "APIChainedArrayValuesFromSiblingFunction";
2068 'display_name' => 'batman',
2069 'contact_type' => 'Individual',
2070 'api.tag.create' => array(
2071 'name' => '$value.id',
2072 'description' => '$value.display_name',
2073 'format.only_id' => 1,
2075 'api.entity_tag.create' => array('tag_id' => '$value.api.tag.create'),
2077 $result = $this->callAPIAndDocument('Contact', 'Create', $params, __FUNCTION__
, __FILE__
, $description, $subfile);
2078 $this->assertEquals(0, $result['values'][$result['id']]['api.entity_tag.create']['is_error']);
2080 $tablesToTruncate = array(
2083 'civicrm_entity_tag',
2086 $this->quickCleanup($tablesToTruncate, TRUE);
2090 * Test TrueFalse format - I couldn't come up with an easy way to get an error on Get.
2092 public function testContactGetFormatIsSuccessTrue() {
2093 $this->createContactFromXML();
2094 $description = "This demonstrates use of the 'format.is_success' param.
2095 This param causes only the success or otherwise of the function to be returned as BOOLEAN";
2096 $subfile = "FormatIsSuccess_True";
2097 $params = array('id' => 17, 'format.is_success' => 1);
2098 $result = $this->callAPIAndDocument('Contact', 'Get', $params, __FUNCTION__
, __FILE__
, $description, $subfile);
2099 $this->assertEquals(1, $result);
2100 $this->callAPISuccess('Contact', 'Delete', $params);
2104 * Test TrueFalse format.
2106 public function testContactCreateFormatIsSuccessFalse() {
2108 $description = "This demonstrates use of the 'format.is_success' param.
2109 This param causes only the success or otherwise of the function to be returned as BOOLEAN";
2110 $subfile = "FormatIsSuccess_Fail";
2111 $params = array('id' => 500, 'format.is_success' => 1);
2112 $result = $this->callAPIAndDocument('Contact', 'Create', $params, __FUNCTION__
, __FILE__
, $description, $subfile);
2113 $this->assertEquals(0, $result);
2117 * Test Single Entity format.
2119 public function testContactGetSingleEntityArray() {
2120 $this->createContactFromXML();
2121 $description = "This demonstrates use of the 'format.single_entity_array' param.
2122 This param causes the only contact to be returned as an array without the other levels.
2123 It will be ignored if there is not exactly 1 result";
2124 $subfile = "GetSingleContact";
2125 $params = array('id' => 17);
2126 $result = $this->callAPIAndDocument('Contact', 'GetSingle', $params, __FUNCTION__
, __FILE__
, $description, $subfile);
2127 $this->assertEquals('Test Contact', $result['display_name']);
2128 $this->callAPISuccess('Contact', 'Delete', $params);
2132 * Test Single Entity format.
2134 public function testContactGetFormatCountOnly() {
2135 $this->createContactFromXML();
2136 $description = "This demonstrates use of the 'getCount' action.
2137 This param causes the count of the only function to be returned as an integer.";
2138 $params = array('id' => 17);
2139 $result = $this->callAPIAndDocument('Contact', 'GetCount', $params, __FUNCTION__
, __FILE__
, $description,
2141 $this->assertEquals('1', $result);
2142 $this->callAPISuccess('Contact', 'Delete', $params);
2146 * Test id only format.
2148 public function testContactGetFormatIDOnly() {
2149 $this->createContactFromXML();
2150 $description = "This demonstrates use of the 'format.id_only' param.
2151 This param causes the id of the only entity to be returned as an integer.
2152 It will be ignored if there is not exactly 1 result";
2153 $subfile = "FormatOnlyID";
2154 $params = array('id' => 17, 'format.only_id' => 1);
2155 $result = $this->callAPIAndDocument('Contact', 'Get', $params, __FUNCTION__
, __FILE__
, $description, $subfile);
2156 $this->assertEquals('17', $result);
2157 $this->callAPISuccess('Contact', 'Delete', $params);
2161 * Test id only format.
2163 public function testContactGetFormatSingleValue() {
2164 $this->createContactFromXML();
2165 $description = "This demonstrates use of the 'format.single_value' param.
2166 This param causes only a single value of the only entity to be returned as an string.
2167 It will be ignored if there is not exactly 1 result";
2168 $subFile = "FormatSingleValue";
2169 $params = array('id' => 17, 'return' => 'display_name');
2170 $result = $this->callAPIAndDocument('Contact', 'getvalue', $params, __FUNCTION__
, __FILE__
, $description, $subFile);
2171 $this->assertEquals('Test Contact', $result);
2172 $this->callAPISuccess('Contact', 'Delete', $params);
2176 * Test that permissions are respected when creating contacts.
2178 public function testContactCreationPermissions() {
2180 'contact_type' => 'Individual',
2181 'first_name' => 'Foo',
2182 'last_name' => 'Bear',
2183 'check_permissions' => TRUE,
2185 $config = CRM_Core_Config
::singleton();
2186 $config->userPermissionClass
->permissions
= array('access CiviCRM');
2187 $result = $this->callAPIFailure('contact', 'create', $params);
2188 $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');
2190 $config->userPermissionClass
->permissions
= array('access CiviCRM', 'add contacts', 'import contacts');
2191 $this->callAPISuccess('contact', 'create', $params);
2195 * Test update with check permissions set.
2197 public function testContactUpdatePermissions() {
2199 'contact_type' => 'Individual',
2200 'first_name' => 'Foo',
2201 'last_name' => 'Bear',
2202 'check_permissions' => TRUE,
2204 $result = $this->callAPISuccess('contact', 'create', $params);
2205 $config = CRM_Core_Config
::singleton();
2207 'id' => $result['id'],
2208 'contact_type' => 'Individual',
2209 'last_name' => 'Bar',
2210 'check_permissions' => TRUE,
2213 $config->userPermissionClass
->permissions
= array('access CiviCRM');
2214 $result = $this->callAPIFailure('contact', 'update', $params);
2215 $this->assertEquals('Permission denied to modify contact record', $result['error_message']);
2217 $config->userPermissionClass
->permissions
= array(
2220 'view all contacts',
2221 'edit all contacts',
2224 $this->callAPISuccess('contact', 'update', $params);
2228 * Set up helper to create a contact.
2230 public function createContactFromXML() {
2231 // Insert a row in civicrm_contact creating contact 17.
2232 $op = new PHPUnit_Extensions_Database_Operation_Insert();
2233 $op->execute($this->_dbconn
,
2234 $this->createXMLDataSet(
2235 dirname(__FILE__
) . '/dataset/contact_17.xml'
2241 * Test contact proximity api.
2243 public function testContactProximity() {
2244 // first create a contact with a SF location with a specific
2246 $contactID = $this->organizationCreate();
2248 // now create the address
2250 'street_address' => '123 Main Street',
2251 'city' => 'San Francisco',
2253 'country_id' => 1228,
2254 'state_province_id' => 1004,
2255 'geo_code_1' => '37.79',
2256 'geo_code_2' => '-122.40',
2257 'location_type_id' => 1,
2258 'contact_id' => $contactID,
2261 $result = $this->callAPISuccess('address', 'create', $params);
2262 $this->assertEquals(1, $result['count']);
2264 // now do a proximity search with a close enough geocode and hope to match
2265 // that specific contact only!
2266 $proxParams = array(
2268 'longitude' => -122.3,
2272 $result = $this->callAPISuccess('contact', 'proximity', $proxParams);
2273 $this->assertEquals(1, $result['count']);
2277 * Test that Ajax API permission is sufficient to access getquick api.
2279 * (note that getquick api is required for autocomplete & has ACL permissions applied)
2281 public function testGetquickPermissionCRM13744() {
2282 CRM_Core_Config
::singleton()->userPermissionClass
->permissions
= array('access CiviEvent');
2283 $this->callAPIFailure('contact', 'getquick', array('name' => 'b', 'check_permissions' => TRUE));
2284 CRM_Core_Config
::singleton()->userPermissionClass
->permissions
= array('access CiviCRM');
2285 $this->callAPISuccess('contact', 'getquick', array('name' => 'b', 'check_permissions' => TRUE));
2286 CRM_Core_Config
::singleton()->userPermissionClass
->permissions
= array('access AJAX API');
2287 $this->callAPISuccess('contact', 'getquick', array('name' => 'b', 'check_permissions' => TRUE));
2291 * Test that getquick returns contacts with an exact first name match first.
2293 * The search string 'b' & 'bob' both return ordered by sort_name if includeOrderByClause
2294 * is true (default) but if it is false then matches are returned in ID order.
2296 public function testGetQuickExactFirst() {
2297 $this->getQuickSearchSampleData();
2298 $result = $this->callAPISuccess('contact', 'getquick', array('name' => 'b'));
2299 $this->assertEquals('A Bobby, Bobby', $result['values'][0]['sort_name']);
2300 $this->assertEquals('B Bobby, Bobby', $result['values'][1]['sort_name']);
2301 $result = $this->callAPISuccess('contact', 'getquick', array('name' => 'bob'));
2302 $this->assertEquals('A Bobby, Bobby', $result['values'][0]['sort_name']);
2303 $this->assertEquals('B Bobby, Bobby', $result['values'][1]['sort_name']);
2304 $this->callAPISuccess('Setting', 'create', array('includeOrderByClause' => FALSE));
2305 $result = $this->callAPISuccess('contact', 'getquick', array('name' => 'bob'));
2306 $this->assertEquals('Bob, Bob', $result['values'][0]['sort_name']);
2307 $this->assertEquals('A Bobby, Bobby', $result['values'][1]['sort_name']);
2311 * Test that getquick returns contacts with an exact first name match first.
2313 public function testGetQuickEmail() {
2314 $this->getQuickSearchSampleData();
2315 $loggedInContactID = $this->createLoggedInUser();
2316 $result = $this->callAPISuccess('contact', 'getquick', array(
2319 $expectedData = array(
2320 'Bob, Bob :: bob@bob.com',
2322 'E Bobby, Bobby :: bob@bobby.com',
2323 'H Bobby, Bobby :: bob@h.com',
2325 $this->callAPISuccessGetValue('Contact', array('id' => $loggedInContactID, 'return' => 'last_name')) . ', Logged In :: anthony_anderson@civicrm.org',
2327 $this->assertEquals(6, $result['count']);
2328 foreach ($expectedData as $index => $value) {
2329 $this->assertEquals($value, $result['values'][$index]['data']);
2331 $result = $this->callAPISuccess('contact', 'getquick', array(
2334 $expectedData = array(
2335 'H Bobby, Bobby :: bob@h.com',
2337 foreach ($expectedData as $index => $value) {
2338 $this->assertEquals($value, $result['values'][$index]['data']);
2340 $this->callAPISuccess('Setting', 'create', array('includeWildCardInName' => FALSE));
2341 $result = $this->callAPISuccess('contact', 'getquick', array(
2344 $this->callAPISuccess('Setting', 'create', array('includeWildCardInName' => TRUE));
2345 $this->assertEquals(0, $result['count']);
2349 * Test that getquick returns contacts with an exact first name match first.
2351 public function testGetQuickEmailACL() {
2352 $this->getQuickSearchSampleData();
2353 $loggedInContactID = $this->createLoggedInUser();
2354 CRM_Core_Config
::singleton()->userPermissionClass
->permissions
= array();
2355 $result = $this->callAPISuccess('contact', 'getquick', array(
2358 $this->assertEquals(0, $result['count']);
2360 $this->hookClass
->setHook('civicrm_aclWhereClause', array($this, 'aclWhereNoBobH'));
2361 CRM_Contact_BAO_Contact_Permission
::cache($loggedInContactID, CRM_Core_Permission
::VIEW
, TRUE);
2362 $result = $this->callAPISuccess('contact', 'getquick', array(
2366 // Without the acl it would be 6 like the previous email getquick test.
2367 $this->assertEquals(5, $result['count']);
2368 $expectedData = array(
2369 'Bob, Bob :: bob@bob.com',
2371 'E Bobby, Bobby :: bob@bobby.com',
2373 $this->callAPISuccessGetValue('Contact', array('id' => $loggedInContactID, 'return' => 'last_name')) . ', Logged In :: anthony_anderson@civicrm.org',
2375 foreach ($expectedData as $index => $value) {
2376 $this->assertEquals($value, $result['values'][$index]['data']);
2381 * Test that getquick returns contacts with an exact first name match first.
2383 public function testGetQuickExternalID() {
2384 $this->getQuickSearchSampleData();
2385 $result = $this->callAPISuccess('contact', 'getquick', array(
2387 'field_name' => 'external_identifier',
2388 'table_name' => 'cc',
2390 $this->assertEquals(0, $result['count']);
2391 $result = $this->callAPISuccess('contact', 'getquick', array(
2393 'field_name' => 'external_identifier',
2394 'table_name' => 'cc',
2396 $this->assertEquals(1, $result['count']);
2397 $this->assertEquals('Bob, Bob', $result['values'][0]['sort_name']);
2401 * Test that getquick returns contacts with an exact first name match first.
2403 public function testGetQuickID() {
2404 $max = CRM_Core_DAO
::singleValueQuery("SELECT max(id) FROM civicrm_contact");
2405 $this->getQuickSearchSampleData();
2406 $result = $this->callAPISuccess('contact', 'getquick', array(
2408 'field_name' => 'id',
2409 'table_name' => 'cc',
2411 $this->assertEquals(1, $result['count']);
2412 $this->assertEquals('A Bobby, Bobby', $result['values'][0]['sort_name']);
2413 $result = $this->callAPISuccess('contact', 'getquick', array(
2415 'field_name' => 'contact_id',
2416 'table_name' => 'cc',
2418 $this->assertEquals(1, $result['count']);
2419 $this->assertEquals('A Bobby, Bobby', $result['values'][0]['sort_name']);
2423 * Test that getquick returns contacts with an exact first name match first.
2425 * Depending on the setting the sort name sort might click in next or not - test!
2427 public function testGetQuickFirstName() {
2428 $this->getQuickSearchSampleData();
2429 $this->callAPISuccess('Setting', 'create', array('includeOrderByClause' => TRUE));
2430 $result = $this->callAPISuccess('contact', 'getquick', array(
2432 'field_name' => 'first_name',
2433 'table_name' => 'cc',
2441 foreach ($expected as $index => $value) {
2442 $this->assertEquals($value, $result['values'][$index]['sort_name']);
2444 $this->callAPISuccess('Setting', 'create', array('includeOrderByClause' => FALSE));
2445 $result = $this->callAPISuccess('contact', 'getquick', array('name' => 'bob'));
2446 $this->assertEquals('Bob, Bob', $result['values'][0]['sort_name']);
2447 $this->assertEquals('A Bobby, Bobby', $result['values'][1]['sort_name']);
2451 * Test that getquick applies ACLs.
2453 public function testGetQuickFirstNameACLs() {
2454 $this->getQuickSearchSampleData();
2455 $userID = $this->createLoggedInUser();
2456 $this->callAPISuccess('Setting', 'create', array('includeOrderByClause' => TRUE));
2457 CRM_Core_Config
::singleton()->userPermissionClass
->permissions
= array();
2458 $result = $this->callAPISuccess('contact', 'getquick', array(
2460 'field_name' => 'first_name',
2461 'table_name' => 'cc',
2463 $this->assertEquals(0, $result['count']);
2465 $this->hookClass
->setHook('civicrm_aclWhereClause', array($this, 'aclWhereNoBobH'));
2466 CRM_Contact_BAO_Contact_Permission
::cache($userID, CRM_Core_Permission
::VIEW
, TRUE);
2467 $result = $this->callAPISuccess('contact', 'getquick', array(
2469 'field_name' => 'first_name',
2470 'table_name' => 'cc',
2472 $this->assertEquals('K Bobby, Bob', $result['values'][1]['sort_name']);
2473 // Without the ACL 9 would be bob@h.com.
2474 $this->assertEquals('I Bobby, Bobby', $result['values'][9]['sort_name']);
2478 * Full results returned.
2479 * @implements CRM_Utils_Hook::aclWhereClause
2481 * @param string $type
2482 * @param array $tables
2483 * @param array $whereTables
2484 * @param int $contactID
2485 * @param string $where
2487 public function aclWhereNoBobH($type, &$tables, &$whereTables, &$contactID, &$where) {
2488 $where = " (email <> 'bob@h.com' OR email IS NULL) ";
2489 $whereTables['civicrm_email'] = "LEFT JOIN civicrm_email e ON contact_a.id = e.contact_id";
2493 * Test that getquick returns contacts with an exact last name match first.
2495 public function testGetQuickLastName() {
2496 $this->getQuickSearchSampleData();
2497 $this->callAPISuccess('Setting', 'create', array('includeOrderByClause' => TRUE));
2498 $result = $this->callAPISuccess('contact', 'getquick', array(
2500 'field_name' => 'last_name',
2501 'table_name' => 'cc',
2509 foreach ($expected as $index => $value) {
2510 $this->assertEquals($value, $result['values'][$index]['sort_name']);
2512 $this->callAPISuccess('Setting', 'create', array('includeOrderByClause' => FALSE));
2513 $result = $this->callAPISuccess('contact', 'getquick', array('name' => 'bob'));
2514 $this->assertEquals('Bob, Bob :: bob@bob.com', $result['values'][0]['data']);
2518 * Test that getquick returns contacts by city.
2520 public function testGetQuickCity() {
2521 $this->getQuickSearchSampleData();
2522 $result = $this->callAPISuccess('contact', 'getquick', array(
2524 'field_name' => 'city',
2525 'table_name' => 'sts',
2527 $this->assertEquals('B Bobby, Bobby :: Toronto', $result['values'][0]['data']);
2528 $result = $this->callAPISuccess('contact', 'getquick', array(
2530 'field_name' => 'city',
2531 'table_name' => 'sts',
2533 $this->assertEquals('B Bobby, Bobby :: Toronto', $result['values'][0]['data']);
2534 $this->assertEquals('C Bobby, Bobby :: Whanganui', $result['values'][1]['data']);
2538 * Set up some sample data for testing quicksearch.
2540 public function getQuickSearchSampleData() {
2542 array('first_name' => 'Bob', 'last_name' => 'Bob', 'external_identifier' => 'abc', 'email' => 'bob@bob.com'),
2543 array('first_name' => 'Bobby', 'last_name' => 'A Bobby', 'external_identifier' => 'abcd'),
2545 'first_name' => 'Bobby',
2546 'last_name' => 'B Bobby',
2547 'external_identifier' => 'bcd',
2548 'api.address.create' => array(
2549 'street_address' => 'Sesame Street',
2550 'city' => 'Toronto',
2551 'location_type_id' => 1,
2555 'first_name' => 'Bobby',
2556 'last_name' => 'C Bobby',
2557 'external_identifier' => 'bcde',
2558 'api.address.create' => array(
2559 'street_address' => 'Te huarahi',
2560 'city' => 'Whanganui',
2561 'location_type_id' => 1,
2564 array('first_name' => 'Bobby', 'last_name' => 'D Bobby', 'external_identifier' => 'efg'),
2565 array('first_name' => 'Bobby', 'last_name' => 'E Bobby', 'external_identifier' => 'hij', 'email' => 'bob@bobby.com'),
2566 array('first_name' => 'Bobby', 'last_name' => 'F Bobby', 'external_identifier' => 'klm'),
2567 array('first_name' => 'Bobby', 'last_name' => 'G Bobby', 'external_identifier' => 'nop'),
2568 array('first_name' => 'Bobby', 'last_name' => 'H Bobby', 'external_identifier' => 'qrs', 'email' => 'bob@h.com'),
2569 array('first_name' => 'Bobby', 'last_name' => 'I Bobby'),
2570 array('first_name' => 'Bobby', 'last_name' => 'J Bobby'),
2571 array('first_name' => 'Bob', 'last_name' => 'K Bobby', 'external_identifier' => 'bcdef'),
2573 foreach ($contacts as $type => $contact) {
2574 $contact['contact_type'] = 'Individual';
2575 $this->callAPISuccess('Contact', 'create', $contact);
2580 * Test get ref api - gets a list of references to an entity.
2582 public function testGetReferenceCounts() {
2583 $result = $this->callAPISuccess('Contact', 'create', array(
2584 'first_name' => 'Testily',
2585 'last_name' => 'McHaste',
2586 'contact_type' => 'Individual',
2587 'api.Address.replace' => array(
2588 'values' => array(),
2590 'api.Email.replace' => array(
2593 'email' => 'spam@dev.null',
2595 'location_type_id' => 1,
2599 'api.Phone.replace' => array(
2602 'phone' => '234-567-0001',
2604 'location_type_id' => 1,
2607 'phone' => '234-567-0002',
2609 'location_type_id' => 1,
2615 //$dao = new CRM_Contact_BAO_Contact();
2616 //$dao->id = $result['id'];
2617 //$this->assertTrue((bool) $dao->find(TRUE));
2619 //$refCounts = $dao->getReferenceCounts();
2620 //$this->assertTrue(is_array($refCounts));
2621 //$refCountsIdx = CRM_Utils_Array::index(array('name'), $refCounts);
2623 $refCounts = $this->callAPISuccess('Contact', 'getrefcount', array(
2624 'id' => $result['id'],
2626 $refCountsIdx = CRM_Utils_Array
::index(array('name'), $refCounts['values']);
2628 $this->assertEquals(1, $refCountsIdx['sql:civicrm_email:contact_id']['count']);
2629 $this->assertEquals('civicrm_email', $refCountsIdx['sql:civicrm_email:contact_id']['table']);
2630 $this->assertEquals(2, $refCountsIdx['sql:civicrm_phone:contact_id']['count']);
2631 $this->assertEquals('civicrm_phone', $refCountsIdx['sql:civicrm_phone:contact_id']['table']);
2632 $this->assertTrue(!isset($refCountsIdx['sql:civicrm_address:contact_id']));
2636 * Test the use of sql operators.
2638 public function testSQLOperatorsOnContactAPI() {
2639 $this->individualCreate();
2640 $this->organizationCreate();
2641 $this->householdCreate();
2642 $contacts = $this->callAPISuccess('contact', 'get', array('legal_name' => array('IS NOT NULL' => TRUE)));
2643 $this->assertEquals($contacts['count'], CRM_Core_DAO
::singleValueQuery('select count(*) FROM civicrm_contact WHERE legal_name IS NOT NULL'));
2644 $contacts = $this->callAPISuccess('contact', 'get', array('legal_name' => array('IS NULL' => TRUE)));
2645 $this->assertEquals($contacts['count'], CRM_Core_DAO
::singleValueQuery('select count(*) FROM civicrm_contact WHERE legal_name IS NULL'));
2649 * CRM-14743 - test api respects search operators.
2651 public function testGetModifiedDateByOperators() {
2652 $preExistingContactCount = CRM_Core_DAO
::singleValueQuery('select count(*) FROM civicrm_contact');
2653 $contact1 = $this->individualCreate();
2654 $sql = "UPDATE civicrm_contact SET created_date = '2012-01-01', modified_date = '2013-01-01' WHERE id = " . $contact1;
2655 CRM_Core_DAO
::executeQuery($sql);
2656 $contact2 = $this->individualCreate();
2657 $sql = "UPDATE civicrm_contact SET created_date = '2012-02-01', modified_date = '2013-02-01' WHERE id = " . $contact2;
2658 CRM_Core_DAO
::executeQuery($sql);
2659 $contact3 = $this->householdCreate();
2660 $sql = "UPDATE civicrm_contact SET created_date = '2012-03-01', modified_date = '2013-03-01' WHERE id = " . $contact3;
2661 CRM_Core_DAO
::executeQuery($sql);
2662 $contacts = $this->callAPISuccess('contact', 'get', array('modified_date' => array('<' => '2014-01-01')));
2663 $this->assertEquals($contacts['count'], 3);
2664 $contacts = $this->callAPISuccess('contact', 'get', array('modified_date' => array('>' => '2014-01-01')));
2665 $this->assertEquals($contacts['count'], $preExistingContactCount);
2669 * CRM-14743 - test api respects search operators.
2671 public function testGetCreatedDateByOperators() {
2672 $preExistingContactCount = CRM_Core_DAO
::singleValueQuery('select count(*) FROM civicrm_contact');
2673 $contact1 = $this->individualCreate();
2674 $sql = "UPDATE civicrm_contact SET created_date = '2012-01-01' WHERE id = " . $contact1;
2675 CRM_Core_DAO
::executeQuery($sql);
2676 $contact2 = $this->individualCreate();
2677 $sql = "UPDATE civicrm_contact SET created_date = '2012-02-01' WHERE id = " . $contact2;
2678 CRM_Core_DAO
::executeQuery($sql);
2679 $contact3 = $this->householdCreate();
2680 $sql = "UPDATE civicrm_contact SET created_date = '2012-03-01' WHERE id = " . $contact3;
2681 CRM_Core_DAO
::executeQuery($sql);
2682 $contacts = $this->callAPISuccess('contact', 'get', array('created_date' => array('<' => '2014-01-01')));
2683 $this->assertEquals($contacts['count'], 3);
2684 $contacts = $this->callAPISuccess('contact', 'get', array('created_date' => array('>' => '2014-01-01')));
2685 $this->assertEquals($contacts['count'], $preExistingContactCount);
2689 * CRM-14263 check that API is not affected by search profile related bug.
2691 public function testReturnCityProfile() {
2692 $contactID = $this->individualCreate();
2693 CRM_Core_Config
::singleton()->defaultSearchProfileID
= 1;
2694 $this->callAPISuccess('address', 'create', array(
2695 'contact_id' => $contactID,
2696 'city' => 'Cool City',
2697 'location_type_id' => 1,
2699 $result = $this->callAPISuccess('contact', 'get', array('city' => 'Cool City', 'return' => 'contact_type'));
2700 $this->assertEquals(1, $result['count']);
2704 * CRM-15443 - ensure getlist api does not return deleted contacts.
2706 public function testGetlistExcludeConditions() {
2707 $name = md5(time());
2708 $contact = $this->individualCreate(array('last_name' => $name));
2709 $this->individualCreate(array('last_name' => $name, 'is_deceased' => 1));
2710 $this->individualCreate(array('last_name' => $name, 'is_deleted' => 1));
2711 // We should get all but the deleted contact.
2712 $result = $this->callAPISuccess('contact', 'getlist', array('input' => $name));
2713 $this->assertEquals(2, $result['count']);
2714 // Force-exclude the deceased contact.
2715 $result = $this->callAPISuccess('contact', 'getlist', array(
2717 'params' => array('is_deceased' => 0),
2719 $this->assertEquals(1, $result['count']);
2720 $this->assertEquals($contact, $result['values'][0]['id']);
2724 * Test contact getactions.
2726 public function testGetActions() {
2727 $description = "Getting the available actions for an entity.";
2728 $result = $this->callAPIAndDocument($this->_entity
, 'getactions', array(), __FUNCTION__
, __FILE__
, $description);
2748 $deprecated = array(
2752 foreach ($expected as $action) {
2753 $this->assertTrue(in_array($action, $result['values']), "Expected action $action");
2755 foreach ($deprecated as $action) {
2756 $this->assertArrayKeyExists($action, $result['deprecated']);
2761 * Test the duplicate check function.
2763 public function testDuplicateCheck() {
2764 $this->callAPISuccess('Contact', 'create', array(
2765 'first_name' => 'Harry',
2766 'last_name' => 'Potter',
2767 'email' => 'harry@hogwarts.edu',
2768 'contact_type' => 'Individual',
2770 $result = $this->callAPISuccess('Contact', 'duplicatecheck', array(
2772 'first_name' => 'Harry',
2773 'last_name' => 'Potter',
2774 'email' => 'harry@hogwarts.edu',
2775 'contact_type' => 'Individual',
2779 $this->assertEquals(1, $result['count']);
2780 $result = $this->callAPISuccess('Contact', 'duplicatecheck', array(
2782 'first_name' => 'Harry',
2783 'last_name' => 'Potter',
2784 'email' => 'no5@privet.drive',
2785 'contact_type' => 'Individual',
2788 $this->assertEquals(0, $result['count']);
2791 public function testGetByContactType() {
2792 $individual = $this->callAPISuccess('Contact', 'create', array(
2793 'email' => 'individual@test.com',
2794 'contact_type' => 'Individual',
2796 $household = $this->callAPISuccess('Contact', 'create', array(
2797 'household_name' => 'household@test.com',
2798 'contact_type' => 'Household',
2800 $organization = $this->callAPISuccess('Contact', 'create', array(
2801 'organization_name' => 'organization@test.com',
2802 'contact_type' => 'Organization',
2804 // Test with id - getsingle will throw an exception if not found
2805 $this->callAPISuccess('Contact', 'getsingle', array(
2806 'id' => $individual['id'],
2807 'contact_type' => 'Individual',
2809 $this->callAPISuccess('Contact', 'getsingle', array(
2810 'id' => $individual['id'],
2811 'contact_type' => array('IN' => array('Individual')),
2814 $this->callAPISuccess('Contact', 'getsingle', array(
2815 'id' => $organization['id'],
2816 'contact_type' => array('IN' => array('Individual', 'Organization')),
2819 $result = $this->callAPISuccess('Contact', 'get', array(
2820 'contact_type' => array('IN' => array('Individual', 'Organization')),
2821 'options' => array('limit' => 0),
2824 $this->assertContains($organization['id'], array_keys($result['values']));
2825 $this->assertContains($individual['id'], array_keys($result['values']));
2826 $this->assertNotContains($household['id'], array_keys($result['values']));
2828 $result = $this->callAPISuccess('Contact', 'get', array(
2829 'contact_type' => 'Household',
2830 'options' => array('limit' => 0),
2833 $this->assertNotContains($organization['id'], array_keys($result['values']));
2834 $this->assertNotContains($individual['id'], array_keys($result['values']));
2835 $this->assertContains($household['id'], array_keys($result['values']));
2839 * Test merging 2 contacts.
2841 * Someone kindly bequethed us the legacy of mixed up use of main_id & other_id
2842 * in the params for contact.merge api.
2844 * This test protects that legacy.
2846 public function testMergeBizzareOldParams() {
2847 $this->createLoggedInUser();
2848 $otherContact = $this->callAPISuccess('contact', 'create', $this->_params
);
2849 $mainContact = $this->callAPISuccess('contact', 'create', $this->_params
);
2850 $this->callAPISuccess('contact', 'merge', array(
2851 'main_id' => $mainContact['id'],
2852 'other_id' => $otherContact['id'],
2854 $contacts = $this->callAPISuccess('contact', 'get', $this->_params
);
2855 $this->assertEquals($otherContact['id'], $contacts['id']);
2859 * Test merging 2 contacts.
2861 public function testMerge() {
2862 $this->createLoggedInUser();
2863 $otherContact = $this->callAPISuccess('contact', 'create', $this->_params
);
2864 $retainedContact = $this->callAPISuccess('contact', 'create', $this->_params
);
2865 $this->callAPISuccess('contact', 'merge', array(
2866 'to_keep_id' => $retainedContact['id'],
2867 'to_remove_id' => $otherContact['id'],
2868 'auto_flip' => FALSE,
2871 $contacts = $this->callAPISuccess('contact', 'get', $this->_params
);
2872 $this->assertEquals($retainedContact['id'], $contacts['id']);
2873 $activity = $this->callAPISuccess('Activity', 'getsingle', array(
2874 'target_contact_id' => $retainedContact['id'],
2875 'activity_type_id' => 'Contact Merged',
2877 $this->assertEquals(date('Y-m-d'), date('Y-m-d', strtotime($activity['activity_date_time'])));
2878 $activity2 = $this->callAPISuccess('Activity', 'getsingle', array(
2879 'target_contact_id' => $otherContact['id'],
2880 'activity_type_id' => 'Contact Deleted by Merge',
2882 $this->assertEquals($activity['id'], $activity2['parent_id']);
2883 $this->assertEquals('Normal', civicrm_api3('option_value', 'getvalue', array(
2884 'value' => $activity['priority_id'],
2885 'return' => 'label',
2886 'option_group_id' => 'priority',
2892 * Test merging 2 contacts with delete to trash off.
2894 * We are checking that there is no error due to attempting to add an activity for the
2899 public function testMergeNoTrash() {
2900 $this->createLoggedInUser();
2901 $this->callAPISuccess('Setting', 'create', array('contact_undelete' => FALSE));
2902 $otherContact = $this->callAPISuccess('contact', 'create', $this->_params
);
2903 $retainedContact = $this->callAPISuccess('contact', 'create', $this->_params
);
2904 $this->callAPISuccess('contact', 'merge', array(
2905 'to_keep_id' => $retainedContact['id'],
2906 'to_remove_id' => $otherContact['id'],
2907 'auto_flip' => FALSE,
2909 $this->callAPISuccess('Setting', 'create', array('contact_undelete' => TRUE));