3 * File for the TestContact class
7 * @author Walt Haas <walt@dharmatech.org> (801) 534-1262
8 * @copyright Copyright CiviCRM LLC (C) 2009
9 * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html
10 * GNU Affero General Public License version 3
11 * @version $Id: ContactTest.php 31254 2010-12-15 10:09:29Z eileen $
14 * This file is part of CiviCRM
16 * CiviCRM is free software; you can redistribute it and/or
17 * modify it under the terms of the GNU Affero General Public License
18 * as published by the Free Software Foundation; either version 3 of
19 * the License, or (at your option) any later version.
21 * CiviCRM is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU Affero General Public License for more details.
26 * You should have received a copy of the GNU Affero General Public
27 * License along with this program. If not, see
28 * <http://www.gnu.org/licenses/>.
32 * Include class definitions
34 require_once 'CiviTest/CiviUnitTestCase.php';
38 * Test APIv3 civicrm_contact* functions
40 * @package CiviCRM_APIv3
41 * @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 // truncate a few tables
73 $tablesToTruncate = array(
76 'civicrm_contribution',
79 'civicrm_relationship',
84 $this->quickCleanup($tablesToTruncate, TRUE);
88 * Test civicrm_contact_create
90 * Verify that attempt to create individual contact with only
91 * first and last names succeeds
93 function testAddCreateIndividual() {
94 $oldCount = CRM_Core_DAO
::singleValueQuery('select count(*) from civicrm_contact');
96 'first_name' => 'abc1',
97 'contact_type' => 'Individual',
98 'last_name' => 'xyz1',
101 $contact = $this->callAPISuccess('contact', 'create', $params);
102 $this->assertTrue(is_numeric($contact['id']), "In line " . __LINE__
);
103 $this->assertTrue($contact['id'] > 0, "In line " . __LINE__
);
104 $newCount = CRM_Core_DAO
::singleValueQuery('select count(*) from civicrm_contact');
105 $this->assertEquals($oldCount+
1, $newCount);
107 $this->assertDBState('CRM_Contact_DAO_Contact',
114 * Test civicrm_contact_create with sub-types
116 * Verify that sub-types are created successfully and not deleted by subsequent updates
118 function testIndividualSubType() {
120 'first_name' => 'test abc',
121 'contact_type' => 'Individual',
122 'last_name' => 'test xyz',
123 'contact_sub_type' => array('Student', 'Staff'),
125 $contact = $this->callAPISuccess('contact', 'create', $params);
126 $cid = $contact['id'];
130 'middle_name' => 'foo',
132 $this->callAPISuccess('contact', 'create', $params);
133 unset($params['middle_name']);
135 $contact = $this->callAPISuccess('contact', 'get', $params);
137 $this->assertEquals(array('Student', 'Staff'), $contact['values'][$cid]['contact_sub_type'], "In line " . __LINE__
);
141 * Verify that attempt to create contact with empty params fails
143 function testCreateEmptyContact() {
144 $this->callAPIFailure('contact', 'create', array());
148 * Verify that attempt to create contact with bad contact type fails
150 function testCreateBadTypeContact() {
152 'email' => 'man1@yahoo.com',
153 'contact_type' => 'Does not Exist',
155 $this->callAPIFailure('contact', 'create', $params,"'Does not Exist' is not a valid option for field contact_type");
159 * Verify that attempt to create individual contact with required
160 * fields missing fails
162 function testCreateBadRequiredFieldsIndividual() {
164 'middle_name' => 'This field is not required',
165 'contact_type' => 'Individual',
167 $this->callAPIFailure('contact', 'create', $params);
171 * Verify that attempt to create household contact with required
172 * fields missing fails
174 function testCreateBadRequiredFieldsHousehold() {
176 'middle_name' => 'This field is not required',
177 'contact_type' => 'Household',
179 $this->callAPIFailure('contact', 'create', $params);
183 * Verify that attempt to create organization contact with
184 * required fields missing fails
186 function testCreateBadRequiredFieldsOrganization() {
188 'middle_name' => 'This field is not required',
189 'contact_type' => 'Organization',
192 $this->callAPIFailure('contact', 'create', $params);
196 * Verify that attempt to create individual contact with only an
199 function testCreateEmailIndividual() {
202 'email' => 'man3@yahoo.com',
203 'contact_type' => 'Individual',
204 'location_type_id' => 1,
207 $contact = $this->callAPISuccess('contact', 'create', $params);
209 $this->assertEquals(1, $contact['id'], "In line " . __LINE__
);
210 $email = $this->callAPISuccess('email', 'get', array('contact_id' => $contact['id']));
211 $this->assertEquals(1, $email['count']);
212 $this->assertEquals('man3@yahoo.com', $email['values'][$email['id']]['email']);
214 $this->callAPISuccess('contact', 'delete', $contact);
218 * Verify that attempt to create individual contact with only
219 * first and last names succeeds
221 function testCreateNameIndividual() {
223 'first_name' => 'abc1',
224 'contact_type' => 'Individual',
225 'last_name' => 'xyz1',
228 $contact = $this->callAPISuccess('contact', 'create', $params);
229 $this->assertEquals(1, $contact['id']);
233 * Verify that attempt to create individual contact with
234 * first and last names and old key values works
236 function testCreateNameIndividualOldKeys() {
238 'individual_prefix' => 'Dr.',
239 'first_name' => 'abc1',
240 'contact_type' => 'Individual',
241 'last_name' => 'xyz1',
242 'individual_suffix' => 'Jr.',
245 $contact = $this->callAPISuccess('contact', 'create', $params);
246 $result = $this->callAPISuccess('contact', 'getsingle', array('id' => $contact['id']));
248 $this->assertArrayKeyExists('prefix_id', $result);
249 $this->assertArrayKeyExists('suffix_id', $result);
250 $this->assertArrayKeyExists('gender_id', $result);
251 $this->assertEquals(4, $result['prefix_id']);
252 $this->assertEquals(1, $result['suffix_id']);
256 * Verify that attempt to create individual contact with
257 * first and last names and old key values works
259 function testCreateNameIndividualrecommendedKeys2() {
261 'prefix_id' => 'Dr.',
262 'first_name' => 'abc1',
263 'contact_type' => 'Individual',
264 'last_name' => 'xyz1',
265 'suffix_id' => 'Jr.',
266 'gender_id' => 'Male',
269 $contact = $this->callAPISuccess('contact', 'create', $params);
270 $result = $this->callAPISuccess('contact', 'getsingle', array('id' => $contact['id']));
272 $this->assertArrayKeyExists('prefix_id', $result);
273 $this->assertArrayKeyExists('suffix_id', $result);
274 $this->assertArrayKeyExists('gender_id', $result);
275 $this->assertEquals(4, $result['prefix_id']);
276 $this->assertEquals(1, $result['suffix_id']);
280 * Verify that attempt to create household contact with only
281 * household name succeeds
283 function testCreateNameHousehold() {
285 'household_name' => 'The abc Household',
286 'contact_type' => 'Household',
288 $contact = $this->callAPISuccess('contact', 'create', $params);
289 $this->assertEquals(1, $contact['id'], "In line " . __LINE__
);
293 * Verify that attempt to create organization contact with only
294 * organization name succeeds
296 function testCreateNameOrganization() {
298 'organization_name' => 'The abc Organization',
299 'contact_type' => 'Organization',
301 $contact = $this->callAPISuccess('contact', 'create', $params);
302 $this->assertEquals(1, $contact['id']);
305 * Verify that attempt to create organization contact without organization name fails
307 function testCreateNoNameOrganization() {
309 'first_name' => 'The abc Organization',
310 'contact_type' => 'Organization',
312 $this->callAPIFailure('contact', 'create', $params);
315 * Check with complete array + custom field
316 * Note that the test is written on purpose without any
317 * variables specific to participant so it can be replicated into other entities
318 * and / or moved to the automated test suite
320 function testCreateWithCustom() {
321 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__
, __FILE__
);
323 $params = $this->_params
;
324 $params['custom_' . $ids['custom_field_id']] = "custom string";
325 $description = "/*this demonstrates setting a custom field through the API ";
326 $result = $this->callAPIAndDocument($this->_entity
, 'create', $params, __FUNCTION__
, __FILE__
, $description);
328 $check = $this->callAPISuccess($this->_entity
, 'get', array('return.custom_' . $ids['custom_field_id'] => 1, 'id' => $result['id']));
329 $this->assertEquals("custom string", $check['values'][$check['id']]['custom_' . $ids['custom_field_id']]);
331 $this->customFieldDelete($ids['custom_field_id']);
332 $this->customGroupDelete($ids['custom_group_id']);
336 * CRM-12773 - expectation is that civicrm quietly ignores
337 * fields without values
339 function testCreateWithNULLCustomCRM12773() {
340 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__
, __FILE__
);
341 $params = $this->_params
;
342 $params['custom_' . $ids['custom_field_id']] = NULL;
343 $this->callAPISuccess('contact', 'create', $params);
344 $this->customFieldDelete($ids['custom_field_id']);
345 $this->customGroupDelete($ids['custom_group_id']);
350 * Test creating a current employer through API
352 function testContactCreateCurrentEmployer(){
353 //here we will just do the get for set-up purposes
354 $count = $this->callAPISuccess('contact', 'getcount', array(
355 'organization_name' => 'new employer org',
356 'contact_type' => 'Organization'
358 $this->assertEquals(0, $count);
359 $employerResult = $this->callAPISuccess('contact', 'create', array_merge($this->_params
, array(
360 'current_employer' => 'new employer org',)
362 // do it again as an update to check it doesn't cause an error
363 $employerResult = $this->callAPISuccess('contact', 'create', array_merge($this->_params
, array(
364 'current_employer' => 'new employer org', 'id' => $employerResult['id'])
367 $this->callAPISuccess('contact', 'getcount', array(
368 'organization_name' => 'new employer org',
369 'contact_type' => 'Organization'
373 $result = $this->callAPISuccess('contact', 'getsingle', array(
374 'id' => $employerResult['id'],
377 $this->assertEquals('new employer org', $result['current_employer']);
381 * Test creating a current employer through API
382 * - check it will re-activate a de-activated employer
384 function testContactCreateDuplicateCurrentEmployerEnables(){
385 //set up - create employer relationship
386 $employerResult = $this->callAPISuccess('contact', 'create', array_merge($this->_params
, array(
387 'current_employer' => 'new employer org',)
389 $relationship = $this->callAPISuccess('relationship','get', array(
390 'contact_id_a' => $employerResult['id'],
393 //disable & check it is disabled
394 $this->callAPISuccess('relationship', 'create', array('id' => $relationship['id'], 'is_active' => 0));
395 $this->callAPISuccess('relationship','getvalue', array(
396 'id' => $relationship['id'],
397 'return' => 'is_active'
400 //re-set the current employer - thus enabling the relationshp
401 $this->callAPISuccess('contact', 'create', array_merge($this->_params
, array(
402 'current_employer' => 'new employer org', 'id' => $employerResult['id'])
404 //check is_active is now 1
405 $relationship = $this->callAPISuccess('relationship','getsingle', array(
406 'return' => 'is_active',));
407 $this->assertEquals(1, $relationship['is_active']);
411 * Check deceased contacts are not retrieved
412 * Note at time of writing the default is to return default. This should possibly be changed & test added
414 function testGetDeceasedRetrieved() {
415 $this->callAPISuccess($this->_entity
, 'create', $this->_params
);
416 $c2 = $this->callAPISuccess($this->_entity
, 'create', array('first_name' => 'bb', 'last_name' => 'ccc', 'contact_type' => 'Individual', 'is_deceased' => 1));
417 $result = $this->callAPISuccess($this->_entity
, 'get', array('is_deceased' => 0));
418 $this->assertFalse(array_key_exists($c2['id'], $result['values']));
422 * Test that sort works - old syntax
424 function testGetSort() {
425 $c1 = $this->callAPISuccess($this->_entity
, 'create', $this->_params
);
426 $c2 = $this->callAPISuccess($this->_entity
, 'create', array('first_name' => 'bb', 'last_name' => 'ccc', 'contact_type' => 'Individual'));
427 $result = $this->callAPISuccess($this->_entity
, 'get', array(
428 'sort' => 'first_name ASC',
429 'return.first_name' => 1,
434 $this->assertEquals('abc1', $result['values'][0]['first_name']);
435 $result = $this->callAPISuccess($this->_entity
, 'get', array(
436 'sort' => 'first_name DESC',
437 'return.first_name' => 1,
441 $this->assertEquals('bb', $result['values'][0]['first_name']);
443 $this->callAPISuccess($this->_entity
, 'delete', array('id' => $c1['id']));
444 $this->callAPISuccess($this->_entity
, 'delete', array('id' => $c2['id']));
447 * Test that we can retrieve contacts using
448 * 'id' => array('IN' => array('3,4')) syntax
450 function testGetINIDArray() {
451 $c1 = $this->callAPISuccess($this->_entity
, 'create', $this->_params
);
452 $c2 = $this->callAPISuccess($this->_entity
, 'create', array('first_name' => 'bb', 'last_name' => 'ccc', 'contact_type' => 'Individual'));
453 $c3 = $this->callAPISuccess($this->_entity
, 'create', array('first_name' => 'hh', 'last_name' => 'll', 'contact_type' => 'Individual'));
454 $result = $this->callAPISuccess($this->_entity
, 'get', array('id' => array('IN' => array($c1['id'], $c3['id']))));
455 $this->assertEquals(2, $result['count']);
456 $this->assertEquals(array($c1['id'], $c3['id']), array_keys($result['values']));
457 $this->callAPISuccess($this->_entity
, 'delete', array('id' => $c1['id']));
458 $this->callAPISuccess($this->_entity
, 'delete', array('id' => $c2['id']));
459 $this->callAPISuccess($this->_entity
, 'delete', array('id' => $c3['id']));
462 * Test variants on deleted behaviour
464 function testGetDeleted() {
465 $params = $this->_params
;
466 $contact1 = $this->callAPISuccess('contact', 'create', $params);
467 $params['is_deleted'] = 1;
468 $params['last_name'] = 'bcd';
469 $contact2 = $this->callAPISuccess('contact', 'create', $params);
470 $countActive = $this->callAPISuccess('contact', 'getcount', array('showAll' => 'active'));
471 $countAll = $this->callAPISuccess('contact', 'getcount', array('showAll' => 'all'));
472 $countTrash = $this->callAPISuccess('contact', 'getcount', array('showAll' => 'trash'));
473 $countDefault = $this->callAPISuccess('contact', 'getcount', array());
474 $countDeleted = $this->callAPISuccess('contact', 'getcount', array(
475 'contact_is_deleted' => 1,
477 $countNotDeleted = $this->callAPISuccess('contact', 'getcount', array(
478 'contact_is_deleted' => 0,
480 $this->callAPISuccess('contact', 'delete', array('id' => $contact1['id']));
481 $this->callAPISuccess('contact', 'delete', array('id' => $contact2['id']));
482 $this->assertEquals(1, $countNotDeleted, 'contact_is_deleted => 0 is respected in line ' . __LINE__
);
483 $this->assertEquals(1, $countActive, 'in line ' . __LINE__
);
484 $this->assertEquals(1, $countTrash, 'in line ' . __LINE__
);
485 $this->assertEquals(2, $countAll, 'in line ' . __LINE__
);
486 $this->assertEquals(1, $countDeleted, 'in line ' . __LINE__
);
487 $this->assertEquals(1, $countDefault, 'Only active by default in line ' . __LINE__
);
491 * Test that sort works - new syntax
493 function testGetSortNewSYntax() {
494 $c1 = $this->callAPISuccess($this->_entity
, 'create', $this->_params
);
495 $c2 = $this->callAPISuccess($this->_entity
, 'create', array('first_name' => 'bb', 'last_name' => 'ccc', 'contact_type' => 'Individual'));
496 $result = $this->callAPISuccess($this->_entity
, 'getvalue', array(
497 'return' => 'first_name',
500 'sort' => 'first_name',
503 $this->assertEquals('abc1', $result, 'in line' . __LINE__
);
505 $result = $this->callAPISuccess($this->_entity
, 'getvalue', array(
506 'return' => 'first_name',
509 'sort' => 'first_name DESC',
512 $this->assertEquals('bb', $result);
514 $this->callAPISuccess($this->_entity
, 'delete', array('id' => $c1['id']));
515 $this->callAPISuccess($this->_entity
, 'delete', array('id' => $c2['id']));
519 * Test apostrophe works in get & create
521 function testGetApostropheCRM10857() {
522 $params = array_merge($this->_params
, array('last_name' => "O'Connor"));
523 $this->callAPISuccess($this->_entity
, 'create', $params);
524 $result = $this->callAPISuccess($this->_entity
, 'getsingle', array(
525 'last_name' => "O'Connor",
528 $this->assertEquals("O'Connor", $result['last_name'], 'in line' . __LINE__
);
532 * Check with complete array + custom field
533 * Note that the test is written on purpose without any
534 * variables specific to participant so it can be replicated into other entities
535 * and / or moved to the automated test suite
537 function testGetWithCustom() {
538 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__
, __FILE__
);
540 $params = $this->_params
;
541 $params['custom_' . $ids['custom_field_id']] = "custom string";
542 $description = "/*this demonstrates setting a custom field through the API ";
543 $subfile = "CustomFieldGet";
544 $result = $this->callAPISuccess($this->_entity
, 'create', $params);
546 $check = $this->callAPIAndDocument($this->_entity
, 'get', array('return.custom_' . $ids['custom_field_id'] => 1, 'id' => $result['id']), __FUNCTION__
, __FILE__
, $description, $subfile);
548 $this->assertEquals("custom string", $check['values'][$check['id']]['custom_' . $ids['custom_field_id']]);
549 $fields = ($this->callAPISuccess('contact', 'getfields', $params));
550 $this->assertTrue(is_array($fields['values']['custom_' . $ids['custom_field_id']]));
551 $this->customFieldDelete($ids['custom_field_id']);
552 $this->customGroupDelete($ids['custom_group_id']);
556 * Check with complete array + custom field
557 * Note that the test is written on purpose without any
558 * variables specific to participant so it can be replicated into other entities
559 * and / or moved to the automated test suite
561 function testGetWithCustomReturnSyntax() {
562 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__
, __FILE__
);
564 $params = $this->_params
;
565 $params['custom_' . $ids['custom_field_id']] = "custom string";
566 $description = "/*this demonstrates setting a custom field through the API ";
567 $subfile = "CustomFieldGetReturnSyntaxVariation";
568 $result = $this->callAPISuccess($this->_entity
, 'create', $params);
569 $params = array('return' => 'custom_' . $ids['custom_field_id'], 'id' => $result['id']);
570 $check = $this->callAPIAndDocument($this->_entity
, 'get', $params, __FUNCTION__
, __FILE__
, $description, $subfile);
572 $this->assertEquals("custom string", $check['values'][$check['id']]['custom_' . $ids['custom_field_id']]);
573 $this->customFieldDelete($ids['custom_field_id']);
574 $this->customGroupDelete($ids['custom_group_id']);
578 * Check that address name is returned if required
580 function testGetReturnAddressName () {
581 $contactID = $this->individualCreate();
582 $this->callAPISuccess('address', 'create', array('contact_id' => $contactID, 'address_name' => 'My house', 'location_type_id' => 'Home', 'street_address' => '1 my road'));
583 $result = $this->callAPISuccessGetSingle('contact', array('return' => 'address_name, street_address', 'id' => $contactID));
584 $this->assertEquals('1 my road', $result['street_address']);
585 $this->assertEquals('My house', $result['address_name']);
589 function testGetGroupIDFromContact() {
590 $groupId = $this->groupCreate();
591 $description = "Get all from group and display contacts";
592 $subFile = "GroupFilterUsingContactAPI";
594 'email' => 'man2@yahoo.com',
595 'contact_type' => 'Individual',
596 'location_type_id' => 1,
597 'api.group_contact.create' => array('group_id' => $groupId),
600 $this->callAPISuccess('contact', 'create', $params);
601 // testing as integer
603 'filter.group_id' => $groupId,
604 'contact_type' => 'Individual',
606 $result = $this->callAPIAndDocument('contact', 'get', $params, __FUNCTION__
, __FILE__
, $description, $subFile);
607 $this->assertEquals(1, $result['count']);
608 // group 26 doesn't exist, but we can still search contacts in it.
610 'filter.group_id' => 26,
611 'contact_type' => 'Individual',
613 $this->callAPISuccess('contact', 'get', $params);
616 'filter.group_id' => "$groupId, 26",
617 'contact_type' => 'Individual',
619 $result = $this->callAPIAndDocument('contact', 'get', $params, __FUNCTION__
, __FILE__
, $description, $subFile);
620 $this->assertEquals(1, $result['count']);
622 'filter.group_id' => "26,27",
623 'contact_type' => 'Individual',
625 $this->callAPISuccess('contact', 'get', $params);
628 $params = array('filter.group_id' => array($groupId, 26),
629 'contact_type' => 'Individual',
631 $result = $this->callAPIAndDocument('contact', 'get', $params, __FUNCTION__
, __FILE__
, $description, $subFile);
632 $this->assertEquals(1, $result['count']);
634 //test in conjunction with other criteria
635 $params = array('filter.group_id' => array($groupId, 26),
636 'contact_type' => 'Organization',
638 $this->callAPISuccess('contact', 'get', $params);
639 $params = array('filter.group_id' => array(26, 27),
640 'contact_type' => 'Individual',
642 $result = $this->callAPISuccess('contact', 'get', $params);
643 $this->assertEquals(0, $result['count']);
647 * Verify that attempt to create individual contact with two chained websites succeeds
649 function testCreateIndividualWithContributionDottedSyntax() {
650 $description = "test demonstrates the syntax to create 2 chained entities";
651 $subFile = "ChainTwoWebsites";
653 'first_name' => 'abc3',
654 'last_name' => 'xyz3',
655 'contact_type' => 'Individual',
656 'email' => 'man3@yahoo.com',
657 'api.contribution.create' => array(
658 'receive_date' => '2010-01-01',
659 'total_amount' => 100.00,
660 'financial_type_id' => $this->_financialTypeId
,
661 'payment_instrument_id' => 1,
662 'non_deductible_amount' => 10.00,
663 'fee_amount' => 50.00,
664 'net_amount' => 90.00,
666 'invoice_id' => 67990,
668 'contribution_status_id' => 1,
670 'api.website.create' => array(
671 'url' => "http://civicrm.org",
673 'api.website.create.2' => array(
674 'url' => "http://chained.org",
678 $result = $this->callAPIAndDocument('Contact', 'create', $params, __FUNCTION__
, __FILE__
, $description, $subFile);
680 $this->assertEquals(1, $result['id'], "In line " . __LINE__
);
681 // checking child function result not covered in callAPIAndDocument
682 $this->assertAPISuccess($result['values'][$result['id']]['api.website.create']);
683 $this->assertEquals("http://chained.org", $result['values'][$result['id']]['api.website.create.2']['values'][0]['url'], "In line " . __LINE__
);
684 $this->assertEquals("http://civicrm.org", $result['values'][$result['id']]['api.website.create']['values'][0]['url'], "In line " . __LINE__
);
686 // delete the contact
687 $this->callAPISuccess('contact', 'delete', $result);
691 * Verify that attempt to create individual contact with chained contribution and website succeeds
693 function testCreateIndividualWithContributionChainedArrays() {
695 'first_name' => 'abc3',
696 'last_name' => 'xyz3',
697 'contact_type' => 'Individual',
698 'email' => 'man3@yahoo.com',
699 'api.contribution.create' => array(
700 'receive_date' => '2010-01-01',
701 'total_amount' => 100.00,
702 'financial_type_id' => $this->_financialTypeId
,
703 'payment_instrument_id' => 1,
704 'non_deductible_amount' => 10.00,
705 'fee_amount' => 50.00,
706 'net_amount' => 90.00,
708 'invoice_id' => 67890,
710 'contribution_status_id' => 1,
712 'api.website.create' => array(
714 'url' => "http://civicrm.org",
717 'url' => "http://chained.org",
718 'website_type_id' => 2,
723 $description = "demonstrates creating two websites as an array";
724 $subfile = "ChainTwoWebsitesSyntax2";
725 $result = $this->callAPIAndDocument('Contact', 'create', $params, __FUNCTION__
, __FILE__
, $description, $subfile);
727 $this->assertEquals(1, $result['id']);
728 // the callAndDocument doesn't check the chained call
729 $this->assertEquals(0, $result['values'][$result['id']]['api.website.create'][0]['is_error'], "In line " . __LINE__
);
730 $this->assertEquals("http://chained.org", $result['values'][$result['id']]['api.website.create'][1]['values'][0]['url'], "In line " . __LINE__
);
731 $this->assertEquals("http://civicrm.org", $result['values'][$result['id']]['api.website.create'][0]['values'][0]['url'], "In line " . __LINE__
);
733 $this->callAPISuccess('contact', 'delete', $result);
737 * Verify that attempt to create individual contact with first
738 * and last names and email succeeds
740 function testCreateIndividualWithNameEmail() {
742 'first_name' => 'abc3',
743 'last_name' => 'xyz3',
744 'contact_type' => 'Individual',
745 'email' => 'man3@yahoo.com',
748 $contact = $this->callAPISuccess('contact', 'create', $params);
749 $this->assertEquals(1, $contact['id'], "In line " . __LINE__
);
751 // delete the contact
752 $this->callAPISuccess('contact', 'delete', $contact);
755 * Verify that attempt to create individual contact with no data fails
757 function testCreateIndividualWithOutNameEmail() {
759 'contact_type' => 'Individual',
761 $this->callAPIFailure('contact', 'create', $params);
764 * Verify that attempt to create individual contact with first
765 * and last names, email and location type succeeds
767 function testCreateIndividualWithNameEmailLocationType() {
769 'first_name' => 'abc4',
770 'last_name' => 'xyz4',
771 'email' => 'man4@yahoo.com',
772 'contact_type' => 'Individual',
773 'location_type_id' => 1,
775 $result = $this->callAPISuccess('contact', 'create', $params);
777 $this->assertEquals(1, $result['id'], "In line " . __LINE__
);
779 $this->callAPISuccess('contact', 'delete', array('id' => $result['id']));
783 * Verify that when changing employers
784 * the old employer relationship becomes inactive
786 function testCreateIndividualWithEmployer() {
787 $employer = $this->organizationCreate();
788 $employer2 = $this->organizationCreate();
791 'email' => 'man4@yahoo.com',
792 'contact_type' => 'Individual',
793 'employer_id' => $employer,
796 $result = $this->callAPISuccess('contact', 'create', $params);
797 $relationships = $this->callAPISuccess('relationship', 'get', array(
798 'contact_id_a' => $result['id'],
802 $this->assertEquals($employer, $relationships['values'][0]['contact_id_b']);
804 // Add more random relationships to make the test more realistic
805 foreach (array('Employee of', 'Volunteer for') as $relationshipType) {
806 $relTypeId = CRM_Core_DAO
::getFieldValue('CRM_Contact_DAO_RelationshipType', $relationshipType, 'id', 'name_a_b');
807 $this->callAPISuccess('relationship', 'create', array(
808 'contact_id_a' => $result['id'],
809 'contact_id_b' => $this->organizationCreate(),
811 'relationship_type_id' => $relTypeId,
815 // Add second employer
816 $params['employer_id'] = $employer2;
817 $params['id'] = $result['id'];
818 $result = $this->callAPISuccess('contact', 'create', $params);
820 $relationships = $this->callAPISuccess('relationship', 'get', array(
821 'contact_id_a' => $result['id'],
826 $this->assertEquals($employer, $relationships['values'][0]['contact_id_b']);
830 * Verify that attempt to create household contact with details
833 function testCreateHouseholdDetails() {
835 'household_name' => 'abc8\'s House',
836 'nick_name' => 'x House',
837 'email' => 'man8@yahoo.com',
838 'contact_type' => 'Household',
841 $contact = $this->callAPISuccess('contact', 'create', $params);
843 $this->assertEquals(1, $contact['id'], "In line " . __LINE__
);
845 $this->callAPISuccess('contact', 'delete', $contact);
848 * Verify that attempt to create household contact with inadequate details
851 function testCreateHouseholdInadequateDetails() {
853 'nick_name' => 'x House',
854 'email' => 'man8@yahoo.com',
855 'contact_type' => 'Household',
857 $this->callAPIFailure('contact', 'create', $params);
861 * Verify successful update of individual contact
863 function testUpdateIndividualWithAll() {
864 // Insert a row in civicrm_contact creating individual contact
865 $op = new PHPUnit_Extensions_Database_Operation_Insert();
866 $op->execute($this->_dbconn
,
867 $this->createXMLDataSet(
868 dirname(__FILE__
) . '/dataset/contact_ind.xml'
874 'first_name' => 'abcd',
875 'contact_type' => 'Individual',
876 'nick_name' => 'This is nickname first',
877 'do_not_email' => '1',
878 'do_not_phone' => '1',
879 'do_not_mail' => '1',
880 'do_not_trade' => '1',
881 'legal_identifier' => 'ABC23853ZZ2235',
882 'external_identifier' => '1928837465',
883 'image_URL' => 'http://some.url.com/image.jpg',
884 'home_url' => 'http://www.example.org',
888 $this->callAPISuccess('Contact', 'Update', $params);
889 $getResult = $this->callAPISuccess('Contact', 'Get', $params);
890 unset($params['contact_id']);
891 //Todo - neither API v2 or V3 are testing for home_url - not sure if it is being set.
892 //reducing this test partially back to api v2 level to get it through
893 unset($params['home_url']);
894 foreach ($params as $key => $value) {
895 $this->assertEquals($value, $getResult['values'][23][$key]);
897 // Check updated civicrm_contact against expected
898 $expected = $this->createXMLDataSet(
899 dirname(__FILE__
) . '/dataset/contact_ind_upd.xml'
901 $actual = new PHPUnit_Extensions_Database_DataSet_QueryDataSet(
904 $actual->addTable('civicrm_contact');
905 $expected->matches($actual);
909 * Verify successful update of organization contact
911 function testUpdateOrganizationWithAll() {
912 // Insert a row in civicrm_contact creating organization contact
913 $op = new PHPUnit_Extensions_Database_Operation_Insert();
914 $op->execute($this->_dbconn
,
915 $this->createXMLDataSet(
916 dirname(__FILE__
) . '/dataset/contact_org.xml'
922 'organization_name' => 'WebAccess India Pvt Ltd',
923 'legal_name' => 'WebAccess',
924 'sic_code' => 'ABC12DEF',
925 'contact_type' => 'Organization',
928 $this->callAPISuccess('Contact', 'Update', $params);
930 // Check updated civicrm_contact against expected
931 $expected = $this->createXMLDataSet(
932 dirname(__FILE__
) . '/dataset/contact_org_upd.xml'
934 $actual = new PHPUnit_Extensions_Database_DataSet_QueryDataSet(
937 $actual->addTable('civicrm_contact');
938 $expected->matches($actual);
942 * Verify successful update of household contact
944 function testUpdateHouseholdwithAll() {
945 // Insert a row in civicrm_contact creating household contact
946 $op = new PHPUnit_Extensions_Database_Operation_Insert();
947 $op->execute($this->_dbconn
,
948 $this->createXMLDataSet(
949 dirname(__FILE__
) . '/dataset/contact_hld.xml'
955 'household_name' => 'ABC household',
956 'nick_name' => 'ABC House',
957 'contact_type' => 'Household',
960 $result = $this->callAPISuccess('Contact', 'Update', $params);
963 'contact_type' => 'Household',
965 'sort_name' => 'ABC household',
966 'display_name' => 'ABC household',
967 'nick_name' => 'ABC House',
969 $this->getAndCheck($expected, $result['id'], 'contact');
973 * Test civicrm_update() Deliberately exclude contact_type as it should still
974 * cope using civicrm_api CRM-7645
977 public function testUpdateCreateWithID() {
978 // Insert a row in civicrm_contact creating individual contact
979 $op = new PHPUnit_Extensions_Database_Operation_Insert();
980 $op->execute($this->_dbconn
,
981 $this->createXMLDataSet(
982 dirname(__FILE__
) . '/dataset/contact_ind.xml'
990 'first_name' => 'abcd',
991 'last_name' => 'wxyz',
993 $this->callAPISuccess('Contact', 'Update', $params);
997 * Test civicrm_contact_delete() with no contact ID
999 function testContactDeleteNoID() {
1003 $this->callAPIFailure('contact', 'delete', $params);
1007 * Test civicrm_contact_delete() with error
1009 function testContactDeleteError() {
1010 $params = array('contact_id' => 999);
1011 $this->callAPIFailure('contact', 'delete', $params);
1015 * Test civicrm_contact_delete()
1017 function testContactDelete() {
1018 $contactID = $this->individualCreate();
1020 'id' => $contactID ,
1022 $this->callAPIAndDocument('contact', 'delete', $params, __FUNCTION__
, __FILE__
);
1026 * Test civicrm_contact_get() return only first name
1028 public function testContactGetRetFirst() {
1029 $contact = $this->callAPISuccess('contact', 'create', $this->_params
);
1031 'contact_id' => $contact['id'],
1032 'return_first_name' => TRUE,
1033 'sort' => 'first_name',
1035 $result = $this->callAPISuccess('contact', 'get', $params);
1036 $this->assertEquals(1, $result['count']);
1037 $this->assertEquals($contact['id'], $result['id']);
1038 $this->assertEquals('abc1', $result['values'][$contact['id']]['first_name']);
1042 * Test civicrm_contact_get() return only first name & last name
1043 * Use comma separated string return with a space
1045 public function testContactGetRetFirstLast() {
1046 $contact = $this->callAPISuccess('contact', 'create', $this->_params
);
1048 'contact_id' => $contact['id'],
1049 'return' => 'first_name, last_name',
1051 $result = $this->callAPISuccess('contact', 'getsingle', $params);
1052 $this->assertEquals('abc1', $result['first_name']);
1053 $this->assertEquals('xyz1', $result['last_name']);
1054 //check that other defaults not returns
1055 $this->assertArrayNotHasKey('sort_name', $result);
1057 'contact_id' => $contact['id'],
1058 'return' => 'first_name,last_name',
1060 $result = $this->callAPISuccess('contact', 'getsingle', $params);
1061 $this->assertEquals('abc1', $result['first_name']);
1062 $this->assertEquals('xyz1', $result['last_name']);
1063 //check that other defaults not returns
1064 $this->assertArrayNotHasKey('sort_name', $result);
1068 * Test civicrm_contact_get() return only first name & last name
1069 * Use comma separated string return without a space
1071 public function testContactGetRetFirstLastNoComma() {
1072 $contact = $this->callAPISuccess('contact', 'create', $this->_params
);
1074 'contact_id' => $contact['id'],
1075 'return' => 'first_name,last_name',
1077 $result = $this->callAPISuccess('contact', 'getsingle', $params);
1078 $this->assertEquals('abc1', $result['first_name']);
1079 $this->assertEquals('xyz1', $result['last_name']);
1080 //check that other defaults not returns
1081 $this->assertArrayNotHasKey('sort_name', $result);
1085 * Test civicrm_contact_get() with default return properties
1087 public function testContactGetRetDefault() {
1088 $contactID = $this->individualCreate();
1090 'contact_id' => $contactID,
1091 'sort' => 'first_name',
1093 $result = $this->callAPISuccess('contact', 'get', $params);
1094 $this->assertEquals($contactID, $result['values'][$contactID]['contact_id']);
1095 $this->assertEquals('Anthony', $result['values'][$contactID]['first_name']);
1099 * Test civicrm_contact_getquick() with empty name param
1101 public function testContactGetQuick() {
1102 // Insert a row in civicrm_contact creating individual contact
1103 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1104 $op->execute($this->_dbconn
,
1105 $this->createXMLDataSet(
1106 dirname(__FILE__
) . '/dataset/contact_17.xml'
1109 $op->execute($this->_dbconn
,
1110 $this->createXMLDataSet(
1111 dirname(__FILE__
) . '/dataset/email_contact_17.xml'
1118 $result = $this->callAPISuccess('contact', 'getquick', $params);
1119 $this->assertEquals(17, $result['values'][0]['id'], 'in line ' . __LINE__
);
1123 * Test civicrm_contact_get) with empty params
1125 public function testContactGetEmptyParams() {
1126 $this->callAPISuccess('contact', 'get', array());
1130 * Test civicrm_contact_get(,true) with no matches
1132 public function testContactGetOldParamsNoMatches() {
1133 // Insert a row in civicrm_contact creating contact 17
1134 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1135 $op->execute($this->_dbconn
,
1136 $this->createXMLDataSet(
1137 dirname(__FILE__
) . '/dataset/contact_17.xml'
1142 'first_name' => 'Fred',
1144 $result = $this->callAPISuccess('contact', 'get', $params);
1145 $this->assertEquals(0, $result['count'], 'in line ' . __LINE__
);
1149 * Test civicrm_contact_get(,true) with one match
1151 public function testContactGetOldParamsOneMatch() {
1152 // Insert a row in civicrm_contact creating contact 17
1153 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1154 $op->execute($this->_dbconn
,
1155 $this->createXMLDataSet(dirname(__FILE__
) . '/dataset/contact_17.xml'
1160 'first_name' => 'Test',
1162 $result = $this->callAPISuccess('contact', 'get', $params);
1163 $this->assertEquals(17, $result['values'][17]['contact_id'], 'in line ' . __LINE__
);
1164 $this->assertEquals(17, $result['id'], 'in line ' . __LINE__
);
1168 * Test civicrm_contact_search_count()
1170 public function testContactGetEmail() {
1172 'email' => 'man2@yahoo.com',
1173 'contact_type' => 'Individual',
1174 'location_type_id' => 1,
1177 $contact = $this->callAPISuccess('contact', 'create', $params);
1179 $this->assertEquals(1, $contact['id']);
1182 'email' => 'man2@yahoo.com',
1184 $result = $this->callAPIAndDocument('contact', 'get', $params, __FUNCTION__
, __FILE__
);
1185 $this->assertEquals(1, $result['values'][1]['contact_id']);
1186 $this->assertEquals('man2@yahoo.com', $result['values'][1]['email']);
1188 // delete the contact
1189 $this->callAPISuccess('contact', 'delete', $contact);
1193 * Test birth date params incl value, array & birth_date_high, birth_date_low
1196 public function testContactGetBirthDate() {
1197 $contact1 = $this->callAPISuccess('contact', 'create', array_merge($this->_params
, array('birth_date' => 'first day of next month - 2 years')));
1198 $contact2 = $this->callAPISuccess('contact', 'create', array_merge($this->_params
, array('birth_date' => 'first day of next month - 5 years')));
1199 $contact3 = $this->callAPISuccess('contact', 'create', array_merge($this->_params
, array('birth_date' => 'first day of next month -20 years')));
1201 $result = $this->callAPISuccess('contact', 'get', array());
1202 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -2 years')), $result['values'][$contact1['id']]['birth_date']);
1203 $result = $this->callAPISuccess('contact', 'get', array('birth_date' => 'first day of next month -5 years'));
1204 $this->assertEquals(1, $result['count']);
1205 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -5 years')), $result['values'][$contact2['id']]['birth_date']);
1206 $result = $this->callAPISuccess('contact', 'get', array('birth_date_high' => date('Y-m-d', strtotime('-6 years'))));
1207 $this->assertEquals(1, $result['count']);
1208 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -20 years')), $result['values'][$contact3['id']]['birth_date']);
1209 $result = $this->callAPISuccess('contact', 'get', array('birth_date_low' => date('Y-m-d', strtotime('-6 years')), 'birth_date_high' => date('Y-m-d', strtotime('- 3 years'))));
1210 $this->assertEquals(1, $result['count']);
1211 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -5 years')), $result['values'][$contact2['id']]['birth_date']);
1212 $result = $this->callAPISuccess('contact', 'get', array('birth_date_low' => '-6 years', 'birth_date_high' => '- 3 years'));
1213 $this->assertEquals(1, $result['count']);
1214 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -5 years')), $result['values'][$contact2['id']]['birth_date']);
1218 * Test Deceaseddate params incl value, array & Deceased_date_high, Deceaseddate_low
1221 public function testContactGetDeceasedDate() {
1222 $contact1 = $this->callAPISuccess('contact', 'create', array_merge($this->_params
, array('deceased_date' => 'first day of next month - 2 years')));
1223 $contact2 = $this->callAPISuccess('contact', 'create', array_merge($this->_params
, array('deceased_date' => 'first day of next month - 5 years')));
1224 $contact3 = $this->callAPISuccess('contact', 'create', array_merge($this->_params
, array('deceased_date' => 'first day of next month -20 years')));
1226 $result = $this->callAPISuccess('contact', 'get', array());
1227 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -2 years')), $result['values'][$contact1['id']]['deceased_date']);
1228 $result = $this->callAPISuccess('contact', 'get', array('deceased_date' => 'first day of next month -5 years'));
1229 $this->assertEquals(1, $result['count']);
1230 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -5 years')), $result['values'][$contact2['id']]['deceased_date']);
1231 $result = $this->callAPISuccess('contact', 'get', array('deceased_date_high' => date('Y-m-d', strtotime('-6 years'))));
1232 $this->assertEquals(1, $result['count']);
1233 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -20 years')), $result['values'][$contact3['id']]['deceased_date']);
1234 $result = $this->callAPISuccess('contact', 'get', array('deceased_date_low' => '-6 years', 'deceased_date_high' => date('Y-m-d', strtotime('- 3 years'))));
1235 $this->assertEquals(1, $result['count']);
1236 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -5 years')), $result['values'][$contact2['id']]['deceased_date']);
1240 * Test for Contact.get id=@user:username
1242 function testContactGetByUsername() {
1243 // setup - create contact with a uf-match
1244 $cid = $this->individualCreate(array(
1245 'contact_type' => 'Individual',
1246 'first_name' => 'testGetByUsername',
1247 'last_name' => 'testGetByUsername',
1250 $ufMatchParams = array(
1251 'domain_id' => CRM_Core_Config
::domainID(),
1253 'uf_name' => 'the-email-matching-key-is-not-really-the-username',
1254 'contact_id' => $cid,
1256 $ufMatch = CRM_Core_BAO_UFMatch
::create($ufMatchParams);
1257 $this->assertTrue(is_numeric($ufMatch->id
));
1259 // setup - mock the calls to CRM_Utils_System_*::getUfId
1260 $userSystem = $this->getMock('CRM_Utils_System_UnitTests', array('getUfId'));
1261 $userSystem->expects($this->once())
1263 ->with($this->equalTo('exampleUser'))
1264 ->will($this->returnValue(99));
1265 CRM_Core_Config
::singleton()->userSystem
= $userSystem;
1268 $result = $this->callAPISuccess('Contact', 'get', array(
1269 'id' => '@user:exampleUser',
1271 $this->assertEquals('testGetByUsername', $result['values'][$cid]['first_name']);
1275 * Test to check return works OK
1277 function testContactGetReturnValues() {
1278 $extraParams = array('nick_name' => 'Bob', 'phone' => '456', 'email' => 'e@mail.com');
1279 $contactID = $this->individualCreate($extraParams);
1280 //actually it turns out the above doesn't create a phone
1281 $this->callAPISuccess('phone', 'create', array('contact_id' => $contactID, 'phone' => '456',));
1282 $result = $this->callAPISuccess('contact', 'getsingle', array('id' => $contactID));
1283 foreach ($extraParams as $key => $value) {
1284 $this->assertEquals($result[$key], $value);
1286 //now we check they are still returned with 'return' key
1287 $result = $this->callAPISuccess('contact', 'getsingle', array('id' => $contactID, 'return' => array_keys($extraParams)));
1288 foreach ($extraParams as $key => $value) {
1289 $this->assertEquals($result[$key], $value);
1293 function testCRM13252MultipleChainedPhones() {
1294 $contactID = $this->householdCreate();
1295 $this->callAPISuccessGetCount('phone', array('contact_id' => $contactID), 0);
1297 'contact_id' => $contactID,
1298 'household_name' => 'Household 1',
1299 'contact_type' => 'Household',
1300 'api.phone.create' => array(
1302 'phone' => '111-111-1111',
1303 'location_type_id' => 1,
1304 'phone_type_id' => 1,
1307 'phone' => '222-222-2222',
1308 'location_type_id' => 1,
1309 'phone_type_id' => 2,
1313 $this->callAPISuccess('contact', 'create', $params);
1314 $this->callAPISuccessGetCount('phone', array('contact_id' => $contactID), 2);
1318 * Test for Contact.get id=@user:username (with an invalid username)
1320 function testContactGetByUnknownUsername() {
1321 // setup - mock the calls to CRM_Utils_System_*::getUfId
1322 $userSystem = $this->getMock('CRM_Utils_System_UnitTests', array('getUfId'));
1323 $userSystem->expects($this->once())
1325 ->with($this->equalTo('exampleUser'))
1326 ->will($this->returnValue(NULL));
1327 CRM_Core_Config
::singleton()->userSystem
= $userSystem;
1330 $result = $this->callAPIFailure('Contact', 'get', array(
1331 'id' => '@user:exampleUser',
1333 $this->assertRegExp('/cannot be resolved to a contact ID/', $result['error_message']);
1337 * Verify attempt to create individual with chained arrays
1339 function testGetIndividualWithChainedArrays() {
1340 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__
, __FILE__
);
1341 $params['custom_' . $ids['custom_field_id']] = "custom string";
1343 $moreids = $this->CustomGroupMultipleCreateWithFields();
1344 $description = "/*this demonstrates the usage of chained api functions. In this case no notes or custom fields have been created ";
1345 $subfile = "APIChainedArray";
1347 'first_name' => 'abc3',
1348 'last_name' => 'xyz3',
1349 'contact_type' => 'Individual',
1350 'email' => 'man3@yahoo.com',
1351 'api.contribution.create' => array(
1352 'receive_date' => '2010-01-01',
1353 'total_amount' => 100.00,
1354 'financial_type_id' => 1,
1355 'payment_instrument_id' => 1,
1356 'non_deductible_amount' => 10.00,
1357 'fee_amount' => 50.00,
1358 'net_amount' => 90.00,
1360 'invoice_id' => 67890,
1362 'contribution_status_id' => 1,
1364 'api.contribution.create.1' => array(
1365 'receive_date' => '2011-01-01',
1366 'total_amount' => 120.00,
1367 'financial_type_id' => $this->_financialTypeId
=1,
1368 'payment_instrument_id' => 1,
1369 'non_deductible_amount' => 10.00,
1370 'fee_amount' => 50.00,
1371 'net_amount' => 90.00,
1373 'invoice_id' => 67830,
1375 'contribution_status_id' => 1,
1377 'api.website.create' => array(
1379 'url' => "http://civicrm.org",
1384 $result = $this->callAPISuccess('Contact', 'create', $params);
1386 'id' => $result['id'],
1387 'api.website.get' => array(),
1388 'api.Contribution.get' => array(
1389 'total_amount' => '120.00',
1390 ), 'api.CustomValue.get' => 1,
1391 'api.Note.get' => 1,
1393 $result = $this->callAPIAndDocument('Contact', 'Get', $params, __FUNCTION__
, __FILE__
, $description, $subfile);
1394 // delete the contact
1395 $this->callAPISuccess('contact', 'delete', $result);
1396 $this->customGroupDelete($ids['custom_group_id']);
1397 $this->customGroupDelete($moreids['custom_group_id']);
1398 $this->assertEquals(1, $result['id']);
1399 $this->assertEquals(0, $result['values'][$result['id']]['api.website.get']['is_error']);
1400 $this->assertEquals("http://civicrm.org", $result['values'][$result['id']]['api.website.get']['values'][0]['url']);
1403 function testGetIndividualWithChainedArraysFormats() {
1404 $description = "/*this demonstrates the usage of chained api functions. A variety of return formats are used. Note that no notes
1405 *custom fields or memberships exist";
1406 $subfile = "APIChainedArrayFormats";
1407 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__
, __FILE__
);
1408 $params['custom_' . $ids['custom_field_id']] = "custom string";
1410 $moreids = $this->CustomGroupMultipleCreateWithFields();
1412 'first_name' => 'abc3',
1413 'last_name' => 'xyz3',
1414 'contact_type' => 'Individual',
1415 'email' => 'man3@yahoo.com',
1416 'api.contribution.create' => array(
1417 'receive_date' => '2010-01-01',
1418 'total_amount' => 100.00,
1419 'financial_type_id' => $this->_financialTypeId
,
1420 'payment_instrument_id' => 1,
1421 'non_deductible_amount' => 10.00,
1422 'fee_amount' => 50.00,
1423 'net_amount' => 90.00,
1425 'contribution_status_id' => 1,
1427 'api.contribution.create.1' => array(
1428 'receive_date' => '2011-01-01',
1429 'total_amount' => 120.00,
1430 'financial_type_id' => $this->_financialTypeId
,
1431 'payment_instrument_id' => 1,
1432 'non_deductible_amount' => 10.00,
1433 'fee_amount' => 50.00,
1434 'net_amount' => 90.00,
1436 'contribution_status_id' => 1,
1438 'api.website.create' => array(
1440 'url' => "http://civicrm.org",
1446 $result = $this->callAPISuccess('Contact', 'create', $params);
1448 'id' => $result['id'],
1449 'api.website.getValue' => array('return' => 'url'),
1450 'api.Contribution.getCount' => array(),
1451 'api.CustomValue.get' => 1,
1452 'api.Note.get' => 1,
1453 'api.Membership.getCount' => array(),
1455 $result = $this->callAPIAndDocument('Contact', 'Get', $params, __FUNCTION__
, __FILE__
, $description, $subfile);
1456 $this->assertEquals(1, $result['id']);
1457 $this->assertEquals(2, $result['values'][$result['id']]['api.Contribution.getCount']);
1458 $this->assertEquals(0, $result['values'][$result['id']]['api.Note.get']['is_error']);
1459 $this->assertEquals("http://civicrm.org", $result['values'][$result['id']]['api.website.getValue']);
1461 $this->callAPISuccess('contact', 'delete', $result);
1462 $this->customGroupDelete($ids['custom_group_id']);
1463 $this->customGroupDelete($moreids['custom_group_id']);
1466 function testGetIndividualWithChainedArraysAndMultipleCustom() {
1467 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__
, __FILE__
);
1468 $params['custom_' . $ids['custom_field_id']] = "custom string";
1469 $moreids = $this->CustomGroupMultipleCreateWithFields();
1470 $andmoreids = $this->CustomGroupMultipleCreateWithFields(array('title' => "another group", 'name' => 'another name'));
1471 $description = "/*this demonstrates the usage of chained api functions. A variety of techniques are used";
1472 $subfile = "APIChainedArrayMultipleCustom";
1474 'first_name' => 'abc3',
1475 'last_name' => 'xyz3',
1476 'contact_type' => 'Individual',
1477 'email' => 'man3@yahoo.com',
1478 'api.contribution.create' => array(
1479 'receive_date' => '2010-01-01',
1480 'total_amount' => 100.00,
1481 'financial_type_id' => 1,
1482 'payment_instrument_id' => 1,
1483 'non_deductible_amount' => 10.00,
1484 'fee_amount' => 50.00,
1485 'net_amount' => 90.00,
1487 'invoice_id' => 67890,
1489 'contribution_status_id' => 1,
1491 'api.contribution.create.1' => array(
1492 'receive_date' => '2011-01-01',
1493 'total_amount' => 120.00,
1494 'financial_type_id' => 1,
1495 'payment_instrument_id' => 1,
1496 'non_deductible_amount' => 10.00,
1497 'fee_amount' => 50.00,
1498 'net_amount' => 90.00,
1500 'invoice_id' => 67830,
1502 'contribution_status_id' => 1,
1504 'api.website.create' => array(
1506 'url' => "http://civicrm.org",
1509 'custom_' . $ids['custom_field_id'] => "value 1",
1510 'custom_' . $moreids['custom_field_id'][0] => "value 2",
1511 'custom_' . $moreids['custom_field_id'][1] => "warm beer",
1512 'custom_' . $andmoreids['custom_field_id'][1] => "vegemite",
1516 $result = $this->callAPISuccess('Contact', 'create', $params);
1517 $result = $this->callAPISuccess('Contact', 'create', array(
1518 'contact_type' => 'Individual', 'id' => $result['id'], 'custom_' . $moreids['custom_field_id'][0] => "value 3", 'custom_' . $ids['custom_field_id'] => "value 4",
1522 'id' => $result['id'],
1523 'api.website.getValue' => array('return' => 'url'),
1524 'api.Contribution.getCount' => array(),
1525 'api.CustomValue.get' => 1,
1527 $result = $this->callAPIAndDocument('Contact', 'Get', $params, __FUNCTION__
, __FILE__
, $description, $subfile);
1529 $this->customGroupDelete($ids['custom_group_id']);
1530 $this->customGroupDelete($moreids['custom_group_id']);
1531 $this->customGroupDelete($andmoreids['custom_group_id']);
1532 $this->assertEquals(1, $result['id']);
1533 $this->assertEquals(0, $result['values'][$result['id']]['api.CustomValue.get']['is_error']);
1534 $this->assertEquals('http://civicrm.org', $result['values'][$result['id']]['api.website.getValue']);
1537 * Test checks siusage of $values to pick & choose inputs
1539 function testChainingValuesCreate() {
1540 $description = "/*this demonstrates the usage of chained api functions. Specifically it has one 'parent function' &
1541 2 child functions - one receives values from the parent (Contact) and the other child (Tag). ";
1542 $subfile = "APIChainedArrayValuesFromSiblingFunction";
1544 'display_name' => 'batman', 'contact_type' => 'Individual',
1545 'api.tag.create' => array('name' => '$value.id', 'description' => '$value.display_name', 'format.only_id' => 1),
1546 'api.entity_tag.create' => array('tag_id' => '$value.api.tag.create'),
1548 $result = $this->callAPIAndDocument('Contact', 'Create', $params, __FUNCTION__
, __FILE__
, $description, $subfile);
1549 $this->assertEquals(0, $result['values'][$result['id']]['api.entity_tag.create']['is_error']);
1551 $tablesToTruncate = array(
1554 'civicrm_entity_tag',
1557 $this->quickCleanup($tablesToTruncate, TRUE);
1561 * test TrueFalse format - I couldn't come up with an easy way to get an error on Get
1563 function testContactGetFormatIsSuccessTrue() {
1564 $this->createContactFromXML();
1565 $description = "This demonstrates use of the 'format.is_success' param.
1566 This param causes only the success or otherwise of the function to be returned as BOOLEAN";
1567 $subfile = "FormatIsSuccess_True";
1568 $params = array('id' => 17, 'format.is_success' => 1);
1569 $result = $this->callAPIAndDocument('Contact', 'Get', $params, __FUNCTION__
, __FILE__
, $description, $subfile);
1570 $this->assertEquals(1, $result);
1571 $this->callAPISuccess('Contact', 'Delete', $params);
1574 * test TrueFalse format
1576 function testContactCreateFormatIsSuccessFalse() {
1578 $description = "This demonstrates use of the 'format.is_success' param.
1579 This param causes only the success or otherwise of the function to be returned as BOOLEAN";
1580 $subfile = "FormatIsSuccess_Fail";
1581 $params = array('id' => 500, 'format.is_success' => 1);
1582 $result = $this->callAPIAndDocument('Contact', 'Create', $params, __FUNCTION__
, __FILE__
, $description, $subfile);
1583 $this->assertEquals(0, $result);
1586 * test Single Entity format
1588 function testContactGetSingle_entity_array() {
1589 $this->createContactFromXML();
1590 $description = "This demonstrates use of the 'format.single_entity_array' param.
1591 /* This param causes the only contact to be returned as an array without the other levels.
1592 /* it will be ignored if there is not exactly 1 result";
1593 $subfile = "GetSingleContact";
1594 $params = array('id' => 17);
1595 $result = $this->callAPIAndDocument('Contact', 'GetSingle', $params, __FUNCTION__
, __FILE__
, $description, $subfile);
1596 $this->assertEquals('Test Contact', $result['display_name']);
1597 $this->callAPISuccess('Contact', 'Delete', $params);
1601 * test Single Entity format
1603 function testContactGetFormatcount_only() {
1604 $this->createContactFromXML();
1605 $description = "/*This demonstrates use of the 'getCount' action
1606 /* This param causes the count of the only function to be returned as an integer";
1607 $subfile = "GetCountContact";
1608 $params = array('id' => 17);
1609 $result = $this->callAPIAndDocument('Contact', 'GetCount', $params, __FUNCTION__
, __FILE__
, $description, $subfile);
1610 $this->assertEquals('1', $result);
1611 $this->callAPISuccess('Contact', 'Delete', $params);
1614 * Test id only format
1616 function testContactGetFormatID_only() {
1617 $this->createContactFromXML();
1618 $description = "This demonstrates use of the 'format.id_only' param.
1619 /* This param causes the id of the only entity to be returned as an integer.
1620 /* it will be ignored if there is not exactly 1 result";
1621 $subfile = "FormatOnlyID";
1622 $params = array('id' => 17, 'format.only_id' => 1);
1623 $result = $this->callAPIAndDocument('Contact', 'Get', $params, __FUNCTION__
, __FILE__
, $description, $subfile);
1624 $this->assertEquals('17', $result);
1625 $this->callAPISuccess('Contact', 'Delete', $params);
1629 * Test id only format
1631 function testContactGetFormatSingleValue() {
1632 $this->createContactFromXML();
1633 $description = "This demonstrates use of the 'format.single_value' param.
1634 /* This param causes only a single value of the only entity to be returned as an string.
1635 /* it will be ignored if there is not exactly 1 result";
1636 $subFile = "FormatSingleValue";
1637 $params = array('id' => 17, 'return' => 'display_name');
1638 $result = $this->callAPIAndDocument('Contact', 'getvalue', $params, __FUNCTION__
, __FILE__
, $description, $subFile,'getvalue');
1639 $this->assertEquals('Test Contact', $result);
1640 $this->callAPISuccess('Contact', 'Delete', $params);
1644 * Test that permissions are respected when creating contacts
1646 function testContactCreationPermissions() {
1648 'contact_type' => 'Individual', 'first_name' => 'Foo',
1649 'last_name' => 'Bear',
1650 'check_permissions' => TRUE,
1652 $config = CRM_Core_Config
::singleton();
1653 $config->userPermissionClass
->permissions
= array('access CiviCRM');
1654 $result = $this->callAPIFailure('contact', 'create', $params);
1655 $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');
1657 $config->userPermissionClass
->permissions
= array('access CiviCRM', 'add contacts', 'import contacts');
1658 $this->callAPISuccess('contact', 'create', $params, NULL, 'overfluous permissions should be enough to create a contact');
1661 function testContactUpdatePermissions() {
1662 $params = array('contact_type' => 'Individual', 'first_name' => 'Foo', 'last_name' => 'Bear', 'check_permissions' => TRUE,);
1663 $result = $this->callAPISuccess('contact', 'create', $params);
1664 $config = CRM_Core_Config
::singleton();
1665 $params = array('id' => $result['id'], 'contact_type' => 'Individual', 'last_name' => 'Bar', 'check_permissions' => TRUE,);
1667 $config->userPermissionClass
->permissions
= array('access CiviCRM');
1668 $result = $this->callAPIFailure('contact', 'update', $params);
1669 $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');
1671 $config->userPermissionClass
->permissions
= array('access CiviCRM', 'add contacts', 'view all contacts', 'edit all contacts', 'import contacts');
1672 $this->callAPISuccess('contact', 'update', $params, NULL, 'overfluous permissions should be enough to update a contact');
1675 function createContactFromXML() {
1676 // Insert a row in civicrm_contact creating contact 17
1677 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1678 $op->execute($this->_dbconn
,
1679 $this->createXMLDataSet(
1680 dirname(__FILE__
) . '/dataset/contact_17.xml'
1685 function testContactProximity() {
1686 // first create a contact with a SF location with a specific
1688 $contactID = $this->organizationCreate();
1690 // now create the address
1692 'street_address' => '123 Main Street',
1693 'city' => 'San Francisco',
1695 'country_id' => 1228,
1696 'state_province_id' => 1004,
1697 'geo_code_1' => '37.79',
1698 'geo_code_2' => '-122.40',
1699 'location_type_id' => 1,
1700 'contact_id' => $contactID,
1703 $result = $this->callAPISuccess('address', 'create', $params);
1704 $this->assertEquals(1, $result['count'], 'In line ' . __LINE__
);
1706 // now do a proximity search with a close enough geocode and hope to match
1707 // that specific contact only!
1708 $proxParams = array(
1710 'longitude' => -122.3,
1714 $result = $this->callAPISuccess('contact', 'proximity', $proxParams);
1715 $this->assertEquals(1, $result['count'], 'In line ' . __LINE__
);
1719 * Test that Ajax API permission is sufficient to access getquick api
1720 * (note that getquick api is required for autocomplete & has ACL permissions applied)
1722 function testGetquickPermission_CRM_13744() {
1723 CRM_Core_Config
::singleton()->userPermissionClass
->permissions
= array('access CiviEvent');
1724 $this->callAPIFailure('contact', 'getquick', array('name' => 'b', 'check_permissions' => TRUE));
1725 CRM_Core_Config
::singleton()->userPermissionClass
->permissions
= array('access CiviCRM');
1726 $this->callAPISuccess('contact', 'getquick', array('name' => 'b', 'check_permissions' => TRUE));
1727 CRM_Core_Config
::singleton()->userPermissionClass
->permissions
= array('access AJAX API');
1728 $this->callAPISuccess('contact', 'getquick', array('name' => 'b', 'check_permissions' => TRUE));
1732 * Test get ref api - gets a list of references to an entity
1734 function testGetReferenceCounts() {
1735 $result = $this->callAPISuccess('Contact', 'create', array(
1736 'first_name' => 'Testily',
1737 'last_name' => 'McHaste',
1738 'contact_type' => 'Individual',
1739 'api.Address.replace' => array(
1740 'values' => array(),
1742 'api.Email.replace' => array(
1745 'email' => 'spam@dev.null',
1747 'location_type_id' => 1,
1751 'api.Phone.replace' => array(
1754 'phone' => '234-567-0001',
1756 'location_type_id' => 1,
1759 'phone' => '234-567-0002',
1761 'location_type_id' => 1,
1767 //$dao = new CRM_Contact_BAO_Contact();
1768 //$dao->id = $result['id'];
1769 //$this->assertTrue((bool) $dao->find(TRUE));
1771 //$refCounts = $dao->getReferenceCounts();
1772 //$this->assertTrue(is_array($refCounts));
1773 //$refCountsIdx = CRM_Utils_Array::index(array('name'), $refCounts);
1775 $refCounts = $this->callAPISuccess('Contact', 'getrefcount', array(
1776 'id' => $result['id']
1778 $refCountsIdx = CRM_Utils_Array
::index(array('name'), $refCounts['values']);
1780 $this->assertEquals(1, $refCountsIdx['sql:civicrm_email:contact_id']['count']);
1781 $this->assertEquals('civicrm_email', $refCountsIdx['sql:civicrm_email:contact_id']['table']);
1782 $this->assertEquals(2, $refCountsIdx['sql:civicrm_phone:contact_id']['count']);
1783 $this->assertEquals('civicrm_phone', $refCountsIdx['sql:civicrm_phone:contact_id']['table']);
1784 $this->assertTrue(!isset($refCountsIdx['sql:civicrm_address:contact_id']));
1787 function testSQLOperatorsOnContactAPI() {
1788 $this->individualCreate();
1789 $this->organizationCreate();
1790 $this->householdCreate();
1791 $contacts = $this->callAPISuccess('contact', 'get', array('legal_name' => array('IS NOT NULL' => TRUE)));
1792 $this->assertEquals($contacts['count'], CRM_Core_DAO
::singleValueQuery('select count(*) FROM civicrm_contact WHERE legal_name IS NOT NULL'));
1793 $contacts = $this->callAPISuccess('contact', 'get', array('legal_name' => array('IS NULL' => TRUE)));
1794 $this->assertEquals($contacts['count'], CRM_Core_DAO
::singleValueQuery('select count(*) FROM civicrm_contact WHERE legal_name IS NULL'));
1798 * CRM-14743 - test api respects search operators
1800 function testGetModifiedDateByOperators() {
1801 $preExistingContactCount = CRM_Core_DAO
::singleValueQuery('select count(*) FROM civicrm_contact');
1802 $contact1 = $this->individualCreate();
1803 $sql = "UPDATE civicrm_contact SET created_date = '2012-01-01', modified_date = '2013-01-01' WHERE id = " . $contact1;
1804 CRM_Core_DAO
::executeQuery($sql);
1805 $contact2 = $this->individualCreate();
1806 $sql = "UPDATE civicrm_contact SET created_date = '2012-02-01', modified_date = '2013-02-01' WHERE id = " . $contact2;
1807 CRM_Core_DAO
::executeQuery($sql);
1808 $contact3 = $this->householdCreate();
1809 $sql = "UPDATE civicrm_contact SET created_date = '2012-03-01', modified_date = '2013-03-01' WHERE id = " . $contact3;
1810 CRM_Core_DAO
::executeQuery($sql);
1811 $contacts = $this->callAPISuccess('contact', 'get', array('modified_date' => array('<' => '2014-01-01')));
1812 $this->assertEquals($contacts['count'], 3);
1813 $contacts = $this->callAPISuccess('contact', 'get', array('modified_date' => array('>' => '2014-01-01')));
1814 $this->assertEquals($contacts['count'], $preExistingContactCount);
1818 * CRM-14743 - test api respects search operators
1820 function testGetCreatedDateByOperators() {
1821 $preExistingContactCount = CRM_Core_DAO
::singleValueQuery('select count(*) FROM civicrm_contact');
1822 $contact1 = $this->individualCreate();
1823 $sql = "UPDATE civicrm_contact SET created_date = '2012-01-01' WHERE id = " . $contact1;
1824 CRM_Core_DAO
::executeQuery($sql);
1825 $contact2 = $this->individualCreate();
1826 $sql = "UPDATE civicrm_contact SET created_date = '2012-02-01' WHERE id = " . $contact2;
1827 CRM_Core_DAO
::executeQuery($sql);
1828 $contact3 = $this->householdCreate();
1829 $sql = "UPDATE civicrm_contact SET created_date = '2012-03-01' WHERE id = " . $contact3;
1830 CRM_Core_DAO
::executeQuery($sql);
1831 $contacts = $this->callAPISuccess('contact', 'get', array('created_date' => array('<' => '2014-01-01')));
1832 $this->assertEquals($contacts['count'], 3);
1833 $contacts = $this->callAPISuccess('contact', 'get', array('created_date' => array('>' => '2014-01-01')));
1834 $this->assertEquals($contacts['count'], $preExistingContactCount);
1838 * CRM-14263 check that API is not affected by search profile related bug
1840 function testReturnCityProfile () {
1841 $contactID = $this->individualCreate();
1842 CRM_Core_Config
::singleton()->defaultSearchProfileID
= 1;
1843 $this->callAPISuccess('address', 'create', array('contact_id' => $contactID, 'city' => 'Cool City', 'location_type_id' => 1,));
1844 $result = $this->callAPISuccess('contact', 'get', array('city' => 'Cool City', 'return' => 'contact_type'));
1845 $this->assertEquals(1, $result['count']);
1849 * CRM-15443 - ensure getlist api does not return deleted contacts
1851 function testGetlistExcludeConditions() {
1852 $name = md5(time());
1853 $contact = $this->individualCreate(array('last_name' => $name));
1854 $deceasedContact = $this->individualCreate(array('last_name' => $name, 'is_deceased' => 1));
1855 $deletedContact = $this->individualCreate(array('last_name' => $name, 'is_deleted' => 1));
1856 // We should get all but the deleted contact
1857 $result = $this->callAPISuccess('contact', 'getlist', array('input' => $name));
1858 $this->assertEquals(2, $result['count'], 'In line ' . __LINE__
);
1859 // Force-exclude the deceased contact
1860 $result = $this->callAPISuccess('contact', 'getlist', array('input' => $name, 'params' => array('is_deceased' => 0)));
1861 $this->assertEquals(1, $result['count'], 'In line ' . __LINE__
);
1862 $this->assertEquals($contact, $result['values'][0]['id'], 'In line ' . __LINE__
);
1866 * Test contact.getactions
1868 function testGetActions() {
1869 $description = "Getting the available actions for an entity.";
1870 $result = $this->callAPIAndDocument($this->_entity
, 'getactions', array(), __FUNCTION__
, __FILE__
, $description);
1890 $deprecated = array(
1894 foreach ($expected as $action) {
1895 $this->assertTrue(in_array($action, $result['values']), "Expected action $action");
1897 foreach ($deprecated as $action) {
1898 $this->assertArrayKeyExists($action, $result['deprecated']);