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;
49 public $_eNoticeCompliant = TRUE;
50 protected $_contactID;
51 protected $_financialTypeId =1;
56 * Initialize configuration
58 function __construct() {
59 parent
::__construct();
63 * Test setup for every test
65 * Connect to the database, truncate the tables that will be used
66 * and redirect stdin to a temporary file
68 public function setUp() {
69 // Connect to the database
71 $this->_apiversion
= 3;
72 $this->_entity
= 'contact';
73 $this->_params
= array(
74 'first_name' => 'abc1',
75 'contact_type' => 'Individual',
76 'last_name' => 'xyz1',
81 // truncate a few tables
82 $tablesToTruncate = array(
85 'civicrm_contribution',
88 'civicrm_relationship',
93 $this->quickCleanup($tablesToTruncate, TRUE);
97 * Test civicrm_contact_create
99 * Verify that attempt to create individual contact with only
100 * first and last names succeeds
102 function testAddCreateIndividual() {
103 $oldCount = CRM_Core_DAO
::singleValueQuery('select count(*) from civicrm_contact');
105 'first_name' => 'abc1',
106 'contact_type' => 'Individual',
107 'last_name' => 'xyz1',
110 $contact = $this->callAPISuccess('contact', 'create', $params);
111 $this->assertTrue(is_numeric($contact['id']), "In line " . __LINE__
);
112 $this->assertTrue($contact['id'] > 0, "In line " . __LINE__
);
113 $newCount = CRM_Core_DAO
::singleValueQuery('select count(*) from civicrm_contact');
114 $this->assertEquals($oldCount+
1, $newCount);
116 $this->assertDBState('CRM_Contact_DAO_Contact',
123 * Test civicrm_contact_create with sub-types
125 * Verify that sub-types are created successfully and not deleted by subsequent updates
127 function testIndividualSubType() {
129 'first_name' => 'test abc',
130 'contact_type' => 'Individual',
131 'last_name' => 'test xyz',
132 'contact_sub_type' => array('Student', 'Staff'),
134 $contact = $this->callAPISuccess('contact', 'create', $params);
135 $cid = $contact['id'];
139 'middle_name' => 'foo',
141 $this->callAPISuccess('contact', 'create', $params);
142 unset($params['middle_name']);
144 $contact = $this->callAPISuccess('contact', 'get', $params);
146 $this->assertEquals(array('Student', 'Staff'), $contact['values'][$cid]['contact_sub_type'], "In line " . __LINE__
);
150 * Verify that attempt to create contact with empty params fails
152 function testCreateEmptyContact() {
153 $this->callAPIFailure('contact', 'create', array());
157 * Verify that attempt to create contact with bad contact type fails
159 function testCreateBadTypeContact() {
161 'email' => 'man1@yahoo.com',
162 'contact_type' => 'Does not Exist',
164 $result = $this->callAPIFailure('contact', 'create', $params,"'Does not Exist' is not a valid option for field contact_type");
168 * Verify that attempt to create individual contact with required
169 * fields missing fails
171 function testCreateBadRequiredFieldsIndividual() {
173 'middle_name' => 'This field is not required',
174 'contact_type' => 'Individual',
177 $contact = $this->callAPIFailure('contact', 'create', $params);
181 * Verify that attempt to create household contact with required
182 * fields missing fails
184 function testCreateBadRequiredFieldsHousehold() {
186 'middle_name' => 'This field is not required',
187 'contact_type' => 'Household',
189 $contact = $this->callAPIFailure('contact', 'create', $params);
193 * Verify that attempt to create organization contact with
194 * required fields missing fails
196 function testCreateBadRequiredFieldsOrganization() {
198 'middle_name' => 'This field is not required',
199 'contact_type' => 'Organization',
202 $contact = $this->callAPIFailure('contact', 'create', $params);
206 * Verify that attempt to create individual contact with only an
209 function testCreateEmailIndividual() {
212 'email' => 'man3@yahoo.com',
213 'contact_type' => 'Individual',
214 'location_type_id' => 1,
217 $contact = $this->callAPISuccess('contact', 'create', $params);
219 $this->assertEquals(1, $contact['id'], "In line " . __LINE__
);
220 $email = $this->callAPISuccess('email', 'get', array('contact_id' => $contact['id']));
221 $this->assertEquals(1, $email['count']);
222 $this->assertEquals('man3@yahoo.com', $email['values'][$email['id']]['email']);
224 $this->callAPISuccess('contact', 'delete', $contact);
228 * Verify that attempt to create individual contact with only
229 * first and last names succeeds
231 function testCreateNameIndividual() {
233 'first_name' => 'abc1',
234 'contact_type' => 'Individual',
235 'last_name' => 'xyz1',
238 $contact = $this->callAPISuccess('contact', 'create', $params);
239 $this->assertEquals(1, $contact['id']);
243 * Verify that attempt to create individual contact with
244 * first and last names and old key values works
246 function testCreateNameIndividualOldKeys() {
248 'individual_prefix' => 'Dr.',
249 'first_name' => 'abc1',
250 'contact_type' => 'Individual',
251 'last_name' => 'xyz1',
252 'individual_suffix' => 'Jr.',
255 $contact = $this->callAPISuccess('contact', 'create', $params);
256 $result = $this->callAPISuccess('contact', 'getsingle', array('id' => $contact['id']));
258 $this->assertArrayKeyExists('prefix_id', $result);
259 $this->assertArrayKeyExists('suffix_id', $result);
260 $this->assertArrayKeyExists('gender_id', $result);
261 $this->assertEquals(4, $result['prefix_id']);
262 $this->assertEquals(1, $result['suffix_id']);
266 * Verify that attempt to create individual contact with
267 * first and last names and old key values works
269 function testCreateNameIndividualrecommendedKeys2() {
271 'prefix_id' => 'Dr.',
272 'first_name' => 'abc1',
273 'contact_type' => 'Individual',
274 'last_name' => 'xyz1',
275 'suffix_id' => 'Jr.',
276 'gender_id' => 'Male',
279 $contact = $this->callAPISuccess('contact', 'create', $params);
280 $result = $this->callAPISuccess('contact', 'getsingle', array('id' => $contact['id']));
282 $this->assertArrayKeyExists('prefix_id', $result);
283 $this->assertArrayKeyExists('suffix_id', $result);
284 $this->assertArrayKeyExists('gender_id', $result);
285 $this->assertEquals(4, $result['prefix_id']);
286 $this->assertEquals(1, $result['suffix_id']);
290 * Verify that attempt to create household contact with only
291 * household name succeeds
293 function testCreateNameHousehold() {
295 'household_name' => 'The abc Household',
296 'contact_type' => 'Household',
298 $contact = $this->callAPISuccess('contact', 'create', $params);
299 $this->assertEquals(1, $contact['id'], "In line " . __LINE__
);
303 * Verify that attempt to create organization contact with only
304 * organization name succeeds
306 function testCreateNameOrganization() {
308 'organization_name' => 'The abc Organization',
309 'contact_type' => 'Organization',
311 $contact = $this->callAPISuccess('contact', 'create', $params);
312 $this->assertEquals(1, $contact['id']);
315 * Verify that attempt to create organization contact without organization name fails
317 function testCreateNoNameOrganization() {
319 'first_name' => 'The abc Organization',
320 'contact_type' => 'Organization',
322 $result = $this->callAPIFailure('contact', 'create', $params);
325 * check with complete array + custom field
326 * Note that the test is written on purpose without any
327 * variables specific to participant so it can be replicated into other entities
328 * and / or moved to the automated test suite
330 function testCreateWithCustom() {
331 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__
, __FILE__
);
333 $params = $this->_params
;
334 $params['custom_' . $ids['custom_field_id']] = "custom string";
335 $description = "/*this demonstrates setting a custom field through the API ";
336 $subfile = "CustomFieldCreate";
337 $result = $this->callAPIAndDocument($this->_entity
, 'create', $params, __FUNCTION__
, __FILE__
, $description);
339 $check = $this->callAPISuccess($this->_entity
, 'get', array('return.custom_' . $ids['custom_field_id'] => 1, 'id' => $result['id']));
340 $this->assertEquals("custom string", $check['values'][$check['id']]['custom_' . $ids['custom_field_id']], ' in line ' . __LINE__
);
342 $this->customFieldDelete($ids['custom_field_id']);
343 $this->customGroupDelete($ids['custom_group_id']);
347 * CRM-12773 - expectation is that civicrm quietly ignores
348 * fields without values
350 function testCreateWithNULLCustomCRM12773() {
351 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__
, __FILE__
);
352 $params = $this->_params
;
353 $params['custom_' . $ids['custom_field_id']] = NULL;
354 $result = $this->callAPISuccess('contact', 'create', $params);
355 $this->customFieldDelete($ids['custom_field_id']);
356 $this->customGroupDelete($ids['custom_group_id']);
361 * Test creating a current employer through API
363 function testContactCreateCurrentEmployer(){
364 //here we will just do the get for set-up purposes
365 $count = $this->callAPISuccess('contact', 'getcount', array(
366 'organization_name' => 'new employer org',
367 'contact_type' => 'Organization'
369 $this->assertEquals(0, $count);
370 $employerResult = $this->callAPISuccess('contact', 'create', array_merge($this->_params
, array(
371 'current_employer' => 'new employer org',)
374 $count = $this->callAPISuccess('contact', 'getcount', array(
375 'organization_name' => 'new employer org',
376 'contact_type' => 'Organization'
380 $result = $this->callAPISuccess('contact', 'getsingle', array(
381 'id' => $employerResult['id'],
384 $this->assertEquals('new employer org', $result['current_employer']);
388 * Check deceased contacts are not retrieved
389 * Note at time of writing the default is to return default. This should possibly be changed & test added
392 function testGetDeceasedRetrieved() {
393 $c1 = $this->callAPISuccess($this->_entity
, 'create', $this->_params
);
394 $c2 = $this->callAPISuccess($this->_entity
, 'create', array('first_name' => 'bb', 'last_name' => 'ccc', 'contact_type' => 'Individual', 'is_deceased' => 1));
395 $result = $this->callAPISuccess($this->_entity
, 'get', array('is_deceased' => 0));
396 $this->assertFalse(array_key_exists($c2['id'], $result['values']));
400 * Test that sort works - old syntax
402 function testGetSort() {
403 $c1 = $this->callAPISuccess($this->_entity
, 'create', $this->_params
);
404 $c2 = $this->callAPISuccess($this->_entity
, 'create', array('first_name' => 'bb', 'last_name' => 'ccc', 'contact_type' => 'Individual'));
405 $result = $this->callAPISuccess($this->_entity
, 'get', array(
406 'sort' => 'first_name ASC',
407 'return.first_name' => 1,
412 $this->assertEquals('abc1', $result['values'][0]['first_name']);
413 $result = $this->callAPISuccess($this->_entity
, 'get', array(
414 'sort' => 'first_name DESC',
415 'return.first_name' => 1,
419 $this->assertEquals('bb', $result['values'][0]['first_name']);
421 $this->callAPISuccess($this->_entity
, 'delete', array('id' => $c1['id']));
422 $this->callAPISuccess($this->_entity
, 'delete', array('id' => $c2['id']));
425 * Test that we can retrieve contacts using
426 * 'id' => array('IN' => array('3,4')) syntax
428 function testGetINIDArray() {
429 $c1 = $this->callAPISuccess($this->_entity
, 'create', $this->_params
);
430 $c2 = $this->callAPISuccess($this->_entity
, 'create', array('first_name' => 'bb', 'last_name' => 'ccc', 'contact_type' => 'Individual'));
431 $c3 = $this->callAPISuccess($this->_entity
, 'create', array('first_name' => 'hh', 'last_name' => 'll', 'contact_type' => 'Individual'));
432 $result = $this->callAPISuccess($this->_entity
, 'get', array('id' => array('IN' => array($c1['id'], $c3['id']))));
433 $this->assertEquals(2, $result['count']);
434 $this->assertEquals(array($c1['id'], $c3['id']), array_keys($result['values']));
435 $this->callAPISuccess($this->_entity
, 'delete', array('id' => $c1['id']));
436 $this->callAPISuccess($this->_entity
, 'delete', array('id' => $c2['id']));
437 $this->callAPISuccess($this->_entity
, 'delete', array('id' => $c3['id']));
440 * Test variants on deleted behaviour
442 function testGetDeleted() {
443 $params = $this->_params
;
444 $contact1 = $this->callAPISuccess('contact', 'create', $params);
445 $params['is_deleted'] = 1;
446 $params['last_name'] = 'bcd';
447 $contact2 = $this->callAPISuccess('contact', 'create', $params);
448 $countActive = $this->callAPISuccess('contact', 'getcount', array('showAll' => 'active'));
449 $countAll = $this->callAPISuccess('contact', 'getcount', array('showAll' => 'all'));
450 $countTrash = $this->callAPISuccess('contact', 'getcount', array('showAll' => 'trash'));
451 $countDefault = $this->callAPISuccess('contact', 'getcount', array());
452 $countDeleted = $this->callAPISuccess('contact', 'getcount', array(
453 'contact_is_deleted' => 1,
455 $countNotDeleted = $this->callAPISuccess('contact', 'getcount', array(
456 'contact_is_deleted' => 0,
458 $this->callAPISuccess('contact', 'delete', array('id' => $contact1['id']));
459 $this->callAPISuccess('contact', 'delete', array('id' => $contact2['id']));
460 $this->assertEquals(1, $countNotDeleted, 'contact_is_deleted => 0 is respected in line ' . __LINE__
);
461 $this->assertEquals(1, $countActive, 'in line ' . __LINE__
);
462 $this->assertEquals(1, $countTrash, 'in line ' . __LINE__
);
463 $this->assertEquals(2, $countAll, 'in line ' . __LINE__
);
464 $this->assertEquals(1, $countDeleted, 'in line ' . __LINE__
);
465 $this->assertEquals(1, $countDefault, 'Only active by default in line ' . __LINE__
);
468 * Test that sort works - new syntax
470 function testGetSortNewSYntax() {
471 $c1 = $this->callAPISuccess($this->_entity
, 'create', $this->_params
);
472 $c2 = $this->callAPISuccess($this->_entity
, 'create', array('first_name' => 'bb', 'last_name' => 'ccc', 'contact_type' => 'Individual'));
473 $result = $this->callAPISuccess($this->_entity
, 'getvalue', array(
474 'return' => 'first_name',
477 'sort' => 'first_name',
480 $this->assertEquals('abc1', $result, 'in line' . __LINE__
);
482 $result = $this->callAPISuccess($this->_entity
, 'getvalue', array(
483 'return' => 'first_name',
486 'sort' => 'first_name DESC',
489 $this->assertEquals('bb', $result);
491 $this->callAPISuccess($this->_entity
, 'delete', array('id' => $c1['id']));
492 $this->callAPISuccess($this->_entity
, 'delete', array('id' => $c2['id']));
495 * Test appostrophe works in get & create
497 function testGetAppostropheCRM10857() {
498 $params = array_merge($this->_params
, array('last_name' => "O'Connor"));
499 $contact = $this->callAPISuccess($this->_entity
, 'create', $params);
500 $result = $this->callAPISuccess($this->_entity
, 'getsingle', array(
501 'last_name' => "O'Connor",
504 $this->assertEquals("O'Connor", $result['last_name'], 'in line' . __LINE__
);
508 * check with complete array + custom field
509 * Note that the test is written on purpose without any
510 * variables specific to participant so it can be replicated into other entities
511 * and / or moved to the automated test suite
513 function testGetWithCustom() {
514 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__
, __FILE__
);
516 $params = $this->_params
;
517 $params['custom_' . $ids['custom_field_id']] = "custom string";
518 $description = "/*this demonstrates setting a custom field through the API ";
519 $subfile = "CustomFieldGet";
520 $result = $this->callAPISuccess($this->_entity
, 'create', $params);
522 $check = $this->callAPIAndDocument($this->_entity
, 'get', array('return.custom_' . $ids['custom_field_id'] => 1, 'id' => $result['id']), __FUNCTION__
, __FILE__
, $description, $subfile);
524 $this->assertEquals("custom string", $check['values'][$check['id']]['custom_' . $ids['custom_field_id']], ' in line ' . __LINE__
);
525 $fields = ($this->callAPISuccess('contact', 'getfields', $params));
526 $this->assertTrue(is_array($fields['values']['custom_' . $ids['custom_field_id']]));
527 $this->customFieldDelete($ids['custom_field_id']);
528 $this->customGroupDelete($ids['custom_group_id']);
531 * check with complete array + custom field
532 * Note that the test is written on purpose without any
533 * variables specific to participant so it can be replicated into other entities
534 * and / or moved to the automated test suite
536 function testGetWithCustomReturnSyntax() {
537 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__
, __FILE__
);
539 $params = $this->_params
;
540 $params['custom_' . $ids['custom_field_id']] = "custom string";
541 $description = "/*this demonstrates setting a custom field through the API ";
542 $subfile = "CustomFieldGetReturnSyntaxVariation";
543 $result = $this->callAPISuccess($this->_entity
, 'create', $params);
544 $params = array('return' => 'custom_' . $ids['custom_field_id'], 'id' => $result['id']);
545 $check = $this->callAPIAndDocument($this->_entity
, 'get', $params, __FUNCTION__
, __FILE__
, $description, $subfile);
547 $this->assertEquals("custom string", $check['values'][$check['id']]['custom_' . $ids['custom_field_id']], ' in line ' . __LINE__
);
548 $this->customFieldDelete($ids['custom_field_id']);
549 $this->customGroupDelete($ids['custom_group_id']);
552 function testGetGroupIDFromContact() {
553 $groupId = $this->groupCreate(NULL);
554 $description = "Get all from group and display contacts";
555 $subfile = "GroupFilterUsingContactAPI";
557 'email' => 'man2@yahoo.com',
558 'contact_type' => 'Individual',
559 'location_type_id' => 1,
560 'api.group_contact.create' => array('group_id' => $groupId),
563 $contact = $this->callAPISuccess('contact', 'create', $params);
564 // testing as integer
566 'filter.group_id' => $groupId,
567 'contact_type' => 'Individual',
569 $result = $this->callAPIAndDocument('contact', 'get', $params, __FUNCTION__
, __FILE__
, $description, $subfile);
570 $this->assertEquals(1, $result['count']);
571 // group 26 doesn't exist, but we can still search contacts in it.
573 'filter.group_id' => 26,
574 'contact_type' => 'Individual',
576 $result = $this->callAPISuccess('contact', 'get', $params);
579 'filter.group_id' => "$groupId, 26",
580 'contact_type' => 'Individual',
582 $result = $this->callAPIAndDocument('contact', 'get', $params, __FUNCTION__
, __FILE__
, $description, $subfile);
583 $this->assertEquals(1, $result['count']);
585 'filter.group_id' => "26,27",
586 'contact_type' => 'Individual',
588 $result = $this->callAPISuccess('contact', 'get', $params);
591 $params = array('filter.group_id' => array($groupId, 26),
592 'contact_type' => 'Individual',
594 $result = $this->callAPIAndDocument('contact', 'get', $params, __FUNCTION__
, __FILE__
, $description, $subfile);
595 $this->assertEquals(1, $result['count']);
597 //test in conjunction with other criteria
598 $params = array('filter.group_id' => array($groupId, 26),
599 'contact_type' => 'Organization',
601 $result = $this->callAPISuccess('contact', 'get', $params);
602 $params = array('filter.group_id' => array(26, 27),
603 'contact_type' => 'Individual',
605 $result = $this->callAPISuccess('contact', 'get', $params);
606 $this->assertEquals(0, $result['count'], " in line " . __LINE__
);
610 * Verify that attempt to create individual contact with two chained websites succeeds
612 function testCreateIndividualWithContributionDottedSyntax() {
613 $description = "test demonstrates the syntax to create 2 chained entities";
614 $subfile = "ChainTwoWebsites";
616 'first_name' => 'abc3',
617 'last_name' => 'xyz3',
618 'contact_type' => 'Individual',
619 'email' => 'man3@yahoo.com',
620 'api.contribution.create' => array(
621 'receive_date' => '2010-01-01',
622 'total_amount' => 100.00,
623 'financial_type_id' => $this->_financialTypeId
,
624 'payment_instrument_id' => 1,
625 'non_deductible_amount' => 10.00,
626 'fee_amount' => 50.00,
627 'net_amount' => 90.00,
629 'invoice_id' => 67990,
631 'contribution_status_id' => 1,
633 'api.website.create' => array(
634 'url' => "http://civicrm.org",
636 'api.website.create.2' => array(
637 'url' => "http://chained.org",
641 $result = $this->callAPIAndDocument('Contact', 'create', $params, __FUNCTION__
, __FILE__
, $description, $subfile);
643 $this->assertEquals(1, $result['id'], "In line " . __LINE__
);
644 // checking child function result not covered in callAPIAndDocument
645 $this->assertAPISuccess($result['values'][$result['id']]['api.website.create']);
646 $this->assertEquals("http://chained.org", $result['values'][$result['id']]['api.website.create.2']['values'][0]['url'], "In line " . __LINE__
);
647 $this->assertEquals("http://civicrm.org", $result['values'][$result['id']]['api.website.create']['values'][0]['url'], "In line " . __LINE__
);
649 // delete the contact
650 $this->callAPISuccess('contact', 'delete', $result);
654 * Verify that attempt to create individual contact with chained contribution and website succeeds
656 function testCreateIndividualWithContributionChainedArrays() {
658 'first_name' => 'abc3',
659 'last_name' => 'xyz3',
660 'contact_type' => 'Individual',
661 'email' => 'man3@yahoo.com',
662 'api.contribution.create' => array(
663 'receive_date' => '2010-01-01',
664 'total_amount' => 100.00,
665 'financial_type_id' => $this->_financialTypeId
,
666 'payment_instrument_id' => 1,
667 'non_deductible_amount' => 10.00,
668 'fee_amount' => 50.00,
669 'net_amount' => 90.00,
671 'invoice_id' => 67890,
673 'contribution_status_id' => 1,
675 'api.website.create' => array(
677 'url' => "http://civicrm.org",
680 'url' => "http://chained.org",
681 'website_type_id' => 2,
686 $description = "demonstrates creating two websites as an array";
687 $subfile = "ChainTwoWebsitesSyntax2";
688 $result = $this->callAPIAndDocument('Contact', 'create', $params, __FUNCTION__
, __FILE__
, $description, $subfile);
690 $this->assertEquals(1, $result['id']);
691 // the callAndDocument doesn't check the chained call
692 $this->assertEquals(0, $result['values'][$result['id']]['api.website.create'][0]['is_error'], "In line " . __LINE__
);
693 $this->assertEquals("http://chained.org", $result['values'][$result['id']]['api.website.create'][1]['values'][0]['url'], "In line " . __LINE__
);
694 $this->assertEquals("http://civicrm.org", $result['values'][$result['id']]['api.website.create'][0]['values'][0]['url'], "In line " . __LINE__
);
696 $this->callAPISuccess('contact', 'delete', $result);
700 * Verify that attempt to create individual contact with first
701 * and last names and email succeeds
703 function testCreateIndividualWithNameEmail() {
705 'first_name' => 'abc3',
706 'last_name' => 'xyz3',
707 'contact_type' => 'Individual',
708 'email' => 'man3@yahoo.com',
711 $contact = $this->callAPISuccess('contact', 'create', $params);
712 $this->assertEquals(1, $contact['id'], "In line " . __LINE__
);
714 // delete the contact
715 $this->callAPISuccess('contact', 'delete', $contact);
718 * Verify that attempt to create individual contact with no data fails
720 function testCreateIndividualWithOutNameEmail() {
722 'contact_type' => 'Individual',
725 $result = $this->callAPIFailure('contact', 'create', $params);
728 * Verify that attempt to create individual contact with first
729 * and last names, email and location type succeeds
731 function testCreateIndividualWithNameEmailLocationType() {
733 'first_name' => 'abc4',
734 'last_name' => 'xyz4',
735 'email' => 'man4@yahoo.com',
736 'contact_type' => 'Individual',
737 'location_type_id' => 1,
739 $result = $this->callAPISuccess('contact', 'create', $params);
741 $this->assertEquals(1, $result['id'], "In line " . __LINE__
);
743 $this->callAPISuccess('contact', 'delete', array('id' => $result['id']));
747 * Verify that when changing employers
748 * the old employer relationship becomes inactive
750 function testCreateIndividualWithEmployer() {
751 $employer = $this->organizationCreate();
752 $employer2 = $this->organizationCreate();
755 'email' => 'man4@yahoo.com',
756 'contact_type' => 'Individual',
757 'employer_id' => $employer,
760 $result = $this->callAPISuccess('contact', 'create', $params);
761 $relationships = $this->callAPISuccess('relationship', 'get', array(
762 'contact_id_a' => $result['id'],
766 $this->assertEquals($employer, $relationships['values'][0]['contact_id_b']);
768 // Add more random relationships to make the test more realistic
769 foreach (array('Employee of', 'Volunteer for') as $rtype) {
770 $relTypeId = CRM_Core_DAO
::getFieldValue('CRM_Contact_DAO_RelationshipType', $rtype, 'id', 'name_a_b');
771 $random_rel = $this->callAPISuccess('relationship', 'create', array(
772 'contact_id_a' => $result['id'],
773 'contact_id_b' => $this->organizationCreate(),
775 'relationship_type_id' => $relTypeId,
779 // Add second employer
780 $params['employer_id'] = $employer2;
781 $params['id'] = $result['id'];
782 $result = $this->callAPISuccess('contact', 'create', $params);
784 $relationships = $this->callAPISuccess('relationship', 'get', array(
785 'contact_id_a' => $result['id'],
790 $this->assertEquals($employer, $relationships['values'][0]['contact_id_b']);
794 * Verify that attempt to create household contact with details
797 function testCreateHouseholdDetails() {
799 'household_name' => 'abc8\'s House',
800 'nick_name' => 'x House',
801 'email' => 'man8@yahoo.com',
802 'contact_type' => 'Household',
805 $contact = $this->callAPISuccess('contact', 'create', $params);
807 $this->assertEquals(1, $contact['id'], "In line " . __LINE__
);
809 $this->callAPISuccess('contact', 'delete', $contact);
812 * Verify that attempt to create household contact with inadequate details
815 function testCreateHouseholdInadequateDetails() {
817 'nick_name' => 'x House',
818 'email' => 'man8@yahoo.com',
819 'contact_type' => 'Household',
822 $result = $this->callAPIFailure('contact', 'create', $params);
826 * Verify successful update of individual contact
828 function testUpdateIndividualWithAll() {
829 // Insert a row in civicrm_contact creating individual contact
830 $op = new PHPUnit_Extensions_Database_Operation_Insert();
831 $op->execute($this->_dbconn
,
832 new PHPUnit_Extensions_Database_DataSet_XMLDataSet(
833 dirname(__FILE__
) . '/dataset/contact_ind.xml'
839 'first_name' => 'abcd',
840 'contact_type' => 'Individual',
841 'nick_name' => 'This is nickname first',
842 'do_not_email' => '1',
843 'do_not_phone' => '1',
844 'do_not_mail' => '1',
845 'do_not_trade' => '1',
846 'legal_identifier' => 'ABC23853ZZ2235',
847 'external_identifier' => '1928837465',
848 'image_URL' => 'http://some.url.com/image.jpg',
849 'home_url' => 'http://www.example.org',
852 $getResult = $this->callAPISuccess('Contact', 'Get', array());
853 $result = $this->callAPISuccess('Contact', 'Update', $params);
854 $getResult = $this->callAPISuccess('Contact', 'Get', $params);
855 unset($params['contact_id']);
856 //Todo - neither API v2 or V3 are testing for home_url - not sure if it is being set.
857 //reducing this test partially back to apiv2 level to get it through
858 unset($params['home_url']);
859 foreach ($params as $key => $value) {
860 $this->assertEquals($value, $result['values'][23][$key], "In line " . __LINE__
);
862 // Check updated civicrm_contact against expected
863 $expected = new PHPUnit_Extensions_Database_DataSet_XMLDataSet(
864 dirname(__FILE__
) . '/dataset/contact_ind_upd.xml'
866 $actual = new PHPUnit_Extensions_Database_DataSet_QueryDataset(
869 $actual->addTable('civicrm_contact');
870 $expected->matches($actual);
874 * Verify successful update of organization contact
876 function testUpdateOrganizationWithAll() {
877 // Insert a row in civicrm_contact creating organization contact
878 $op = new PHPUnit_Extensions_Database_Operation_Insert();
879 $op->execute($this->_dbconn
,
880 new PHPUnit_Extensions_Database_DataSet_XMLDataSet(
881 dirname(__FILE__
) . '/dataset/contact_org.xml'
887 'organization_name' => 'WebAccess India Pvt Ltd',
888 'legal_name' => 'WebAccess',
889 'sic_code' => 'ABC12DEF',
890 'contact_type' => 'Organization',
893 $result = $this->callAPISuccess('Contact', 'Update', $params);
895 // Check updated civicrm_contact against expected
896 $expected = new PHPUnit_Extensions_Database_DataSet_XMLDataSet(
897 dirname(__FILE__
) . '/dataset/contact_org_upd.xml'
899 $actual = new PHPUnit_Extensions_Database_DataSet_QueryDataset(
902 $actual->addTable('civicrm_contact');
903 $expected->matches($actual);
907 * Verify successful update of household contact
909 function testUpdateHouseholdwithAll() {
910 // Insert a row in civicrm_contact creating household contact
911 $op = new PHPUnit_Extensions_Database_Operation_Insert();
912 $op->execute($this->_dbconn
,
913 new PHPUnit_Extensions_Database_DataSet_XMLDataSet(
914 dirname(__FILE__
) . '/dataset/contact_hld.xml'
920 'household_name' => 'ABC household',
921 'nick_name' => 'ABC House',
922 'contact_type' => 'Household',
925 $result = $this->callAPISuccess('Contact', 'Update', $params);
927 // Check updated civicrm_contact against expected
928 $expected = new PHPUnit_Extensions_Database_DataSet_XMLDataSet(
929 dirname(__FILE__
) . '/dataset/contact_hld_upd.xml'
931 $actual = new PHPUnit_Extensions_Database_DataSet_QueryDataset(
934 $actual->addTable('civicrm_contact');
935 $expected->matches($actual);
939 * Test civicrm_update() Deliberately exclude contact_type as it should still
940 * cope using civicrm_api CRM-7645
943 public function testUpdateCreateWithID() {
944 // Insert a row in civicrm_contact creating individual contact
945 $op = new PHPUnit_Extensions_Database_Operation_Insert();
946 $op->execute($this->_dbconn
,
947 new PHPUnit_Extensions_Database_DataSet_XMLDataSet(
948 dirname(__FILE__
) . '/dataset/contact_ind.xml'
956 'first_name' => 'abcd',
957 'last_name' => 'wxyz',
960 $result = $this->callAPISuccess('Contact', 'Update', $params);
964 * Test civicrm_contact_delete() with no contact ID
966 function testContactDeleteNoID() {
970 $result = $this->callAPIFailure('contact', 'delete', $params);
974 * Test civicrm_contact_delete() with error
976 function testContactDeleteError() {
977 $params = array('contact_id' => 999);
978 $result = $this->callAPIFailure('contact', 'delete', $params);
982 * Test civicrm_contact_delete()
984 function testContactDelete() {
985 $contactID = $this->individualCreate();
989 $result = $this->callAPIAndDocument('contact', 'delete', $params, __FUNCTION__
, __FILE__
);
993 * Test civicrm_contact_get() return only first name
995 public function testContactGetRetFirst() {
996 $contact = $this->callAPISuccess('contact', 'create', $this->_params
);
998 'contact_id' => $contact['id'],
999 'return_first_name' => TRUE,
1000 'sort' => 'first_name',
1002 $result = $this->callAPISuccess('contact', 'get', $params);
1003 $this->assertEquals(1, $result['count'], "In line " . __LINE__
);
1004 $this->assertEquals($contact['id'], $result['id'], "In line " . __LINE__
);
1005 $this->assertEquals('abc1', $result['values'][$contact['id']]['first_name'], "In line " . __LINE__
);
1009 * Test civicrm_contact_get() return only first name & last name
1010 * Use comma separated string return with a space
1012 public function testContactGetRetFirstLast() {
1013 $contact = $this->callAPISuccess('contact', 'create', $this->_params
);
1015 'contact_id' => $contact['id'],
1016 'return' => 'first_name, last_name',
1018 $result = $this->callAPISuccess('contact', 'getsingle', $params);
1019 $this->assertEquals('abc1', $result['first_name'], "In line " . __LINE__
);
1020 $this->assertEquals('xyz1', $result['last_name'], "In line " . __LINE__
);
1021 //check that other defaults not returns
1022 $this->assertArrayNotHasKey('sort_name', $result);
1024 'contact_id' => $contact['id'],
1025 'return' => 'first_name,last_name',
1027 $result = $this->callAPISuccess('contact', 'getsingle', $params);
1028 $this->assertEquals('abc1', $result['first_name'], "In line " . __LINE__
);
1029 $this->assertEquals('xyz1', $result['last_name'], "In line " . __LINE__
);
1030 //check that other defaults not returns
1031 $this->assertArrayNotHasKey('sort_name', $result);
1035 * Test civicrm_contact_get() return only first name & last name
1036 * Use comma separated string return without a space
1038 public function testContactGetRetFirstLastNoComma() {
1039 $contact = $this->callAPISuccess('contact', 'create', $this->_params
);
1041 'contact_id' => $contact['id'],
1042 'return' => 'first_name,last_name',
1044 $result = $this->callAPISuccess('contact', 'getsingle', $params);
1045 $this->assertEquals('abc1', $result['first_name'], "In line " . __LINE__
);
1046 $this->assertEquals('xyz1', $result['last_name'], "In line " . __LINE__
);
1047 //check that other defaults not returns
1048 $this->assertArrayNotHasKey('sort_name', $result);
1052 * Test civicrm_contact_get() with default return properties
1054 public function testContactGetRetDefault() {
1055 // Insert a row in civicrm_contact creating contact 17
1056 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1057 $op->execute($this->_dbconn
,
1058 new PHPUnit_Extensions_Database_DataSet_XMLDataSet(
1059 dirname(__FILE__
) . '/dataset/contact_17.xml'
1064 'sort' => 'first_name',
1066 $result = $this->callAPISuccess('contact', 'get', $params);
1067 $this->assertEquals(17, $result['values'][17]['contact_id'], "In line " . __LINE__
);
1068 $this->assertEquals('Test', $result['values'][17]['first_name'], "In line " . __LINE__
);
1072 * Test civicrm_contact_quicksearch() with empty name param
1074 public function testContactGetQuickEmpty() {
1075 $result = $this->callAPIFailure('contact', 'getquick', array());
1079 * Test civicrm_contact_quicksearch() with empty name param
1081 public function testContactGetQuick() {
1082 // Insert a row in civicrm_contact creating individual contact
1083 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1084 $op->execute($this->_dbconn
,
1085 new PHPUnit_Extensions_Database_DataSet_XMLDataSet(
1086 dirname(__FILE__
) . '/dataset/contact_17.xml'
1089 $op->execute($this->_dbconn
,
1090 new PHPUnit_Extensions_Database_DataSet_XMLDataSet(
1091 dirname(__FILE__
) . '/dataset/email_contact_17.xml'
1098 $result = $this->callAPISuccess('contact', 'quicksearch', $params);
1099 $this->assertEquals(17, $result['values'][0]['id'], 'in line ' . __LINE__
);
1103 * Test civicrm_contact_get) with empty params
1105 public function testContactGetEmptyParams() {
1106 $result = $this->callAPISuccess('contact', 'get', array());
1110 * Test civicrm_contact_get(,true) with no matches
1112 public function testContactGetOldParamsNoMatches() {
1113 // Insert a row in civicrm_contact creating contact 17
1114 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1115 $op->execute($this->_dbconn
,
1116 new PHPUnit_Extensions_Database_DataSet_XMLDataSet(
1117 dirname(__FILE__
) . '/dataset/contact_17.xml'
1122 'first_name' => 'Fred',
1124 $result = $this->callAPISuccess('contact', 'get', $params);
1125 $this->assertEquals(0, $result['count'], 'in line ' . __LINE__
);
1129 * Test civicrm_contact_get(,true) with one match
1131 public function testContactGetOldParamsOneMatch() {
1132 // Insert a row in civicrm_contact creating contact 17
1133 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1134 $op->execute($this->_dbconn
,
1135 new PHPUnit_Extensions_Database_DataSet_XMLDataSet(dirname(__FILE__
) . '/dataset/contact_17.xml'
1140 'first_name' => 'Test',
1142 $result = $this->callAPISuccess('contact', 'get', $params);
1143 $this->assertEquals(17, $result['values'][17]['contact_id'], 'in line ' . __LINE__
);
1144 $this->assertEquals(17, $result['id'], 'in line ' . __LINE__
);
1148 * Test civicrm_contact_search_count()
1150 public function testContactGetEmail() {
1152 'email' => 'man2@yahoo.com',
1153 'contact_type' => 'Individual',
1154 'location_type_id' => 1,
1157 $contact = $this->callAPISuccess('contact', 'create', $params);
1159 $this->assertEquals(1, $contact['id'], "In line " . __LINE__
);
1162 'email' => 'man2@yahoo.com',
1164 $result = $this->callAPIAndDocument('contact', 'get', $params, __FUNCTION__
, __FILE__
);
1165 $this->assertEquals(1, $result['values'][1]['contact_id'], "In line " . __LINE__
);
1166 $this->assertEquals('man2@yahoo.com', $result['values'][1]['email'], "In line " . __LINE__
);
1168 // delete the contact
1169 $this->callAPISuccess('contact', 'delete', $contact);
1173 * Test for Contact.get id=@user:username
1175 function testContactGetByUsername() {
1176 // setup - create contact with a uf-match
1177 $cid = $this->individualCreate(array(
1178 'contact_type' => 'Individual',
1179 'first_name' => 'testGetByUsername',
1180 'last_name' => 'testGetByUsername',
1183 $ufMatchParams = array(
1184 'domain_id' => CRM_Core_Config
::domainID(),
1186 'uf_name' => 'the-email-matching-key-is-not-really-the-username',
1187 'contact_id' => $cid,
1189 $ufMatch = CRM_Core_BAO_UFMatch
::create($ufMatchParams);
1190 $this->assertTrue(is_numeric($ufMatch->id
));
1192 // setup - mock the calls to CRM_Utils_System_*::getUfId
1193 $userSystem = $this->getMock('CRM_Utils_System_UnitTests', array('getUfId'));
1194 $userSystem->expects($this->once())
1196 ->with($this->equalTo('exampleUser'))
1197 ->will($this->returnValue(99));
1198 CRM_Core_Config
::singleton()->userSystem
= $userSystem;
1201 $result = $this->callAPISuccess('Contact', 'get', array(
1202 'id' => '@user:exampleUser',
1204 $this->assertEquals('testGetByUsername', $result['values'][$cid]['first_name']);
1208 * Test to check return works OK
1210 function testContactGetReturnValues() {
1211 $extraParams = array('nick_name' => 'Bob', 'phone' => '456', 'email' => 'e@mail.com');
1212 $contactID = $this->individualCreate($extraParams);
1213 //actually it turns out the above doesn't create a phone
1214 $phones = $this->callAPISuccess('phone', 'create', array('contact_id' => $contactID, 'phone' => '456',));
1215 $result = $this->callAPISuccess('contact', 'getsingle', array('id' => $contactID));
1216 foreach ($extraParams as $key => $value) {
1217 $this->assertEquals($result[$key], $value);
1219 //now we check they are still returned with 'return' key
1220 $result = $this->callAPISuccess('contact', 'getsingle', array('id' => $contactID, 'return' => array_keys($extraParams)));
1221 foreach ($extraParams as $key => $value) {
1222 $this->assertEquals($result[$key], $value);
1226 function testCRM13252MultipleChainedPhones() {
1227 $contactID = $this->householdCreate();
1228 $this->callAPISuccessGetCount('phone', array('contact_id' => $contactID), 0);
1230 'contact_id' => $contactID,
1231 'household_name' => 'Household 1',
1232 'contact_type' => 'Household',
1233 'api.phone.create' => array(
1235 'phone' => '111-111-1111',
1236 'location_type_id' => 1,
1237 'phone_type_id' => 1,
1240 'phone' => '222-222-2222',
1241 'location_type_id' => 1,
1242 'phone_type_id' => 2,
1246 $result = $this->callAPISuccess('contact', 'create', $params);
1247 $this->callAPISuccessGetCount('phone', array('contact_id' => $contactID), 2);
1251 * Test for Contact.get id=@user:username (with an invalid username)
1253 function testContactGetByUnknownUsername() {
1254 // setup - mock the calls to CRM_Utils_System_*::getUfId
1255 $userSystem = $this->getMock('CRM_Utils_System_UnitTests', array('getUfId'));
1256 $userSystem->expects($this->once())
1258 ->with($this->equalTo('exampleUser'))
1259 ->will($this->returnValue(NULL));
1260 CRM_Core_Config
::singleton()->userSystem
= $userSystem;
1263 $result = $this->callAPIFailure('Contact', 'get', array(
1264 'id' => '@user:exampleUser',
1266 $this->assertRegExp('/cannot be resolved to a contact ID/', $result['error_message']);
1270 * Verify attempt to create individual with chained arrays
1272 function testGetIndividualWithChainedArrays() {
1273 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__
, __FILE__
);
1274 $params['custom_' . $ids['custom_field_id']] = "custom string";
1276 $moreids = $this->CustomGroupMultipleCreateWithFields();
1277 $description = "/*this demonstrates the usage of chained api functions. In this case no notes or custom fields have been created ";
1278 $subfile = "APIChainedArray";
1280 'first_name' => 'abc3',
1281 'last_name' => 'xyz3',
1282 'contact_type' => 'Individual',
1283 'email' => 'man3@yahoo.com',
1284 'api.contribution.create' => array(
1285 'receive_date' => '2010-01-01',
1286 'total_amount' => 100.00,
1287 'financial_type_id' => 1,
1288 'payment_instrument_id' => 1,
1289 'non_deductible_amount' => 10.00,
1290 'fee_amount' => 50.00,
1291 'net_amount' => 90.00,
1293 'invoice_id' => 67890,
1295 'contribution_status_id' => 1,
1297 'api.contribution.create.1' => array(
1298 'receive_date' => '2011-01-01',
1299 'total_amount' => 120.00,
1300 'financial_type_id' => $this->_financialTypeId
=1,
1301 'payment_instrument_id' => 1,
1302 'non_deductible_amount' => 10.00,
1303 'fee_amount' => 50.00,
1304 'net_amount' => 90.00,
1306 'invoice_id' => 67830,
1308 'contribution_status_id' => 1,
1310 'api.website.create' => array(
1312 'url' => "http://civicrm.org",
1317 $result = $this->callAPISuccess('Contact', 'create', $params);
1319 'id' => $result['id'],
1320 'api.website.get' => array(),
1321 'api.Contribution.get' => array(
1322 'total_amount' => '120.00',
1323 ), 'api.CustomValue.get' => 1,
1324 'api.Note.get' => 1,
1326 $result = $this->callAPIAndDocument('Contact', 'Get', $params, __FUNCTION__
, __FILE__
, $description, $subfile);
1327 // delete the contact
1328 $this->callAPISuccess('contact', 'delete', $result);
1329 $this->customGroupDelete($ids['custom_group_id']);
1330 $this->customGroupDelete($moreids['custom_group_id']);
1331 $this->assertEquals(1, $result['id'], "In line " . __LINE__
);
1332 $this->assertEquals(0, $result['values'][$result['id']]['api.website.get']['is_error'], "In line " . __LINE__
);
1333 $this->assertEquals("http://civicrm.org", $result['values'][$result['id']]['api.website.get']['values'][0]['url'], "In line " . __LINE__
);
1336 function testGetIndividualWithChainedArraysFormats() {
1337 $description = "/*this demonstrates the usage of chained api functions. A variety of return formats are used. Note that no notes
1338 *custom fields or memberships exist";
1339 $subfile = "APIChainedArrayFormats";
1340 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__
, __FILE__
);
1341 $params['custom_' . $ids['custom_field_id']] = "custom string";
1343 $moreids = $this->CustomGroupMultipleCreateWithFields();
1345 'first_name' => 'abc3',
1346 'last_name' => 'xyz3',
1347 'contact_type' => 'Individual',
1348 'email' => 'man3@yahoo.com',
1349 'api.contribution.create' => array(
1350 'receive_date' => '2010-01-01',
1351 'total_amount' => 100.00,
1352 'financial_type_id' => $this->_financialTypeId
,
1353 'payment_instrument_id' => 1,
1354 'non_deductible_amount' => 10.00,
1355 'fee_amount' => 50.00,
1356 'net_amount' => 90.00,
1358 'contribution_status_id' => 1,
1360 'api.contribution.create.1' => array(
1361 'receive_date' => '2011-01-01',
1362 'total_amount' => 120.00,
1363 'financial_type_id' => $this->_financialTypeId
,
1364 'payment_instrument_id' => 1,
1365 'non_deductible_amount' => 10.00,
1366 'fee_amount' => 50.00,
1367 'net_amount' => 90.00,
1369 'contribution_status_id' => 1,
1371 'api.website.create' => array(
1373 'url' => "http://civicrm.org",
1379 $result = $this->callAPISuccess('Contact', 'create', $params);
1381 'id' => $result['id'],
1382 'api.website.getValue' => array('return' => 'url'),
1383 'api.Contribution.getCount' => array(),
1384 'api.CustomValue.get' => 1,
1385 'api.Note.get' => 1,
1386 'api.Membership.getCount' => array(),
1388 $result = $this->callAPIAndDocument('Contact', 'Get', $params, __FUNCTION__
, __FILE__
, $description, $subfile);
1389 $this->assertEquals(1, $result['id'], "In line " . __LINE__
);
1390 $this->assertEquals(2, $result['values'][$result['id']]['api.Contribution.getCount'], "In line " . __LINE__
);
1391 $this->assertEquals(0, $result['values'][$result['id']]['api.Note.get']['is_error'], "In line " . __LINE__
);
1392 $this->assertEquals("http://civicrm.org", $result['values'][$result['id']]['api.website.getValue'], "In line " . __LINE__
);
1394 $this->callAPISuccess('contact', 'delete', $result);
1395 $this->customGroupDelete($ids['custom_group_id']);
1396 $this->customGroupDelete($moreids['custom_group_id']);
1399 function testGetIndividualWithChainedArraysAndMultipleCustom() {
1400 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__
, __FILE__
);
1401 $params['custom_' . $ids['custom_field_id']] = "custom string";
1402 $moreids = $this->CustomGroupMultipleCreateWithFields();
1403 $andmoreids = $this->CustomGroupMultipleCreateWithFields(array('title' => "another group", 'name' => 'another name'));
1404 $description = "/*this demonstrates the usage of chained api functions. A variety of techniques are used";
1405 $subfile = "APIChainedArrayMultipleCustom";
1407 'first_name' => 'abc3',
1408 'last_name' => 'xyz3',
1409 'contact_type' => 'Individual',
1410 'email' => 'man3@yahoo.com',
1411 'api.contribution.create' => array(
1412 'receive_date' => '2010-01-01',
1413 'total_amount' => 100.00,
1414 'financial_type_id' => 1,
1415 'payment_instrument_id' => 1,
1416 'non_deductible_amount' => 10.00,
1417 'fee_amount' => 50.00,
1418 'net_amount' => 90.00,
1420 'invoice_id' => 67890,
1422 'contribution_status_id' => 1,
1424 'api.contribution.create.1' => array(
1425 'receive_date' => '2011-01-01',
1426 'total_amount' => 120.00,
1427 'financial_type_id' => 1,
1428 'payment_instrument_id' => 1,
1429 'non_deductible_amount' => 10.00,
1430 'fee_amount' => 50.00,
1431 'net_amount' => 90.00,
1433 'invoice_id' => 67830,
1435 'contribution_status_id' => 1,
1437 'api.website.create' => array(
1439 'url' => "http://civicrm.org",
1442 'custom_' . $ids['custom_field_id'] => "value 1",
1443 'custom_' . $moreids['custom_field_id'][0] => "value 2",
1444 'custom_' . $moreids['custom_field_id'][1] => "warm beer",
1445 'custom_' . $andmoreids['custom_field_id'][1] => "vegemite",
1449 $result = $this->callAPISuccess('Contact', 'create', $params);
1450 $result = $this->callAPISuccess('Contact', 'create', array(
1451 'contact_type' => 'Individual', 'id' => $result['id'], 'custom_' . $moreids['custom_field_id'][0] => "value 3", 'custom_' . $ids['custom_field_id'] => "value 4",
1455 'id' => $result['id'],
1456 'api.website.getValue' => array('return' => 'url'),
1457 'api.Contribution.getCount' => array(),
1458 'api.CustomValue.get' => 1,
1460 $result = $this->callAPIAndDocument('Contact', 'Get', $params, __FUNCTION__
, __FILE__
, $description, $subfile);
1462 $this->customGroupDelete($ids['custom_group_id']);
1463 $this->customGroupDelete($moreids['custom_group_id']);
1464 $this->customGroupDelete($andmoreids['custom_group_id']);
1465 $this->assertEquals(1, $result['id'], "In line " . __LINE__
);
1466 $this->assertEquals(0, $result['values'][$result['id']]['api.CustomValue.get']['is_error'], "In line " . __LINE__
);
1467 $this->assertEquals('http://civicrm.org', $result['values'][$result['id']]['api.website.getValue'], "In line " . __LINE__
);
1470 * Test checks siusage of $values to pick & choose inputs
1472 function testChainingValuesCreate() {
1473 $description = "/*this demonstrates the usage of chained api functions. Specifically it has one 'parent function' &
1474 2 child functions - one receives values from the parent (Contact) and the other child (Tag). ";
1475 $subfile = "APIChainedArrayValuesFromSiblingFunction";
1477 'display_name' => 'batman', 'contact_type' => 'Individual',
1478 'api.tag.create' => array('name' => '$value.id', 'description' => '$value.display_name', 'format.only_id' => 1),
1479 'api.entity_tag.create' => array('tag_id' => '$value.api.tag.create'),
1481 $result = $this->callAPIAndDocument('Contact', 'Create', $params, __FUNCTION__
, __FILE__
, $description, $subfile);
1482 $this->assertEquals(0, $result['values'][$result['id']]['api.entity_tag.create']['is_error']);
1484 $tablesToTruncate = array(
1487 'civicrm_entity_tag',
1490 $this->quickCleanup($tablesToTruncate, TRUE);
1494 * test TrueFalse format - I couldn't come up with an easy way to get an error on Get
1496 function testContactGetFormatIsSuccessTrue() {
1497 $this->createContactFromXML();
1498 $description = "This demonstrates use of the 'format.is_success' param.
1499 This param causes only the success or otherwise of the function to be returned as BOOLEAN";
1500 $subfile = "FormatIsSuccess_True";
1501 $params = array('id' => 17, 'format.is_success' => 1);
1502 $result = $this->callAPIAndDocument('Contact', 'Get', $params, __FUNCTION__
, __FILE__
, $description, $subfile);
1503 $this->assertEquals(1, $result);
1504 $this->callAPISuccess('Contact', 'Delete', $params);
1507 * test TrueFalse format
1509 function testContactCreateFormatIsSuccessFalse() {
1511 $description = "This demonstrates use of the 'format.is_success' param.
1512 This param causes only the success or otherwise of the function to be returned as BOOLEAN";
1513 $subfile = "FormatIsSuccess_Fail";
1514 $params = array('id' => 500, 'format.is_success' => 1);
1515 $result = $this->callAPIAndDocument('Contact', 'Create', $params, __FUNCTION__
, __FILE__
, $description, $subfile);
1516 $this->assertEquals(0, $result);
1519 * test Single Entity format
1521 function testContactGetSingle_entity_array() {
1522 $this->createContactFromXML();
1523 $description = "This demonstrates use of the 'format.single_entity_array' param.
1524 /* This param causes the only contact to be returned as an array without the other levels.
1525 /* it will be ignored if there is not exactly 1 result";
1526 $subfile = "GetSingleContact";
1527 $params = array('id' => 17);
1528 $result = $this->callAPIAndDocument('Contact', 'GetSingle', $params, __FUNCTION__
, __FILE__
, $description, $subfile);
1529 $this->assertEquals('Test Contact', $result['display_name'], "in line " . __LINE__
);
1530 $this->callAPISuccess('Contact', 'Delete', $params);
1534 * test Single Entity format
1536 function testContactGetFormatcount_only() {
1537 $this->createContactFromXML();
1538 $description = "/*This demonstrates use of the 'getCount' action
1539 /* This param causes the count of the only function to be returned as an integer";
1540 $subfile = "GetCountContact";
1541 $params = array('id' => 17);
1542 $result = $this->callAPIAndDocument('Contact', 'GetCount', $params, __FUNCTION__
, __FILE__
, $description, $subfile);
1543 $this->assertEquals('1', $result, "in line " . __LINE__
);
1544 $this->callAPISuccess('Contact', 'Delete', $params);
1547 * Test id only format
1549 function testContactGetFormatID_only() {
1550 $this->createContactFromXML();
1551 $description = "This demonstrates use of the 'format.id_only' param.
1552 /* This param causes the id of the only entity to be returned as an integer.
1553 /* it will be ignored if there is not exactly 1 result";
1554 $subfile = "FormatOnlyID";
1555 $params = array('id' => 17, 'format.only_id' => 1);
1556 $result = $this->callAPIAndDocument('Contact', 'Get', $params, __FUNCTION__
, __FILE__
, $description, $subfile);
1557 $this->assertEquals('17', $result, "in line " . __LINE__
);
1558 $this->callAPISuccess('Contact', 'Delete', $params);
1562 * Test id only format
1564 function testContactGetFormatSingleValue() {
1565 $this->createContactFromXML();
1566 $description = "This demonstrates use of the 'format.single_value' param.
1567 /* This param causes only a single value of the only entity to be returned as an string.
1568 /* it will be ignored if there is not exactly 1 result";
1569 $subfile = "FormatSingleValue";
1570 $params = array('id' => 17, 'return' => 'display_name');
1571 $result = $this->callAPIAndDocument('Contact', 'getvalue', $params, __FUNCTION__
, __FILE__
, $description, $subfile,'getvalue');
1572 $this->assertEquals('Test Contact', $result, "in line " . __LINE__
);
1573 $this->callAPISuccess('Contact', 'Delete', $params);
1576 function testContactCreationPermissions() {
1578 'contact_type' => 'Individual', 'first_name' => 'Foo',
1579 'last_name' => 'Bear',
1580 'check_permissions' => TRUE,
1582 $config = CRM_Core_Config
::singleton();
1583 $config->userPermissionClass
->permissions
= array('access CiviCRM');
1584 $result = $this->callAPIFailure('contact', 'create', $params);
1585 $this->assertEquals('API permission check failed for contact/create call; missing permission: add contacts.', $result['error_message'], 'lacking permissions should not be enough to create a contact');
1587 $config->userPermissionClass
->permissions
= array('access CiviCRM', 'add contacts', 'import contacts');
1588 $result = $this->callAPISuccess('contact', 'create', $params, NULL, 'overfluous permissions should be enough to create a contact');
1591 function testContactUpdatePermissions() {
1592 $params = array('contact_type' => 'Individual', 'first_name' => 'Foo', 'last_name' => 'Bear', 'check_permissions' => TRUE,);
1593 $result = $this->callAPISuccess('contact', 'create', $params);
1594 $config = CRM_Core_Config
::singleton();
1595 $params = array('id' => $result['id'], 'contact_type' => 'Individual', 'last_name' => 'Bar', 'check_permissions' => TRUE,);
1597 $config->userPermissionClass
->permissions
= array('access CiviCRM');
1598 $result = $this->callAPIFailure('contact', 'update', $params);
1599 $this->assertEquals('API permission check failed for contact/update call; missing permission: edit all contacts.', $result['error_message'], 'lacking permissions should not be enough to update a contact');
1601 $config->userPermissionClass
->permissions
= array('access CiviCRM', 'add contacts', 'view all contacts', 'edit all contacts', 'import contacts');
1602 $result = $this->callAPISuccess('contact', 'update', $params, NULL, 'overfluous permissions should be enough to update a contact');
1605 function createContactFromXML() {
1606 // Insert a row in civicrm_contact creating contact 17
1607 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1608 $op->execute($this->_dbconn
,
1609 new PHPUnit_Extensions_Database_DataSet_XMLDataSet(
1610 dirname(__FILE__
) . '/dataset/contact_17.xml'
1615 function testContactProximity() {
1616 // first create a contact with a SF location with a specific
1618 $contactID = $this->organizationCreate();
1620 // now create the address
1622 'street_address' => '123 Main Street',
1623 'city' => 'San Francisco',
1625 'country_id' => 1228,
1626 'state_province_id' => 1004,
1627 'geo_code_1' => '37.79',
1628 'geo_code_2' => '-122.40',
1629 'location_type_id' => 1,
1630 'contact_id' => $contactID,
1633 $result = $this->callAPISuccess('address', 'create', $params);
1634 $this->assertEquals(1, $result['count'], 'In line ' . __LINE__
);
1636 // now do a proximity search with a close enough geocode and hope to match
1637 // that specific contact only!
1638 $proxParams = array(
1640 'longitude' => -122.3,
1644 $result = $this->callAPISuccess('contact', 'proximity', $proxParams);
1645 $this->assertEquals(1, $result['count'], 'In line ' . __LINE__
);