4 * File for the TestContact class.
8 * @author Walt Haas <walt@dharmatech.org> (801) 534-1262
9 * @copyright Copyright CiviCRM LLC (C) 2009
10 * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html
11 * GNU Affero General Public License version 3
12 * @version $Id: ContactTest.php 31254 2010-12-15 10:09:29Z eileen $
15 * This file is part of CiviCRM
17 * CiviCRM is free software; you can redistribute it and/or
18 * modify it under the terms of the GNU Affero General Public License
19 * as published by the Free Software Foundation; either version 3 of
20 * the License, or (at your option) any later version.
22 * CiviCRM is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 * GNU Affero General Public License for more details.
27 * You should have received a copy of the GNU Affero General Public
28 * License along with this program. If not, see
29 * <http://www.gnu.org/licenses/>.
33 * Include class definitions
35 require_once 'CiviTest/CiviUnitTestCase.php';
39 * Test APIv3 civicrm_contact* functions
41 * @package CiviCRM_APIv3
42 * @subpackage API_Contact
44 class api_v3_ContactTest
extends CiviUnitTestCase
{
45 public $DBResetRequired = FALSE;
46 protected $_apiversion;
50 protected $_contactID;
51 protected $_financialTypeId = 1;
54 * Test setup for every test.
56 * Connect to the database, truncate the tables that will be used
57 * and redirect stdin to a temporary file
59 public function setUp() {
60 // Connect to the database.
62 $this->_apiversion
= 3;
63 $this->_entity
= 'contact';
64 $this->_params
= array(
65 'first_name' => 'abc1',
66 'contact_type' => 'Individual',
67 'last_name' => 'xyz1',
72 * Restore the DB for the next test.
76 public function tearDown() {
77 // truncate a few tables
78 $tablesToTruncate = array(
81 'civicrm_contribution',
84 'civicrm_relationship',
89 $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 with sub-types.
121 * Verify that sub-types are created successfully and not deleted by subsequent updates.
123 public function testIndividualSubType() {
125 'first_name' => 'test abc',
126 'contact_type' => 'Individual',
127 'last_name' => 'test xyz',
128 'contact_sub_type' => array('Student', 'Staff'),
130 $contact = $this->callAPISuccess('contact', 'create', $params);
131 $cid = $contact['id'];
135 'middle_name' => 'foo',
137 $this->callAPISuccess('contact', 'create', $params);
138 unset($params['middle_name']);
140 $contact = $this->callAPISuccess('contact', 'get', $params);
142 $this->assertEquals(array('Student', 'Staff'), $contact['values'][$cid]['contact_sub_type']);
146 * Verify that attempt to create contact with empty params fails.
148 public function testCreateEmptyContact() {
149 $this->callAPIFailure('contact', 'create', array());
153 * Verify that attempt to create contact with bad contact type fails.
155 public function testCreateBadTypeContact() {
157 'email' => 'man1@yahoo.com',
158 'contact_type' => 'Does not Exist',
160 $this->callAPIFailure('contact', 'create', $params, "'Does not Exist' is not a valid option for field contact_type");
164 * Verify that attempt to create individual contact without required fields fails.
166 public function testCreateBadRequiredFieldsIndividual() {
168 'middle_name' => 'This field is not required',
169 'contact_type' => 'Individual',
171 $this->callAPIFailure('contact', 'create', $params);
175 * Verify that attempt to create household contact without required fields fails.
177 public function testCreateBadRequiredFieldsHousehold() {
179 'middle_name' => 'This field is not required',
180 'contact_type' => 'Household',
182 $this->callAPIFailure('contact', 'create', $params);
186 * Test required field check.
188 * Verify that attempt to create organization contact without required fields fails.
190 public function testCreateBadRequiredFieldsOrganization() {
192 'middle_name' => 'This field is not required',
193 'contact_type' => 'Organization',
196 $this->callAPIFailure('contact', 'create', $params);
200 * Verify that attempt to create individual contact with only an email succeeds.
202 public function testCreateEmailIndividual() {
205 'email' => 'man3@yahoo.com',
206 'contact_type' => 'Individual',
207 'location_type_id' => 1,
210 $contact = $this->callAPISuccess('contact', 'create', $params);
212 $this->assertEquals(1, $contact['id']);
213 $email = $this->callAPISuccess('email', 'get', array('contact_id' => $contact['id']));
214 $this->assertEquals(1, $email['count']);
215 $this->assertEquals('man3@yahoo.com', $email['values'][$email['id']]['email']);
217 $this->callAPISuccess('contact', 'delete', $contact);
221 * Test creating individual by name.
223 * Verify create individual contact with only first and last names succeeds.
225 public function testCreateNameIndividual() {
227 'first_name' => 'abc1',
228 'contact_type' => 'Individual',
229 'last_name' => 'xyz1',
232 $contact = $this->callAPISuccess('contact', 'create', $params);
233 $this->assertEquals(1, $contact['id']);
237 * Test creating individual by display_name.
239 * Display name & sort name should be set.
241 public function testCreateDisplayNameIndividual() {
243 'display_name' => 'abc1',
244 'contact_type' => 'Individual',
247 $contact = $this->callAPISuccess('contact', 'create', $params);
248 $params['sort_name'] = 'abc1';
249 $this->getAndCheck($params, $contact['id'], 'contact');
253 * Test old keys still work.
255 * Verify that attempt to create individual contact with
256 * first and last names and old key values works
258 public function testCreateNameIndividualOldKeys() {
260 'individual_prefix' => 'Dr.',
261 'first_name' => 'abc1',
262 'contact_type' => 'Individual',
263 'last_name' => 'xyz1',
264 'individual_suffix' => 'Jr.',
267 $contact = $this->callAPISuccess('contact', 'create', $params);
268 $result = $this->callAPISuccess('contact', 'getsingle', array('id' => $contact['id']));
270 $this->assertArrayKeyExists('prefix_id', $result);
271 $this->assertArrayKeyExists('suffix_id', $result);
272 $this->assertArrayKeyExists('gender_id', $result);
273 $this->assertEquals(4, $result['prefix_id']);
274 $this->assertEquals(1, $result['suffix_id']);
278 * Test preferred keys work.
280 * Verify that attempt to create individual contact with
281 * first and last names and old key values works
283 public function testCreateNameIndividualRecommendedKeys2() {
285 'prefix_id' => 'Dr.',
286 'first_name' => 'abc1',
287 'contact_type' => 'Individual',
288 'last_name' => 'xyz1',
289 'suffix_id' => 'Jr.',
290 'gender_id' => 'Male',
293 $contact = $this->callAPISuccess('contact', 'create', $params);
294 $result = $this->callAPISuccess('contact', 'getsingle', array('id' => $contact['id']));
296 $this->assertArrayKeyExists('prefix_id', $result);
297 $this->assertArrayKeyExists('suffix_id', $result);
298 $this->assertArrayKeyExists('gender_id', $result);
299 $this->assertEquals(4, $result['prefix_id']);
300 $this->assertEquals(1, $result['suffix_id']);
304 * Test household name is sufficient for create.
306 * Verify that attempt to create household contact with only
307 * household name succeeds
309 public function testCreateNameHousehold() {
311 'household_name' => 'The abc Household',
312 'contact_type' => 'Household',
314 $contact = $this->callAPISuccess('contact', 'create', $params);
315 $this->assertEquals(1, $contact['id']);
319 * Test organization name is sufficient for create.
321 * Verify that attempt to create organization contact with only
322 * organization name succeeds.
324 public function testCreateNameOrganization() {
326 'organization_name' => 'The abc Organization',
327 'contact_type' => 'Organization',
329 $contact = $this->callAPISuccess('contact', 'create', $params);
330 $this->assertEquals(1, $contact['id']);
334 * Verify that attempt to create organization contact without organization name fails.
336 public function testCreateNoNameOrganization() {
338 'first_name' => 'The abc Organization',
339 'contact_type' => 'Organization',
341 $this->callAPIFailure('contact', 'create', $params);
345 * Check with complete array + custom field.
347 * Note that the test is written on purpose without any
348 * variables specific to participant so it can be replicated into other entities
349 * and / or moved to the automated test suite
351 public function testCreateWithCustom() {
352 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__
, __FILE__
);
354 $params = $this->_params
;
355 $params['custom_' . $ids['custom_field_id']] = "custom string";
356 $description = "This demonstrates setting a custom field through the API.";
357 $result = $this->callAPIAndDocument($this->_entity
, 'create', $params, __FUNCTION__
, __FILE__
, $description);
359 $check = $this->callAPISuccess($this->_entity
, 'get', array(
360 'return.custom_' . $ids['custom_field_id'] => 1,
361 'id' => $result['id'],
363 $this->assertEquals("custom string", $check['values'][$check['id']]['custom_' . $ids['custom_field_id']]);
365 $this->customFieldDelete($ids['custom_field_id']);
366 $this->customGroupDelete($ids['custom_group_id']);
370 * CRM-12773 - expectation is that civicrm quietly ignores fields without values.
372 public function testCreateWithNULLCustomCRM12773() {
373 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__
, __FILE__
);
374 $params = $this->_params
;
375 $params['custom_' . $ids['custom_field_id']] = NULL;
376 $this->callAPISuccess('contact', 'create', $params);
377 $this->customFieldDelete($ids['custom_field_id']);
378 $this->customGroupDelete($ids['custom_group_id']);
382 * CRM-15792 - create/update datetime field for contact.
384 public function testCreateContactCustomFldDateTime() {
385 $customGroup = $this->customGroupCreate(array('extends' => 'Individual', 'title' => 'datetime_test_group'));
386 $dateTime = CRM_Utils_Date
::currentDBDate();
387 //check date custom field is saved along with time when time_format is set
389 'first_name' => 'abc3',
390 'last_name' => 'xyz3',
391 'contact_type' => 'Individual',
392 'email' => 'man3@yahoo.com',
393 'api.CustomField.create' => array(
394 'custom_group_id' => $customGroup['id'],
395 'name' => 'test_datetime',
396 'label' => 'Demo Date',
397 'html_type' => 'Select Date',
398 'data_type' => 'Date',
402 'is_searchable' => 0,
407 $result = $this->callAPIAndDocument('Contact', 'create', $params, __FUNCTION__
, __FILE__
);
408 $customFldId = $result['values'][$result['id']]['api.CustomField.create']['id'];
409 $this->assertNotNull($result['id'], 'in line ' . __LINE__
);
410 $this->assertNotNull($customFldId, 'in line ' . __LINE__
);
413 'id' => $result['id'],
414 "custom_{$customFldId}" => $dateTime,
415 'api.CustomValue.get' => 1,
418 $result = $this->callAPIAndDocument('Contact', 'create', $params, __FUNCTION__
, __FILE__
);
419 $this->assertNotNull($result['id'], 'in line ' . __LINE__
);
420 $customFldDate = date("YmdHis", strtotime($result['values'][$result['id']]['api.CustomValue.get']['values'][0]['latest']));
421 $this->assertNotNull($customFldDate, 'in line ' . __LINE__
);
422 $this->assertEquals($dateTime, $customFldDate);
423 $customValueId = $result['values'][$result['id']]['api.CustomValue.get']['values'][0]['id'];
424 $dateTime = date('Ymd');
425 //date custom field should not contain time part when time_format is null
427 'id' => $result['id'],
428 'api.CustomField.create' => array(
429 'id' => $customFldId,
430 'html_type' => 'Select Date',
431 'data_type' => 'Date',
434 'api.CustomValue.create' => array(
435 'id' => $customValueId,
436 'entity_id' => $result['id'],
437 "custom_{$customFldId}" => $dateTime,
439 'api.CustomValue.get' => 1,
441 $result = $this->callAPIAndDocument('Contact', 'create', $params, __FUNCTION__
, __FILE__
);
442 $this->assertNotNull($result['id'], 'in line ' . __LINE__
);
443 $customFldDate = date("Ymd", strtotime($result['values'][$result['id']]['api.CustomValue.get']['values'][0]['latest']));
444 $customFldTime = date("His", strtotime($result['values'][$result['id']]['api.CustomValue.get']['values'][0]['latest']));
445 $this->assertNotNull($customFldDate, 'in line ' . __LINE__
);
446 $this->assertEquals($dateTime, $customFldDate);
447 $this->assertEquals(000000, $customFldTime);
448 $this->callAPIAndDocument('Contact', 'create', $params, __FUNCTION__
, __FILE__
);
453 * Test creating a current employer through API.
455 public function testContactCreateCurrentEmployer() {
456 // Here we will just do the get for set-up purposes.
457 $count = $this->callAPISuccess('contact', 'getcount', array(
458 'organization_name' => 'new employer org',
459 'contact_type' => 'Organization',
461 $this->assertEquals(0, $count);
462 $employerResult = $this->callAPISuccess('contact', 'create', array_merge($this->_params
, array(
463 'current_employer' => 'new employer org',
466 // do it again as an update to check it doesn't cause an error
467 $employerResult = $this->callAPISuccess('contact', 'create', array_merge($this->_params
, array(
468 'current_employer' => 'new employer org',
469 'id' => $employerResult['id'],
473 $this->callAPISuccess('contact', 'getcount', array(
474 'organization_name' => 'new employer org',
475 'contact_type' => 'Organization',
479 $result = $this->callAPISuccess('contact', 'getsingle', array(
480 'id' => $employerResult['id'],
483 $this->assertEquals('new employer org', $result['current_employer']);
488 * Test creating a current employer through API.
490 * Check it will re-activate a de-activated employer
492 public function testContactCreateDuplicateCurrentEmployerEnables() {
493 // Set up - create employer relationship.
494 $employerResult = $this->callAPISuccess('contact', 'create', array_merge($this->_params
, array(
495 'current_employer' => 'new employer org',
498 $relationship = $this->callAPISuccess('relationship', 'get', array(
499 'contact_id_a' => $employerResult['id'],
502 //disable & check it is disabled
503 $this->callAPISuccess('relationship', 'create', array('id' => $relationship['id'], 'is_active' => 0));
504 $this->callAPISuccess('relationship', 'getvalue', array(
505 'id' => $relationship['id'],
506 'return' => 'is_active',
509 // Re-set the current employer - thus enabling the relationship.
510 $this->callAPISuccess('contact', 'create', array_merge($this->_params
, array(
511 'current_employer' => 'new employer org',
512 'id' => $employerResult['id'],
515 //check is_active is now 1
516 $relationship = $this->callAPISuccess('relationship', 'getsingle', array(
517 'return' => 'is_active',
519 $this->assertEquals(1, $relationship['is_active']);
523 * Check deceased contacts are not retrieved.
525 * Note at time of writing the default is to return default. This should possibly be changed & test added.
527 public function testGetDeceasedRetrieved() {
528 $this->callAPISuccess($this->_entity
, 'create', $this->_params
);
529 $c2 = $this->callAPISuccess($this->_entity
, 'create', array(
530 'first_name' => 'bb',
531 'last_name' => 'ccc',
532 'contact_type' => 'Individual',
535 $result = $this->callAPISuccess($this->_entity
, 'get', array('is_deceased' => 0));
536 $this->assertFalse(array_key_exists($c2['id'], $result['values']));
540 * Test that sort works - old syntax.
542 public function testGetSort() {
543 $c1 = $this->callAPISuccess($this->_entity
, 'create', $this->_params
);
544 $c2 = $this->callAPISuccess($this->_entity
, 'create', array(
545 'first_name' => 'bb',
546 'last_name' => 'ccc',
547 'contact_type' => 'Individual',
549 $result = $this->callAPISuccess($this->_entity
, 'get', array(
550 'sort' => 'first_name ASC',
551 'return.first_name' => 1,
556 $this->assertEquals('abc1', $result['values'][0]['first_name']);
557 $result = $this->callAPISuccess($this->_entity
, 'get', array(
558 'sort' => 'first_name DESC',
559 'return.first_name' => 1,
563 $this->assertEquals('bb', $result['values'][0]['first_name']);
565 $this->callAPISuccess($this->_entity
, 'delete', array('id' => $c1['id']));
566 $this->callAPISuccess($this->_entity
, 'delete', array('id' => $c2['id']));
570 * Test that we can retrieve contacts using array syntax.
572 * I.e 'id' => array('IN' => array('3,4')).
574 public function testGetINIDArray() {
575 $c1 = $this->callAPISuccess($this->_entity
, 'create', $this->_params
);
576 $c2 = $this->callAPISuccess($this->_entity
, 'create', array(
577 'first_name' => 'bb',
578 'last_name' => 'ccc',
579 'contact_type' => 'Individual',
581 $c3 = $this->callAPISuccess($this->_entity
, 'create', array(
582 'first_name' => 'hh',
584 'contact_type' => 'Individual',
586 $result = $this->callAPISuccess($this->_entity
, 'get', array('id' => array('IN' => array($c1['id'], $c3['id']))));
587 $this->assertEquals(2, $result['count']);
588 $this->assertEquals(array($c1['id'], $c3['id']), array_keys($result['values']));
589 $this->callAPISuccess($this->_entity
, 'delete', array('id' => $c1['id']));
590 $this->callAPISuccess($this->_entity
, 'delete', array('id' => $c2['id']));
591 $this->callAPISuccess($this->_entity
, 'delete', array('id' => $c3['id']));
595 * Test variants on deleted behaviour.
597 public function testGetDeleted() {
598 $params = $this->_params
;
599 $contact1 = $this->callAPISuccess('contact', 'create', $params);
600 $params['is_deleted'] = 1;
601 $params['last_name'] = 'bcd';
602 $contact2 = $this->callAPISuccess('contact', 'create', $params);
603 $countActive = $this->callAPISuccess('contact', 'getcount', array('showAll' => 'active'));
604 $countAll = $this->callAPISuccess('contact', 'getcount', array('showAll' => 'all'));
605 $countTrash = $this->callAPISuccess('contact', 'getcount', array('showAll' => 'trash'));
606 $countDefault = $this->callAPISuccess('contact', 'getcount', array());
607 $countDeleted = $this->callAPISuccess('contact', 'getcount', array(
608 'contact_is_deleted' => 1,
610 $countNotDeleted = $this->callAPISuccess('contact', 'getcount', array(
611 'contact_is_deleted' => 0,
613 $this->callAPISuccess('contact', 'delete', array('id' => $contact1['id']));
614 $this->callAPISuccess('contact', 'delete', array('id' => $contact2['id']));
615 $this->assertEquals(1, $countNotDeleted, 'contact_is_deleted => 0 is respected in line ' . __LINE__
);
616 $this->assertEquals(1, $countActive);
617 $this->assertEquals(1, $countTrash);
618 $this->assertEquals(2, $countAll);
619 $this->assertEquals(1, $countDeleted);
620 $this->assertEquals(1, $countDefault, 'Only active by default in line ' . __LINE__
);
624 * Test that sort works - new syntax.
626 public function testGetSortNewSyntax() {
627 $c1 = $this->callAPISuccess($this->_entity
, 'create', $this->_params
);
628 $c2 = $this->callAPISuccess($this->_entity
, 'create', array(
629 'first_name' => 'bb',
630 'last_name' => 'ccc',
631 'contact_type' => 'Individual',
633 $result = $this->callAPISuccess($this->_entity
, 'getvalue', array(
634 'return' => 'first_name',
637 'sort' => 'first_name',
640 $this->assertEquals('abc1', $result, 'in line' . __LINE__
);
642 $result = $this->callAPISuccess($this->_entity
, 'getvalue', array(
643 'return' => 'first_name',
646 'sort' => 'first_name DESC',
649 $this->assertEquals('bb', $result);
651 $this->callAPISuccess($this->_entity
, 'delete', array('id' => $c1['id']));
652 $this->callAPISuccess($this->_entity
, 'delete', array('id' => $c2['id']));
656 * Test sort and limit for chained relationship get.
658 * https://issues.civicrm.org/jira/browse/CRM-15983
660 public function testSortLimitChainedRelationshipGetCRM15983() {
662 $create_result_1 = $this->callAPISuccess('contact', 'create', array(
663 'first_name' => 'Jules',
664 'last_name' => 'Smos',
665 'contact_type' => 'Individual',
668 // Create another contact with two relationships.
669 $create_params = array(
670 'first_name' => 'Jos',
671 'last_name' => 'Smos',
672 'contact_type' => 'Individual',
673 'api.relationship.create' => array(
675 'contact_id_a' => '$value.id',
676 'contact_id_b' => $create_result_1['id'],
678 'relationship_type_id' => 2,
679 'start_date' => '2005-01-12',
680 'end_date' => '2006-01-11',
681 'description' => 'old',
684 'contact_id_a' => '$value.id',
685 'contact_id_b' => $create_result_1['id'],
686 // spouse of (was married twice :))
687 'relationship_type_id' => 2,
688 'start_date' => '2006-07-01',
689 'end_date' => '2010-07-01',
690 'description' => 'new',
694 $create_result = $this->callAPISuccess('contact', 'create', $create_params);
696 // Try to retrieve the contact and the most recent relationship.
699 'id' => $create_result['id'],
700 'api.relationship.get' => array(
701 'contact_id_a' => '$value.id',
704 'sort' => 'start_date DESC',
707 $get_result = $this->callAPISuccess('contact', 'getsingle', $get_params);
710 $this->callAPISuccess('contact', 'delete', array(
711 'id' => $create_result['id'],
715 $this->assertEquals(1, $get_result['api.relationship.get']['count']);
716 $this->assertEquals('new', $get_result['api.relationship.get']['values'][0]['description']);
720 * Test apostrophe works in get & create.
722 public function testGetApostropheCRM10857() {
723 $params = array_merge($this->_params
, array('last_name' => "O'Connor"));
724 $this->callAPISuccess($this->_entity
, 'create', $params);
725 $result = $this->callAPISuccess($this->_entity
, 'getsingle', array(
726 'last_name' => "O'Connor",
729 $this->assertEquals("O'Connor", $result['last_name'], 'in line' . __LINE__
);
733 * Check with complete array + custom field.
735 * Note that the test is written on purpose without any
736 * variables specific to participant so it can be replicated into other entities
737 * and / or moved to the automated test suite
739 public function testGetWithCustom() {
740 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__
, __FILE__
);
742 $params = $this->_params
;
743 $params['custom_' . $ids['custom_field_id']] = "custom string";
744 $description = "This demonstrates setting a custom field through the API.";
745 $subfile = "CustomFieldGet";
746 $result = $this->callAPISuccess($this->_entity
, 'create', $params);
748 $check = $this->callAPIAndDocument($this->_entity
, 'get', array(
749 'return.custom_' . $ids['custom_field_id'] => 1,
750 'id' => $result['id'],
751 ), __FUNCTION__
, __FILE__
, $description, $subfile);
753 $this->assertEquals("custom string", $check['values'][$check['id']]['custom_' . $ids['custom_field_id']]);
754 $fields = ($this->callAPISuccess('contact', 'getfields', $params));
755 $this->assertTrue(is_array($fields['values']['custom_' . $ids['custom_field_id']]));
756 $this->customFieldDelete($ids['custom_field_id']);
757 $this->customGroupDelete($ids['custom_group_id']);
761 * Check with complete array + custom field.
763 * Note that the test is written on purpose without any
764 * variables specific to participant so it can be replicated into other entities
765 * and / or moved to the automated test suite
767 public function testGetWithCustomReturnSyntax() {
768 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__
, __FILE__
);
770 $params = $this->_params
;
771 $params['custom_' . $ids['custom_field_id']] = "custom string";
772 $description = "This demonstrates setting a custom field through the API.";
773 $subfile = "CustomFieldGetReturnSyntaxVariation";
774 $result = $this->callAPISuccess($this->_entity
, 'create', $params);
775 $params = array('return' => 'custom_' . $ids['custom_field_id'], 'id' => $result['id']);
776 $check = $this->callAPIAndDocument($this->_entity
, 'get', $params, __FUNCTION__
, __FILE__
, $description, $subfile);
778 $this->assertEquals("custom string", $check['values'][$check['id']]['custom_' . $ids['custom_field_id']]);
779 $this->customFieldDelete($ids['custom_field_id']);
780 $this->customGroupDelete($ids['custom_group_id']);
784 * Check that address name is returned if required.
786 public function testGetReturnAddressName() {
787 $contactID = $this->individualCreate();
788 $this->callAPISuccess('address', 'create', array(
789 'contact_id' => $contactID,
790 'address_name' => 'My house',
791 'location_type_id' => 'Home',
792 'street_address' => '1 my road',
794 $result = $this->callAPISuccessGetSingle('contact', array(
795 'return' => 'address_name, street_address',
798 $this->assertEquals('1 my road', $result['street_address']);
799 $this->assertEquals('My house', $result['address_name']);
804 * Test group filter syntaxes.
806 public function testGetGroupIDFromContact() {
807 $groupId = $this->groupCreate();
808 $description = "Get all from group and display contacts.";
809 $subFile = "GroupFilterUsingContactAPI";
811 'email' => 'man2@yahoo.com',
812 'contact_type' => 'Individual',
813 'location_type_id' => 1,
814 'api.group_contact.create' => array('group_id' => $groupId),
817 $this->callAPISuccess('contact', 'create', $params);
818 // testing as integer
820 'filter.group_id' => $groupId,
821 'contact_type' => 'Individual',
823 $result = $this->callAPIAndDocument('contact', 'get', $params, __FUNCTION__
, __FILE__
, $description, $subFile);
824 $this->assertEquals(1, $result['count']);
825 // group 26 doesn't exist, but we can still search contacts in it.
827 'filter.group_id' => 26,
828 'contact_type' => 'Individual',
830 $this->callAPISuccess('contact', 'get', $params);
833 'filter.group_id' => "$groupId, 26",
834 'contact_type' => 'Individual',
836 $result = $this->callAPIAndDocument('contact', 'get', $params, __FUNCTION__
, __FILE__
, $description, $subFile);
837 $this->assertEquals(1, $result['count']);
839 'filter.group_id' => "26,27",
840 'contact_type' => 'Individual',
842 $this->callAPISuccess('contact', 'get', $params);
846 'filter.group_id' => array($groupId, 26),
847 'contact_type' => 'Individual',
849 $result = $this->callAPIAndDocument('contact', 'get', $params, __FUNCTION__
, __FILE__
, $description, $subFile);
850 $this->assertEquals(1, $result['count']);
852 //test in conjunction with other criteria
854 'filter.group_id' => array($groupId, 26),
855 'contact_type' => 'Organization',
857 $this->callAPISuccess('contact', 'get', $params);
859 'filter.group_id' => array(26, 27),
860 'contact_type' => 'Individual',
862 $result = $this->callAPISuccess('contact', 'get', $params);
863 $this->assertEquals(0, $result['count']);
867 * Verify that attempt to create individual contact with two chained websites succeeds.
869 public function testCreateIndividualWithContributionDottedSyntax() {
870 $description = "This demonstrates the syntax to create 2 chained entities.";
871 $subFile = "ChainTwoWebsites";
873 'first_name' => 'abc3',
874 'last_name' => 'xyz3',
875 'contact_type' => 'Individual',
876 'email' => 'man3@yahoo.com',
877 'api.contribution.create' => array(
878 'receive_date' => '2010-01-01',
879 'total_amount' => 100.00,
880 'financial_type_id' => $this->_financialTypeId
,
881 'payment_instrument_id' => 1,
882 'non_deductible_amount' => 10.00,
883 'fee_amount' => 50.00,
884 'net_amount' => 90.00,
886 'invoice_id' => 67990,
888 'contribution_status_id' => 1,
890 'api.website.create' => array(
891 'url' => "http://civicrm.org",
893 'api.website.create.2' => array(
894 'url' => "http://chained.org",
898 $result = $this->callAPIAndDocument('Contact', 'create', $params, __FUNCTION__
, __FILE__
, $description, $subFile);
900 $this->assertEquals(1, $result['id']);
901 // checking child function result not covered in callAPIAndDocument
902 $this->assertAPISuccess($result['values'][$result['id']]['api.website.create']);
903 $this->assertEquals("http://chained.org", $result['values'][$result['id']]['api.website.create.2']['values'][0]['url']);
904 $this->assertEquals("http://civicrm.org", $result['values'][$result['id']]['api.website.create']['values'][0]['url']);
906 // delete the contact
907 $this->callAPISuccess('contact', 'delete', $result);
911 * Verify that attempt to create individual contact with chained contribution and website succeeds.
913 public function testCreateIndividualWithContributionChainedArrays() {
915 'first_name' => 'abc3',
916 'last_name' => 'xyz3',
917 'contact_type' => 'Individual',
918 'email' => 'man3@yahoo.com',
919 'api.contribution.create' => array(
920 'receive_date' => '2010-01-01',
921 'total_amount' => 100.00,
922 'financial_type_id' => $this->_financialTypeId
,
923 'payment_instrument_id' => 1,
924 'non_deductible_amount' => 10.00,
925 'fee_amount' => 50.00,
926 'net_amount' => 90.00,
928 'invoice_id' => 67890,
930 'contribution_status_id' => 1,
932 'api.website.create' => array(
934 'url' => "http://civicrm.org",
937 'url' => "http://chained.org",
938 'website_type_id' => 2,
943 $description = "Demonstrates creating two websites as an array.";
944 $subfile = "ChainTwoWebsitesSyntax2";
945 $result = $this->callAPIAndDocument('Contact', 'create', $params, __FUNCTION__
, __FILE__
, $description, $subfile);
947 $this->assertEquals(1, $result['id']);
948 // the callAndDocument doesn't check the chained call
949 $this->assertEquals(0, $result['values'][$result['id']]['api.website.create'][0]['is_error']);
950 $this->assertEquals("http://chained.org", $result['values'][$result['id']]['api.website.create'][1]['values'][0]['url']);
951 $this->assertEquals("http://civicrm.org", $result['values'][$result['id']]['api.website.create'][0]['values'][0]['url']);
953 $this->callAPISuccess('contact', 'delete', $result);
957 * Test for direction when chaining relationships.
959 * https://issues.civicrm.org/jira/browse/CRM-16084
961 public function testDirectionChainingRelationshipsCRM16084() {
962 // Some contact, called Jules.
963 $create_result_1 = $this->callAPISuccess('contact', 'create', array(
964 'first_name' => 'Jules',
965 'last_name' => 'Smos',
966 'contact_type' => 'Individual',
969 // Another contact: Jos, child of Jules.
970 $create_params = array(
971 'first_name' => 'Jos',
972 'last_name' => 'Smos',
973 'contact_type' => 'Individual',
974 'api.relationship.create' => array(
976 'contact_id_a' => '$value.id',
977 'contact_id_b' => $create_result_1['id'],
979 'relationship_type_id' => 1,
983 $create_result_2 = $this->callAPISuccess('contact', 'create', $create_params);
985 // Mia is the child of Jos.
986 $create_params = array(
987 'first_name' => 'Mia',
988 'last_name' => 'Smos',
989 'contact_type' => 'Individual',
990 'api.relationship.create' => array(
992 'contact_id_a' => '$value.id',
993 'contact_id_b' => $create_result_2['id'],
995 'relationship_type_id' => 1,
999 $create_result_3 = $this->callAPISuccess('contact', 'create', $create_params);
1001 // Get Jos and his children.
1002 $get_params = array(
1004 'id' => $create_result_2['id'],
1005 'api.relationship.get' => array(
1006 'contact_id_b' => '$value.id',
1007 'relationship_type_id' => 1,
1010 $get_result = $this->callAPISuccess('contact', 'getsingle', $get_params);
1013 $this->callAPISuccess('contact', 'delete', array(
1014 'id' => $create_result_1['id'],
1016 $this->callAPISuccess('contact', 'delete', array(
1017 'id' => $create_result_2['id'],
1019 $this->callAPISuccess('contact', 'delete', array(
1020 'id' => $create_result_2['id'],
1024 $this->assertEquals(1, $get_result['api.relationship.get']['count']);
1025 $this->assertEquals($create_result_3['id'], $get_result['api.relationship.get']['values'][0]['contact_id_a']);
1029 * Verify that attempt to create individual contact with first, and last names and email succeeds.
1031 public function testCreateIndividualWithNameEmail() {
1033 'first_name' => 'abc3',
1034 'last_name' => 'xyz3',
1035 'contact_type' => 'Individual',
1036 'email' => 'man3@yahoo.com',
1039 $contact = $this->callAPISuccess('contact', 'create', $params);
1040 $this->assertEquals(1, $contact['id']);
1042 $this->callAPISuccess('contact', 'delete', $contact);
1046 * Verify that attempt to create individual contact with no data fails.
1048 public function testCreateIndividualWithOutNameEmail() {
1050 'contact_type' => 'Individual',
1052 $this->callAPIFailure('contact', 'create', $params);
1056 * Test create individual contact with first &last names, email and location type succeeds.
1058 public function testCreateIndividualWithNameEmailLocationType() {
1060 'first_name' => 'abc4',
1061 'last_name' => 'xyz4',
1062 'email' => 'man4@yahoo.com',
1063 'contact_type' => 'Individual',
1064 'location_type_id' => 1,
1066 $result = $this->callAPISuccess('contact', 'create', $params);
1068 $this->assertEquals(1, $result['id']);
1070 $this->callAPISuccess('contact', 'delete', array('id' => $result['id']));
1074 * Verify that when changing employers the old employer relationship becomes inactive.
1076 public function testCreateIndividualWithEmployer() {
1077 $employer = $this->organizationCreate();
1078 $employer2 = $this->organizationCreate();
1081 'email' => 'man4@yahoo.com',
1082 'contact_type' => 'Individual',
1083 'employer_id' => $employer,
1086 $result = $this->callAPISuccess('contact', 'create', $params);
1087 $relationships = $this->callAPISuccess('relationship', 'get', array(
1088 'contact_id_a' => $result['id'],
1092 $this->assertEquals($employer, $relationships['values'][0]['contact_id_b']);
1094 // Add more random relationships to make the test more realistic
1095 foreach (array('Employee of', 'Volunteer for') as $relationshipType) {
1096 $relTypeId = CRM_Core_DAO
::getFieldValue('CRM_Contact_DAO_RelationshipType', $relationshipType, 'id', 'name_a_b');
1097 $this->callAPISuccess('relationship', 'create', array(
1098 'contact_id_a' => $result['id'],
1099 'contact_id_b' => $this->organizationCreate(),
1101 'relationship_type_id' => $relTypeId,
1105 // Add second employer
1106 $params['employer_id'] = $employer2;
1107 $params['id'] = $result['id'];
1108 $result = $this->callAPISuccess('contact', 'create', $params);
1110 $relationships = $this->callAPISuccess('relationship', 'get', array(
1111 'contact_id_a' => $result['id'],
1116 $this->assertEquals($employer, $relationships['values'][0]['contact_id_b']);
1120 * Verify that attempt to create household contact with details succeeds.
1122 public function testCreateHouseholdDetails() {
1124 'household_name' => 'abc8\'s House',
1125 'nick_name' => 'x House',
1126 'email' => 'man8@yahoo.com',
1127 'contact_type' => 'Household',
1130 $contact = $this->callAPISuccess('contact', 'create', $params);
1132 $this->assertEquals(1, $contact['id']);
1134 $this->callAPISuccess('contact', 'delete', $contact);
1138 * Verify that attempt to create household contact with inadequate details fails.
1140 public function testCreateHouseholdInadequateDetails() {
1142 'nick_name' => 'x House',
1143 'email' => 'man8@yahoo.com',
1144 'contact_type' => 'Household',
1146 $this->callAPIFailure('contact', 'create', $params);
1150 * Verify successful update of individual contact.
1152 public function testUpdateIndividualWithAll() {
1153 // Insert a row in civicrm_contact creating individual contact.
1154 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1155 $op->execute($this->_dbconn
,
1156 $this->createXMLDataSet(
1157 dirname(__FILE__
) . '/dataset/contact_ind.xml'
1163 'first_name' => 'abcd',
1164 'contact_type' => 'Individual',
1165 'nick_name' => 'This is nickname first',
1166 'do_not_email' => '1',
1167 'do_not_phone' => '1',
1168 'do_not_mail' => '1',
1169 'do_not_trade' => '1',
1170 'legal_identifier' => 'ABC23853ZZ2235',
1171 'external_identifier' => '1928837465',
1172 'image_URL' => 'http://some.url.com/image.jpg',
1173 'home_url' => 'http://www.example.org',
1177 $this->callAPISuccess('Contact', 'Update', $params);
1178 $getResult = $this->callAPISuccess('Contact', 'Get', $params);
1179 unset($params['contact_id']);
1180 //Todo - neither API v2 or V3 are testing for home_url - not sure if it is being set.
1181 //reducing this test partially back to api v2 level to get it through
1182 unset($params['home_url']);
1183 foreach ($params as $key => $value) {
1184 $this->assertEquals($value, $getResult['values'][23][$key]);
1186 // Check updated civicrm_contact against expected.
1187 $expected = $this->createXMLDataSet(
1188 dirname(__FILE__
) . '/dataset/contact_ind_upd.xml'
1190 $actual = new PHPUnit_Extensions_Database_DataSet_QueryDataSet(
1193 $actual->addTable('civicrm_contact');
1194 $expected->matches($actual);
1198 * Verify successful update of organization contact.
1200 public function testUpdateOrganizationWithAll() {
1201 // Insert a row in civicrm_contact creating organization contact
1202 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1203 $op->execute($this->_dbconn
,
1204 $this->createXMLDataSet(
1205 dirname(__FILE__
) . '/dataset/contact_org.xml'
1211 'organization_name' => 'WebAccess India Pvt Ltd',
1212 'legal_name' => 'WebAccess',
1213 'sic_code' => 'ABC12DEF',
1214 'contact_type' => 'Organization',
1217 $this->callAPISuccess('Contact', 'Update', $params);
1219 // Check updated civicrm_contact against expected.
1220 $expected = $this->createXMLDataSet(
1221 dirname(__FILE__
) . '/dataset/contact_org_upd.xml'
1223 $actual = new PHPUnit_Extensions_Database_DataSet_QueryDataSet(
1226 $actual->addTable('civicrm_contact');
1227 $expected->matches($actual);
1231 * Verify successful update of household contact.
1233 public function testUpdateHouseholdWithAll() {
1234 // Insert a row in civicrm_contact creating household contact
1235 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1236 $op->execute($this->_dbconn
,
1237 $this->createXMLDataSet(
1238 dirname(__FILE__
) . '/dataset/contact_hld.xml'
1244 'household_name' => 'ABC household',
1245 'nick_name' => 'ABC House',
1246 'contact_type' => 'Household',
1249 $result = $this->callAPISuccess('Contact', 'Update', $params);
1252 'contact_type' => 'Household',
1254 'sort_name' => 'ABC household',
1255 'display_name' => 'ABC household',
1256 'nick_name' => 'ABC House',
1258 $this->getAndCheck($expected, $result['id'], 'contact');
1262 * Test civicrm_update() without contact type.
1264 * Deliberately exclude contact_type as it should still cope using civicrm_api.
1268 public function testUpdateCreateWithID() {
1269 // Insert a row in civicrm_contact creating individual contact.
1270 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1271 $op->execute($this->_dbconn
,
1272 $this->createXMLDataSet(
1273 dirname(__FILE__
) . '/dataset/contact_ind.xml'
1279 'first_name' => 'abcd',
1280 'last_name' => 'wxyz',
1282 $this->callAPISuccess('Contact', 'Update', $params);
1286 * Test civicrm_contact_delete() with no contact ID.
1288 public function testContactDeleteNoID() {
1292 $this->callAPIFailure('contact', 'delete', $params);
1296 * Test civicrm_contact_delete() with error.
1298 public function testContactDeleteError() {
1299 $params = array('contact_id' => 999);
1300 $this->callAPIFailure('contact', 'delete', $params);
1304 * Test civicrm_contact_delete().
1306 public function testContactDelete() {
1307 $contactID = $this->individualCreate();
1311 $this->callAPIAndDocument('contact', 'delete', $params, __FUNCTION__
, __FILE__
);
1315 * Test civicrm_contact_get() return only first name.
1317 public function testContactGetRetFirst() {
1318 $contact = $this->callAPISuccess('contact', 'create', $this->_params
);
1320 'contact_id' => $contact['id'],
1321 'return_first_name' => TRUE,
1322 'sort' => 'first_name',
1324 $result = $this->callAPISuccess('contact', 'get', $params);
1325 $this->assertEquals(1, $result['count']);
1326 $this->assertEquals($contact['id'], $result['id']);
1327 $this->assertEquals('abc1', $result['values'][$contact['id']]['first_name']);
1331 * Test civicrm_contact_get() return only first name & last name.
1333 * Use comma separated string return with a space.
1335 public function testContactGetReturnFirstLast() {
1336 $contact = $this->callAPISuccess('contact', 'create', $this->_params
);
1338 'contact_id' => $contact['id'],
1339 'return' => 'first_name, last_name',
1341 $result = $this->callAPISuccess('contact', 'getsingle', $params);
1342 $this->assertEquals('abc1', $result['first_name']);
1343 $this->assertEquals('xyz1', $result['last_name']);
1344 //check that other defaults not returns
1345 $this->assertArrayNotHasKey('sort_name', $result);
1347 'contact_id' => $contact['id'],
1348 'return' => 'first_name,last_name',
1350 $result = $this->callAPISuccess('contact', 'getsingle', $params);
1351 $this->assertEquals('abc1', $result['first_name']);
1352 $this->assertEquals('xyz1', $result['last_name']);
1353 //check that other defaults not returns
1354 $this->assertArrayNotHasKey('sort_name', $result);
1358 * Test civicrm_contact_get() return only first name & last name.
1360 * Use comma separated string return without a space
1362 public function testContactGetReturnFirstLastNoComma() {
1363 $contact = $this->callAPISuccess('contact', 'create', $this->_params
);
1365 'contact_id' => $contact['id'],
1366 'return' => 'first_name,last_name',
1368 $result = $this->callAPISuccess('contact', 'getsingle', $params);
1369 $this->assertEquals('abc1', $result['first_name']);
1370 $this->assertEquals('xyz1', $result['last_name']);
1371 //check that other defaults not returns
1372 $this->assertArrayNotHasKey('sort_name', $result);
1376 * Test civicrm_contact_get() with default return properties.
1378 public function testContactGetRetDefault() {
1379 $contactID = $this->individualCreate();
1381 'contact_id' => $contactID,
1382 'sort' => 'first_name',
1384 $result = $this->callAPISuccess('contact', 'get', $params);
1385 $this->assertEquals($contactID, $result['values'][$contactID]['contact_id']);
1386 $this->assertEquals('Anthony', $result['values'][$contactID]['first_name']);
1390 * Test civicrm_contact_getquick() with empty name param.
1392 public function testContactGetQuick() {
1393 // Insert a row in civicrm_contact creating individual contact.
1394 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1395 $op->execute($this->_dbconn
,
1396 $this->createXMLDataSet(
1397 dirname(__FILE__
) . '/dataset/contact_17.xml'
1400 $op->execute($this->_dbconn
,
1401 $this->createXMLDataSet(
1402 dirname(__FILE__
) . '/dataset/email_contact_17.xml'
1409 $result = $this->callAPISuccess('contact', 'getquick', $params);
1410 $this->assertEquals(17, $result['values'][0]['id']);
1414 * Test civicrm_contact_get) with empty params.
1416 public function testContactGetEmptyParams() {
1417 $this->callAPISuccess('contact', 'get', array());
1421 * Test civicrm_contact_get(,true) with no matches.
1423 public function testContactGetOldParamsNoMatches() {
1424 // Insert a row in civicrm_contact creating contact 17.
1425 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1426 $op->execute($this->_dbconn
,
1427 $this->createXMLDataSet(
1428 dirname(__FILE__
) . '/dataset/contact_17.xml'
1433 'first_name' => 'Fred',
1435 $result = $this->callAPISuccess('contact', 'get', $params);
1436 $this->assertEquals(0, $result['count']);
1440 * Test civicrm_contact_get(,true) with one match.
1442 public function testContactGetOldParamsOneMatch() {
1443 // Insert a row in civicrm_contact creating contact 17
1444 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1445 $op->execute($this->_dbconn
,
1446 $this->createXMLDataSet(dirname(__FILE__
) . '/dataset/contact_17.xml'
1451 'first_name' => 'Test',
1453 $result = $this->callAPISuccess('contact', 'get', $params);
1454 $this->assertEquals(17, $result['values'][17]['contact_id']);
1455 $this->assertEquals(17, $result['id']);
1459 * Test civicrm_contact_search_count().
1461 public function testContactGetEmail() {
1463 'email' => 'man2@yahoo.com',
1464 'contact_type' => 'Individual',
1465 'location_type_id' => 1,
1468 $contact = $this->callAPISuccess('contact', 'create', $params);
1470 $this->assertEquals(1, $contact['id']);
1473 'email' => 'man2@yahoo.com',
1475 $result = $this->callAPIAndDocument('contact', 'get', $params, __FUNCTION__
, __FILE__
);
1476 $this->assertEquals(1, $result['values'][1]['contact_id']);
1477 $this->assertEquals('man2@yahoo.com', $result['values'][1]['email']);
1479 // delete the contact
1480 $this->callAPISuccess('contact', 'delete', $contact);
1484 * Test birth date parameters.
1486 * These include value, array & birth_date_high, birth_date_low
1489 public function testContactGetBirthDate() {
1490 $contact1 = $this->callAPISuccess('contact', 'create', array_merge($this->_params
, array('birth_date' => 'first day of next month - 2 years')));
1491 $contact2 = $this->callAPISuccess('contact', 'create', array_merge($this->_params
, array('birth_date' => 'first day of next month - 5 years')));
1492 $contact3 = $this->callAPISuccess('contact', 'create', array_merge($this->_params
, array('birth_date' => 'first day of next month -20 years')));
1494 $result = $this->callAPISuccess('contact', 'get', array());
1495 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -2 years')), $result['values'][$contact1['id']]['birth_date']);
1496 $result = $this->callAPISuccess('contact', 'get', array('birth_date' => 'first day of next month -5 years'));
1497 $this->assertEquals(1, $result['count']);
1498 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -5 years')), $result['values'][$contact2['id']]['birth_date']);
1499 $result = $this->callAPISuccess('contact', 'get', array('birth_date_high' => date('Y-m-d', strtotime('-6 years'))));
1500 $this->assertEquals(1, $result['count']);
1501 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -20 years')), $result['values'][$contact3['id']]['birth_date']);
1502 $result = $this->callAPISuccess('contact', 'get', array(
1503 'birth_date_low' => date('Y-m-d', strtotime('-6 years')),
1504 'birth_date_high' => date('Y-m-d', strtotime('- 3 years')),
1506 $this->assertEquals(1, $result['count']);
1507 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -5 years')), $result['values'][$contact2['id']]['birth_date']);
1508 $result = $this->callAPISuccess('contact', 'get', array(
1509 'birth_date_low' => '-6 years',
1510 'birth_date_high' => '- 3 years',
1512 $this->assertEquals(1, $result['count']);
1513 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -5 years')), $result['values'][$contact2['id']]['birth_date']);
1517 * Test Deceased date parameters.
1519 * These include value, array & Deceased_date_high, Deceased date_low
1522 public function testContactGetDeceasedDate() {
1523 $contact1 = $this->callAPISuccess('contact', 'create', array_merge($this->_params
, array('deceased_date' => 'first day of next month - 2 years')));
1524 $contact2 = $this->callAPISuccess('contact', 'create', array_merge($this->_params
, array('deceased_date' => 'first day of next month - 5 years')));
1525 $contact3 = $this->callAPISuccess('contact', 'create', array_merge($this->_params
, array('deceased_date' => 'first day of next month -20 years')));
1527 $result = $this->callAPISuccess('contact', 'get', array());
1528 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -2 years')), $result['values'][$contact1['id']]['deceased_date']);
1529 $result = $this->callAPISuccess('contact', 'get', array('deceased_date' => 'first day of next month -5 years'));
1530 $this->assertEquals(1, $result['count']);
1531 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -5 years')), $result['values'][$contact2['id']]['deceased_date']);
1532 $result = $this->callAPISuccess('contact', 'get', array('deceased_date_high' => date('Y-m-d', strtotime('-6 years'))));
1533 $this->assertEquals(1, $result['count']);
1534 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -20 years')), $result['values'][$contact3['id']]['deceased_date']);
1535 $result = $this->callAPISuccess('contact', 'get', array(
1536 'deceased_date_low' => '-6 years',
1537 'deceased_date_high' => date('Y-m-d', strtotime('- 3 years')),
1539 $this->assertEquals(1, $result['count']);
1540 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -5 years')), $result['values'][$contact2['id']]['deceased_date']);
1544 * Test for Contact.get id=@user:username.
1546 public function testContactGetByUsername() {
1547 // Setup - create contact with a uf-match.
1548 $cid = $this->individualCreate(array(
1549 'contact_type' => 'Individual',
1550 'first_name' => 'testGetByUsername',
1551 'last_name' => 'testGetByUsername',
1554 $ufMatchParams = array(
1555 'domain_id' => CRM_Core_Config
::domainID(),
1557 'uf_name' => 'the-email-matching-key-is-not-really-the-username',
1558 'contact_id' => $cid,
1560 $ufMatch = CRM_Core_BAO_UFMatch
::create($ufMatchParams);
1561 $this->assertTrue(is_numeric($ufMatch->id
));
1563 // setup - mock the calls to CRM_Utils_System_*::getUfId
1564 $userSystem = $this->getMock('CRM_Utils_System_UnitTests', array('getUfId'));
1565 $userSystem->expects($this->once())
1567 ->with($this->equalTo('exampleUser'))
1568 ->will($this->returnValue(99));
1569 CRM_Core_Config
::singleton()->userSystem
= $userSystem;
1572 $result = $this->callAPISuccess('Contact', 'get', array(
1573 'id' => '@user:exampleUser',
1575 $this->assertEquals('testGetByUsername', $result['values'][$cid]['first_name']);
1579 * Test to check return works OK.
1581 public function testContactGetReturnValues() {
1582 $extraParams = array(
1583 'nick_name' => 'Bob',
1585 'email' => 'e@mail.com',
1587 $contactID = $this->individualCreate($extraParams);
1588 //actually it turns out the above doesn't create a phone
1589 $this->callAPISuccess('phone', 'create', array('contact_id' => $contactID, 'phone' => '456'));
1590 $result = $this->callAPISuccess('contact', 'getsingle', array('id' => $contactID));
1591 foreach ($extraParams as $key => $value) {
1592 $this->assertEquals($result[$key], $value);
1594 //now we check they are still returned with 'return' key
1595 $result = $this->callAPISuccess('contact', 'getsingle', array(
1597 'return' => array_keys($extraParams),
1599 foreach ($extraParams as $key => $value) {
1600 $this->assertEquals($result[$key], $value);
1605 * Test creating multiple phones using chaining.
1607 * @throws \Exception
1609 public function testCRM13252MultipleChainedPhones() {
1610 $contactID = $this->householdCreate();
1611 $this->callAPISuccessGetCount('phone', array('contact_id' => $contactID), 0);
1613 'contact_id' => $contactID,
1614 'household_name' => 'Household 1',
1615 'contact_type' => 'Household',
1616 'api.phone.create' => array(
1618 'phone' => '111-111-1111',
1619 'location_type_id' => 1,
1620 'phone_type_id' => 1,
1623 'phone' => '222-222-2222',
1624 'location_type_id' => 1,
1625 'phone_type_id' => 2,
1629 $this->callAPISuccess('contact', 'create', $params);
1630 $this->callAPISuccessGetCount('phone', array('contact_id' => $contactID), 2);
1635 * Test for Contact.get id=@user:username (with an invalid username).
1637 public function testContactGetByUnknownUsername() {
1638 // setup - mock the calls to CRM_Utils_System_*::getUfId
1639 $userSystem = $this->getMock('CRM_Utils_System_UnitTests', array('getUfId'));
1640 $userSystem->expects($this->once())
1642 ->with($this->equalTo('exampleUser'))
1643 ->will($this->returnValue(NULL));
1644 CRM_Core_Config
::singleton()->userSystem
= $userSystem;
1647 $result = $this->callAPIFailure('Contact', 'get', array(
1648 'id' => '@user:exampleUser',
1650 $this->assertRegExp('/cannot be resolved to a contact ID/', $result['error_message']);
1654 * Verify attempt to create individual with chained arrays and sequential.
1656 public function testGetIndividualWithChainedArraysAndSequential() {
1657 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__
, __FILE__
);
1658 $params['custom_' . $ids['custom_field_id']] = "custom string";
1660 $moreIDs = $this->CustomGroupMultipleCreateWithFields();
1664 'first_name' => 'abc3',
1665 'last_name' => 'xyz3',
1666 'contact_type' => 'Individual',
1667 'email' => 'man3@yahoo.com',
1668 'api.website.create' => array(
1670 'url' => "http://civicrm.org",
1673 'url' => "https://civicrm.org",
1678 $result = $this->callAPISuccess('Contact', 'create', $params);
1680 // delete the contact and custom groups
1681 $this->callAPISuccess('contact', 'delete', array('id' => $result['id']));
1682 $this->customGroupDelete($ids['custom_group_id']);
1683 $this->customGroupDelete($moreIDs['custom_group_id']);
1685 $this->assertEquals($result['id'], $result['values'][0]['id']);
1686 $this->assertArrayKeyExists('api.website.create', $result['values'][0]);
1690 * Verify attempt to create individual with chained arrays.
1692 public function testGetIndividualWithChainedArrays() {
1693 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__
, __FILE__
);
1694 $params['custom_' . $ids['custom_field_id']] = "custom string";
1696 $moreIDs = $this->CustomGroupMultipleCreateWithFields();
1697 $description = "This demonstrates the usage of chained api functions.\nIn this case no notes or custom fields have been created.";
1698 $subfile = "APIChainedArray";
1700 'first_name' => 'abc3',
1701 'last_name' => 'xyz3',
1702 'contact_type' => 'Individual',
1703 'email' => 'man3@yahoo.com',
1704 'api.contribution.create' => array(
1705 'receive_date' => '2010-01-01',
1706 'total_amount' => 100.00,
1707 'financial_type_id' => 1,
1708 'payment_instrument_id' => 1,
1709 'non_deductible_amount' => 10.00,
1710 'fee_amount' => 50.00,
1711 'net_amount' => 90.00,
1713 'invoice_id' => 67890,
1715 'contribution_status_id' => 1,
1717 'api.contribution.create.1' => array(
1718 'receive_date' => '2011-01-01',
1719 'total_amount' => 120.00,
1720 'financial_type_id' => $this->_financialTypeId
= 1,
1721 'payment_instrument_id' => 1,
1722 'non_deductible_amount' => 10.00,
1723 'fee_amount' => 50.00,
1724 'net_amount' => 90.00,
1726 'invoice_id' => 67830,
1728 'contribution_status_id' => 1,
1730 'api.website.create' => array(
1732 'url' => "http://civicrm.org",
1737 $result = $this->callAPISuccess('Contact', 'create', $params);
1739 'id' => $result['id'],
1740 'api.website.get' => array(),
1741 'api.Contribution.get' => array(
1742 'total_amount' => '120.00',
1744 'api.CustomValue.get' => 1,
1745 'api.Note.get' => 1,
1747 $result = $this->callAPIAndDocument('Contact', 'Get', $params, __FUNCTION__
, __FILE__
, $description, $subfile);
1748 // delete the contact
1749 $this->callAPISuccess('contact', 'delete', $result);
1750 $this->customGroupDelete($ids['custom_group_id']);
1751 $this->customGroupDelete($moreIDs['custom_group_id']);
1752 $this->assertEquals(1, $result['id']);
1753 $this->assertEquals(0, $result['values'][$result['id']]['api.website.get']['is_error']);
1754 $this->assertEquals("http://civicrm.org", $result['values'][$result['id']]['api.website.get']['values'][0]['url']);
1758 * Verify attempt to create individual with chained arrays and sequential.
1760 * See https://issues.civicrm.org/jira/browse/CRM-15815
1762 public function testCreateIndividualWithChainedArrayAndSequential() {
1765 'first_name' => 'abc5',
1766 'last_name' => 'xyz5',
1767 'contact_type' => 'Individual',
1768 'email' => 'woman5@yahoo.com',
1769 'api.phone.create' => array(
1770 array('phone' => '03-231 07 95'),
1771 array('phone' => '03-232 51 62'),
1773 'api.website.create' => array(
1774 'url' => 'http://civicrm.org',
1777 $result = $this->callAPISuccess('Contact', 'create', $params);
1779 // I could try to parse the result to see whether the two phone numbers
1780 // and the website are there, but I am not sure about the correct format.
1781 // So I will just fetch it again before checking.
1782 // See also http://forum.civicrm.org/index.php/topic,35393.0.html
1785 'id' => $result['id'],
1786 'api.website.get' => array(),
1787 'api.phone.get' => array(),
1789 $result = $this->callAPISuccess('Contact', 'get', $params);
1791 // delete the contact
1792 $this->callAPISuccess('contact', 'delete', $result);
1794 $this->assertEquals(2, $result['values'][0]['api.phone.get']['count']);
1795 $this->assertEquals(1, $result['values'][0]['api.website.get']['count']);
1799 * Test retrieving an individual with chained array syntax.
1801 public function testGetIndividualWithChainedArraysFormats() {
1802 $description = "This demonstrates the usage of chained api functions.\nIn this case no notes or custom fields have been created.";
1803 $subfile = "APIChainedArrayFormats";
1804 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__
, __FILE__
);
1805 $params['custom_' . $ids['custom_field_id']] = "custom string";
1807 $moreIDs = $this->CustomGroupMultipleCreateWithFields();
1809 'first_name' => 'abc3',
1810 'last_name' => 'xyz3',
1811 'contact_type' => 'Individual',
1812 'email' => 'man3@yahoo.com',
1813 'api.contribution.create' => array(
1814 'receive_date' => '2010-01-01',
1815 'total_amount' => 100.00,
1816 'financial_type_id' => $this->_financialTypeId
,
1817 'payment_instrument_id' => 1,
1818 'non_deductible_amount' => 10.00,
1819 'fee_amount' => 50.00,
1820 'net_amount' => 90.00,
1822 'contribution_status_id' => 1,
1824 'api.contribution.create.1' => array(
1825 'receive_date' => '2011-01-01',
1826 'total_amount' => 120.00,
1827 'financial_type_id' => $this->_financialTypeId
,
1828 'payment_instrument_id' => 1,
1829 'non_deductible_amount' => 10.00,
1830 'fee_amount' => 50.00,
1831 'net_amount' => 90.00,
1833 'contribution_status_id' => 1,
1835 'api.website.create' => array(
1837 'url' => "http://civicrm.org",
1842 $result = $this->callAPISuccess('Contact', 'create', $params);
1844 'id' => $result['id'],
1845 'api.website.getValue' => array('return' => 'url'),
1846 'api.Contribution.getCount' => array(),
1847 'api.CustomValue.get' => 1,
1848 'api.Note.get' => 1,
1849 'api.Membership.getCount' => array(),
1851 $result = $this->callAPIAndDocument('Contact', 'Get', $params, __FUNCTION__
, __FILE__
, $description, $subfile);
1852 $this->assertEquals(1, $result['id']);
1853 $this->assertEquals(2, $result['values'][$result['id']]['api.Contribution.getCount']);
1854 $this->assertEquals(0, $result['values'][$result['id']]['api.Note.get']['is_error']);
1855 $this->assertEquals("http://civicrm.org", $result['values'][$result['id']]['api.website.getValue']);
1857 $this->callAPISuccess('contact', 'delete', $result);
1858 $this->customGroupDelete($ids['custom_group_id']);
1859 $this->customGroupDelete($moreIDs['custom_group_id']);
1863 * Test complex chaining.
1865 public function testGetIndividualWithChainedArraysAndMultipleCustom() {
1866 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__
, __FILE__
);
1867 $params['custom_' . $ids['custom_field_id']] = "custom string";
1868 $moreIDs = $this->CustomGroupMultipleCreateWithFields();
1869 $andMoreIDs = $this->CustomGroupMultipleCreateWithFields(array(
1870 'title' => "another group",
1871 'name' => 'another name',
1873 $description = "This demonstrates the usage of chained api functions with multiple custom fields.";
1874 $subfile = "APIChainedArrayMultipleCustom";
1876 'first_name' => 'abc3',
1877 'last_name' => 'xyz3',
1878 'contact_type' => 'Individual',
1879 'email' => 'man3@yahoo.com',
1880 'api.contribution.create' => array(
1881 'receive_date' => '2010-01-01',
1882 'total_amount' => 100.00,
1883 'financial_type_id' => 1,
1884 'payment_instrument_id' => 1,
1885 'non_deductible_amount' => 10.00,
1886 'fee_amount' => 50.00,
1887 'net_amount' => 90.00,
1889 'invoice_id' => 67890,
1891 'contribution_status_id' => 1,
1893 'api.contribution.create.1' => array(
1894 'receive_date' => '2011-01-01',
1895 'total_amount' => 120.00,
1896 'financial_type_id' => 1,
1897 'payment_instrument_id' => 1,
1898 'non_deductible_amount' => 10.00,
1899 'fee_amount' => 50.00,
1900 'net_amount' => 90.00,
1902 'invoice_id' => 67830,
1904 'contribution_status_id' => 1,
1906 'api.website.create' => array(
1908 'url' => "http://civicrm.org",
1911 'custom_' . $ids['custom_field_id'] => "value 1",
1912 'custom_' . $moreIDs['custom_field_id'][0] => "value 2",
1913 'custom_' . $moreIDs['custom_field_id'][1] => "warm beer",
1914 'custom_' . $andMoreIDs['custom_field_id'][1] => "vegemite",
1917 $result = $this->callAPISuccess('Contact', 'create', $params);
1918 $result = $this->callAPISuccess('Contact', 'create', array(
1919 'contact_type' => 'Individual',
1920 'id' => $result['id'],
1922 $moreIDs['custom_field_id'][0] => "value 3",
1924 $ids['custom_field_id'] => "value 4",
1928 'id' => $result['id'],
1929 'api.website.getValue' => array('return' => 'url'),
1930 'api.Contribution.getCount' => array(),
1931 'api.CustomValue.get' => 1,
1933 $result = $this->callAPIAndDocument('Contact', 'Get', $params, __FUNCTION__
, __FILE__
, $description, $subfile);
1935 $this->customGroupDelete($ids['custom_group_id']);
1936 $this->customGroupDelete($moreIDs['custom_group_id']);
1937 $this->customGroupDelete($andMoreIDs['custom_group_id']);
1938 $this->assertEquals(1, $result['id']);
1939 $this->assertEquals(0, $result['values'][$result['id']]['api.CustomValue.get']['is_error']);
1940 $this->assertEquals('http://civicrm.org', $result['values'][$result['id']]['api.website.getValue']);
1944 * Test checks usage of $values to pick & choose inputs.
1946 public function testChainingValuesCreate() {
1947 $description = "This demonstrates the usage of chained api functions. Specifically it has one 'parent function' &
1948 2 child functions - one receives values from the parent (Contact) and the other child (Tag).";
1949 $subfile = "APIChainedArrayValuesFromSiblingFunction";
1951 'display_name' => 'batman',
1952 'contact_type' => 'Individual',
1953 'api.tag.create' => array(
1954 'name' => '$value.id',
1955 'description' => '$value.display_name',
1956 'format.only_id' => 1,
1958 'api.entity_tag.create' => array('tag_id' => '$value.api.tag.create'),
1960 $result = $this->callAPIAndDocument('Contact', 'Create', $params, __FUNCTION__
, __FILE__
, $description, $subfile);
1961 $this->assertEquals(0, $result['values'][$result['id']]['api.entity_tag.create']['is_error']);
1963 $tablesToTruncate = array(
1966 'civicrm_entity_tag',
1969 $this->quickCleanup($tablesToTruncate, TRUE);
1973 * Test TrueFalse format - I couldn't come up with an easy way to get an error on Get.
1975 public function testContactGetFormatIsSuccessTrue() {
1976 $this->createContactFromXML();
1977 $description = "This demonstrates use of the 'format.is_success' param.
1978 This param causes only the success or otherwise of the function to be returned as BOOLEAN";
1979 $subfile = "FormatIsSuccess_True";
1980 $params = array('id' => 17, 'format.is_success' => 1);
1981 $result = $this->callAPIAndDocument('Contact', 'Get', $params, __FUNCTION__
, __FILE__
, $description, $subfile);
1982 $this->assertEquals(1, $result);
1983 $this->callAPISuccess('Contact', 'Delete', $params);
1987 * Test TrueFalse format.
1989 public function testContactCreateFormatIsSuccessFalse() {
1991 $description = "This demonstrates use of the 'format.is_success' param.
1992 This param causes only the success or otherwise of the function to be returned as BOOLEAN";
1993 $subfile = "FormatIsSuccess_Fail";
1994 $params = array('id' => 500, 'format.is_success' => 1);
1995 $result = $this->callAPIAndDocument('Contact', 'Create', $params, __FUNCTION__
, __FILE__
, $description, $subfile);
1996 $this->assertEquals(0, $result);
2000 * Test Single Entity format.
2002 public function testContactGetSingleEntityArray() {
2003 $this->createContactFromXML();
2004 $description = "This demonstrates use of the 'format.single_entity_array' param.
2005 This param causes the only contact to be returned as an array without the other levels.
2006 It will be ignored if there is not exactly 1 result";
2007 $subfile = "GetSingleContact";
2008 $params = array('id' => 17);
2009 $result = $this->callAPIAndDocument('Contact', 'GetSingle', $params, __FUNCTION__
, __FILE__
, $description, $subfile);
2010 $this->assertEquals('Test Contact', $result['display_name']);
2011 $this->callAPISuccess('Contact', 'Delete', $params);
2015 * Test Single Entity format.
2017 public function testContactGetFormatCountOnly() {
2018 $this->createContactFromXML();
2019 $description = "This demonstrates use of the 'getCount' action.
2020 This param causes the count of the only function to be returned as an integer.";
2021 $subfile = "GetCountContact";
2022 $params = array('id' => 17);
2023 $result = $this->callAPIAndDocument('Contact', 'GetCount', $params, __FUNCTION__
, __FILE__
, $description,
2025 $this->assertEquals('1', $result);
2026 $this->callAPISuccess('Contact', 'Delete', $params);
2030 * Test id only format.
2032 public function testContactGetFormatIDOnly() {
2033 $this->createContactFromXML();
2034 $description = "This demonstrates use of the 'format.id_only' param.
2035 This param causes the id of the only entity to be returned as an integer.
2036 It will be ignored if there is not exactly 1 result";
2037 $subfile = "FormatOnlyID";
2038 $params = array('id' => 17, 'format.only_id' => 1);
2039 $result = $this->callAPIAndDocument('Contact', 'Get', $params, __FUNCTION__
, __FILE__
, $description, $subfile);
2040 $this->assertEquals('17', $result);
2041 $this->callAPISuccess('Contact', 'Delete', $params);
2045 * Test id only format.
2047 public function testContactGetFormatSingleValue() {
2048 $this->createContactFromXML();
2049 $description = "This demonstrates use of the 'format.single_value' param.
2050 This param causes only a single value of the only entity to be returned as an string.
2051 It will be ignored if there is not exactly 1 result";
2052 $subFile = "FormatSingleValue";
2053 $params = array('id' => 17, 'return' => 'display_name');
2054 $result = $this->callAPIAndDocument('Contact', 'getvalue', $params, __FUNCTION__
, __FILE__
, $description, $subFile);
2055 $this->assertEquals('Test Contact', $result);
2056 $this->callAPISuccess('Contact', 'Delete', $params);
2060 * Test that permissions are respected when creating contacts.
2062 public function testContactCreationPermissions() {
2064 'contact_type' => 'Individual',
2065 'first_name' => 'Foo',
2066 'last_name' => 'Bear',
2067 'check_permissions' => TRUE,
2069 $config = CRM_Core_Config
::singleton();
2070 $config->userPermissionClass
->permissions
= array('access CiviCRM');
2071 $result = $this->callAPIFailure('contact', 'create', $params);
2072 $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');
2074 $config->userPermissionClass
->permissions
= array('access CiviCRM', 'add contacts', 'import contacts');
2075 $this->callAPISuccess('contact', 'create', $params);
2079 * Test update with check permissions set.
2081 public function testContactUpdatePermissions() {
2083 'contact_type' => 'Individual',
2084 'first_name' => 'Foo',
2085 'last_name' => 'Bear',
2086 'check_permissions' => TRUE,
2088 $result = $this->callAPISuccess('contact', 'create', $params);
2089 $config = CRM_Core_Config
::singleton();
2091 'id' => $result['id'],
2092 'contact_type' => 'Individual',
2093 'last_name' => 'Bar',
2094 'check_permissions' => TRUE,
2097 $config->userPermissionClass
->permissions
= array('access CiviCRM');
2098 $result = $this->callAPIFailure('contact', 'update', $params);
2099 $this->assertEquals('API permission check failed for Contact/update call; insufficient permission: require access CiviCRM and edit all contacts', $result['error_message'], 'lacking permissions should not be enough to update a contact');
2101 $config->userPermissionClass
->permissions
= array(
2104 'view all contacts',
2105 'edit all contacts',
2108 $this->callAPISuccess('contact', 'update', $params);
2112 * Set up helper to create a contact.
2114 public function createContactFromXML() {
2115 // Insert a row in civicrm_contact creating contact 17.
2116 $op = new PHPUnit_Extensions_Database_Operation_Insert();
2117 $op->execute($this->_dbconn
,
2118 $this->createXMLDataSet(
2119 dirname(__FILE__
) . '/dataset/contact_17.xml'
2125 * Test contact proximity api.
2127 public function testContactProximity() {
2128 // first create a contact with a SF location with a specific
2130 $contactID = $this->organizationCreate();
2132 // now create the address
2134 'street_address' => '123 Main Street',
2135 'city' => 'San Francisco',
2137 'country_id' => 1228,
2138 'state_province_id' => 1004,
2139 'geo_code_1' => '37.79',
2140 'geo_code_2' => '-122.40',
2141 'location_type_id' => 1,
2142 'contact_id' => $contactID,
2145 $result = $this->callAPISuccess('address', 'create', $params);
2146 $this->assertEquals(1, $result['count'], 'In line ' . __LINE__
);
2148 // now do a proximity search with a close enough geocode and hope to match
2149 // that specific contact only!
2150 $proxParams = array(
2152 'longitude' => -122.3,
2156 $result = $this->callAPISuccess('contact', 'proximity', $proxParams);
2157 $this->assertEquals(1, $result['count'], 'In line ' . __LINE__
);
2161 * Test that Ajax API permission is sufficient to access getquick api.
2163 * (note that getquick api is required for autocomplete & has ACL permissions applied)
2165 public function testGetquickPermissionCRM13744() {
2166 CRM_Core_Config
::singleton()->userPermissionClass
->permissions
= array('access CiviEvent');
2167 $this->callAPIFailure('contact', 'getquick', array('name' => 'b', 'check_permissions' => TRUE));
2168 CRM_Core_Config
::singleton()->userPermissionClass
->permissions
= array('access CiviCRM');
2169 $this->callAPISuccess('contact', 'getquick', array('name' => 'b', 'check_permissions' => TRUE));
2170 CRM_Core_Config
::singleton()->userPermissionClass
->permissions
= array('access AJAX API');
2171 $this->callAPISuccess('contact', 'getquick', array('name' => 'b', 'check_permissions' => TRUE));
2175 * Test get ref api - gets a list of references to an entity.
2177 public function testGetReferenceCounts() {
2178 $result = $this->callAPISuccess('Contact', 'create', array(
2179 'first_name' => 'Testily',
2180 'last_name' => 'McHaste',
2181 'contact_type' => 'Individual',
2182 'api.Address.replace' => array(
2183 'values' => array(),
2185 'api.Email.replace' => array(
2188 'email' => 'spam@dev.null',
2190 'location_type_id' => 1,
2194 'api.Phone.replace' => array(
2197 'phone' => '234-567-0001',
2199 'location_type_id' => 1,
2202 'phone' => '234-567-0002',
2204 'location_type_id' => 1,
2210 //$dao = new CRM_Contact_BAO_Contact();
2211 //$dao->id = $result['id'];
2212 //$this->assertTrue((bool) $dao->find(TRUE));
2214 //$refCounts = $dao->getReferenceCounts();
2215 //$this->assertTrue(is_array($refCounts));
2216 //$refCountsIdx = CRM_Utils_Array::index(array('name'), $refCounts);
2218 $refCounts = $this->callAPISuccess('Contact', 'getrefcount', array(
2219 'id' => $result['id'],
2221 $refCountsIdx = CRM_Utils_Array
::index(array('name'), $refCounts['values']);
2223 $this->assertEquals(1, $refCountsIdx['sql:civicrm_email:contact_id']['count']);
2224 $this->assertEquals('civicrm_email', $refCountsIdx['sql:civicrm_email:contact_id']['table']);
2225 $this->assertEquals(2, $refCountsIdx['sql:civicrm_phone:contact_id']['count']);
2226 $this->assertEquals('civicrm_phone', $refCountsIdx['sql:civicrm_phone:contact_id']['table']);
2227 $this->assertTrue(!isset($refCountsIdx['sql:civicrm_address:contact_id']));
2231 * Test the use of sql operators.
2233 public function testSQLOperatorsOnContactAPI() {
2234 $this->individualCreate();
2235 $this->organizationCreate();
2236 $this->householdCreate();
2237 $contacts = $this->callAPISuccess('contact', 'get', array('legal_name' => array('IS NOT NULL' => TRUE)));
2238 $this->assertEquals($contacts['count'], CRM_Core_DAO
::singleValueQuery('select count(*) FROM civicrm_contact WHERE legal_name IS NOT NULL'));
2239 $contacts = $this->callAPISuccess('contact', 'get', array('legal_name' => array('IS NULL' => TRUE)));
2240 $this->assertEquals($contacts['count'], CRM_Core_DAO
::singleValueQuery('select count(*) FROM civicrm_contact WHERE legal_name IS NULL'));
2244 * CRM-14743 - test api respects search operators.
2246 public function testGetModifiedDateByOperators() {
2247 $preExistingContactCount = CRM_Core_DAO
::singleValueQuery('select count(*) FROM civicrm_contact');
2248 $contact1 = $this->individualCreate();
2249 $sql = "UPDATE civicrm_contact SET created_date = '2012-01-01', modified_date = '2013-01-01' WHERE id = " . $contact1;
2250 CRM_Core_DAO
::executeQuery($sql);
2251 $contact2 = $this->individualCreate();
2252 $sql = "UPDATE civicrm_contact SET created_date = '2012-02-01', modified_date = '2013-02-01' WHERE id = " . $contact2;
2253 CRM_Core_DAO
::executeQuery($sql);
2254 $contact3 = $this->householdCreate();
2255 $sql = "UPDATE civicrm_contact SET created_date = '2012-03-01', modified_date = '2013-03-01' WHERE id = " . $contact3;
2256 CRM_Core_DAO
::executeQuery($sql);
2257 $contacts = $this->callAPISuccess('contact', 'get', array('modified_date' => array('<' => '2014-01-01')));
2258 $this->assertEquals($contacts['count'], 3);
2259 $contacts = $this->callAPISuccess('contact', 'get', array('modified_date' => array('>' => '2014-01-01')));
2260 $this->assertEquals($contacts['count'], $preExistingContactCount);
2264 * CRM-14743 - test api respects search operators.
2266 public function testGetCreatedDateByOperators() {
2267 $preExistingContactCount = CRM_Core_DAO
::singleValueQuery('select count(*) FROM civicrm_contact');
2268 $contact1 = $this->individualCreate();
2269 $sql = "UPDATE civicrm_contact SET created_date = '2012-01-01' WHERE id = " . $contact1;
2270 CRM_Core_DAO
::executeQuery($sql);
2271 $contact2 = $this->individualCreate();
2272 $sql = "UPDATE civicrm_contact SET created_date = '2012-02-01' WHERE id = " . $contact2;
2273 CRM_Core_DAO
::executeQuery($sql);
2274 $contact3 = $this->householdCreate();
2275 $sql = "UPDATE civicrm_contact SET created_date = '2012-03-01' WHERE id = " . $contact3;
2276 CRM_Core_DAO
::executeQuery($sql);
2277 $contacts = $this->callAPISuccess('contact', 'get', array('created_date' => array('<' => '2014-01-01')));
2278 $this->assertEquals($contacts['count'], 3);
2279 $contacts = $this->callAPISuccess('contact', 'get', array('created_date' => array('>' => '2014-01-01')));
2280 $this->assertEquals($contacts['count'], $preExistingContactCount);
2284 * CRM-14263 check that API is not affected by search profile related bug.
2286 public function testReturnCityProfile() {
2287 $contactID = $this->individualCreate();
2288 CRM_Core_Config
::singleton()->defaultSearchProfileID
= 1;
2289 $this->callAPISuccess('address', 'create', array(
2290 'contact_id' => $contactID,
2291 'city' => 'Cool City',
2292 'location_type_id' => 1,
2294 $result = $this->callAPISuccess('contact', 'get', array('city' => 'Cool City', 'return' => 'contact_type'));
2295 $this->assertEquals(1, $result['count']);
2299 * CRM-15443 - ensure getlist api does not return deleted contacts.
2301 public function testGetlistExcludeConditions() {
2302 $name = md5(time());
2303 $contact = $this->individualCreate(array('last_name' => $name));
2304 $this->individualCreate(array('last_name' => $name, 'is_deceased' => 1));
2305 $this->individualCreate(array('last_name' => $name, 'is_deleted' => 1));
2306 // We should get all but the deleted contact.
2307 $result = $this->callAPISuccess('contact', 'getlist', array('input' => $name));
2308 $this->assertEquals(2, $result['count'], 'In line ' . __LINE__
);
2309 // Force-exclude the deceased contact.
2310 $result = $this->callAPISuccess('contact', 'getlist', array(
2312 'params' => array('is_deceased' => 0),
2314 $this->assertEquals(1, $result['count'], 'In line ' . __LINE__
);
2315 $this->assertEquals($contact, $result['values'][0]['id'], 'In line ' . __LINE__
);
2319 * Test contact getactions.
2321 public function testGetActions() {
2322 $description = "Getting the available actions for an entity.";
2323 $result = $this->callAPIAndDocument($this->_entity
, 'getactions', array(), __FUNCTION__
, __FILE__
, $description);
2343 $deprecated = array(
2347 foreach ($expected as $action) {
2348 $this->assertTrue(in_array($action, $result['values']), "Expected action $action");
2350 foreach ($deprecated as $action) {
2351 $this->assertArrayKeyExists($action, $result['deprecated']);
2356 * Test the duplicate check function.
2358 public function testDuplicateCheck() {
2359 $this->callAPISuccess('Contact', 'create', array(
2360 'first_name' => 'Harry',
2361 'last_name' => 'Potter',
2362 'email' => 'harry@hogwarts.edu',
2363 'contact_type' => 'Individual',
2365 $result = $this->callAPISuccess('Contact', 'duplicatecheck', array(
2367 'first_name' => 'Harry',
2368 'last_name' => 'Potter',
2369 'email' => 'harry@hogwarts.edu',
2370 'contact_type' => 'Individual',
2374 $this->assertEquals(1, $result['count']);
2375 $result = $this->callAPISuccess('Contact', 'duplicatecheck', array(
2377 'first_name' => 'Harry',
2378 'last_name' => 'Potter',
2379 'email' => 'no5@privet.drive',
2380 'contact_type' => 'Individual',
2383 $this->assertEquals(0, $result['count']);