Merge pull request #1216 from davecivicrm/CRM-13062
[civicrm-core.git] / tests / phpunit / api / v3 / ContactTest.php
CommitLineData
6a488035
TO
1<?php
2/**
3 * File for the TestContact class
4 *
5 * (PHP 5)
6 *
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 $
12 * @package CiviCRM
13 *
14 * This file is part of CiviCRM
15 *
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.
20 *
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.
25 *
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/>.
29 */
30
31/**
32 * Include class definitions
33 */
34require_once 'CiviTest/CiviUnitTestCase.php';
35
36
37/**
38 * Test APIv3 civicrm_contact* functions
39 *
40 * @package CiviCRM_APIv3
41 * @subpackage API_Contact
42 */
43
44class api_v3_ContactTest extends CiviUnitTestCase {
45 public $DBResetRequired = FALSE;
46 protected $_apiversion;
47 protected $_entity;
48 protected $_params;
49 public $_eNoticeCompliant = TRUE;
f6722559 50 protected $_contactID;
51 protected $_financialTypeId =1;
6a488035
TO
52
53 /**
54 * Constructor
55 *
56 * Initialize configuration
57 */
58 function __construct() {
59 parent::__construct();
60 }
61
62 /**
63 * Test setup for every test
64 *
65 * Connect to the database, truncate the tables that will be used
66 * and redirect stdin to a temporary file
67 */
68 public function setUp() {
69 // Connect to the database
70 parent::setUp();
71 $this->_apiversion = 3;
f6722559 72 $this->_entity = 'contact';
73 $this->_params = array(
6a488035
TO
74 'first_name' => 'abc1',
75 'contact_type' => 'Individual',
76 'last_name' => 'xyz1',
6a488035 77 );
6a488035
TO
78 }
79
80 function tearDown() {
81 // truncate a few tables
82 $tablesToTruncate = array(
83 'civicrm_contact',
84 'civicrm_email',
85 'civicrm_contribution',
86 'civicrm_line_item',
87 'civicrm_website',
e635f9d4
TO
88 'civicrm_relationship',
89 'civicrm_uf_match',
6a488035
TO
90 );
91
f6722559 92 $this->quickCleanup($tablesToTruncate, TRUE);
6a488035
TO
93 }
94
95 /**
96 * Test civicrm_contact_create
97 *
98 * Verify that attempt to create individual contact with only
99 * first and last names succeeds
100 */
101 function testAddCreateIndividual() {
102 $oldCount = CRM_Core_DAO::singleValueQuery('select count(*) from civicrm_contact');
103 $params = array(
104 'first_name' => 'abc1',
105 'contact_type' => 'Individual',
106 'last_name' => 'xyz1',
6a488035
TO
107 );
108
f6722559 109 $contact = $this->callAPISuccess('contact', 'create', $params);
6a488035
TO
110 $this->assertTrue(is_numeric($contact['id']), "In line " . __LINE__);
111 $this->assertTrue($contact['id'] > 0, "In line " . __LINE__);
112 $newCount = CRM_Core_DAO::singleValueQuery('select count(*) from civicrm_contact');
113 $this->assertEquals($oldCount+1, $newCount);
114
6a488035
TO
115 $this->assertDBState('CRM_Contact_DAO_Contact',
116 $contact['id'],
117 $params
118 );
119 }
120
121 /**
122 * Test civicrm_contact_create with sub-types
123 *
124 * Verify that sub-types are created successfully and not deleted by subsequent updates
125 */
126 function testIndividualSubType() {
127 $params = array(
128 'first_name' => 'test abc',
129 'contact_type' => 'Individual',
130 'last_name' => 'test xyz',
131 'contact_sub_type' => array('Student', 'Staff'),
f6722559 132 );
133 $contact = $this->callAPISuccess('contact', 'create', $params);
6a488035
TO
134 $cid = $contact['id'];
135
136 $params = array(
137 'id' => $cid,
138 'middle_name' => 'foo',
6a488035 139 );
f6722559 140 $this->callAPISuccess('contact', 'create', $params);
6a488035
TO
141 unset($params['middle_name']);
142
f6722559 143 $contact = $this->callAPISuccess('contact', 'get', $params);
6a488035
TO
144
145 $this->assertEquals(array('Student', 'Staff'), $contact['values'][$cid]['contact_sub_type'], "In line " . __LINE__);
146 }
147
148 /**
149 * Verify that attempt to create contact with empty params fails
150 */
151 function testCreateEmptyContact() {
f6722559 152 $this->callAPIFailure('contact', 'create', array());
6a488035
TO
153 }
154
155 /**
156 * Verify that attempt to create contact with bad contact type fails
157 */
158 function testCreateBadTypeContact() {
159 $params = array(
160 'email' => 'man1@yahoo.com',
161 'contact_type' => 'Does not Exist',
6a488035 162 );
f6722559 163 $result = $this->callAPIFailure('contact', 'create', $params,"'Does not Exist' is not a valid option for field contact_type");
6a488035
TO
164 }
165
166 /**
167 * Verify that attempt to create individual contact with required
168 * fields missing fails
169 */
170 function testCreateBadRequiredFieldsIndividual() {
171 $params = array(
172 'middle_name' => 'This field is not required',
173 'contact_type' => 'Individual',
174 );
175
f6722559 176 $contact = $this->callAPIFailure('contact', 'create', $params);
6a488035
TO
177 }
178
179 /**
180 * Verify that attempt to create household contact with required
181 * fields missing fails
182 */
183 function testCreateBadRequiredFieldsHousehold() {
184 $params = array(
185 'middle_name' => 'This field is not required',
186 'contact_type' => 'Household',
187 );
f6722559 188 $contact = $this->callAPIFailure('contact', 'create', $params);
6a488035
TO
189 }
190
191 /**
192 * Verify that attempt to create organization contact with
193 * required fields missing fails
194 */
195 function testCreateBadRequiredFieldsOrganization() {
196 $params = array(
197 'middle_name' => 'This field is not required',
198 'contact_type' => 'Organization',
199 );
200
f6722559 201 $contact = $this->callAPIFailure('contact', 'create', $params);
6a488035
TO
202 }
203
204 /**
205 * Verify that attempt to create individual contact with only an
206 * email succeeds
207 */
208 function testCreateEmailIndividual() {
209
210 $params = array(
211 'email' => 'man3@yahoo.com',
212 'contact_type' => 'Individual',
213 'location_type_id' => 1,
6a488035
TO
214 );
215
f6722559 216 $contact = $this->callAPISuccess('contact', 'create', $params);
217
6a488035 218 $this->assertEquals(1, $contact['id'], "In line " . __LINE__);
f6722559 219 $email = $this->callAPISuccess('email', 'get', array('contact_id' => $contact['id']));
220 $this->assertEquals(1, $email['count']);
221 $this->assertEquals('man3@yahoo.com', $email['values'][$email['id']]['email']);
6a488035 222
f6722559 223 $this->callAPISuccess('contact', 'delete', $contact);
6a488035
TO
224 }
225
226 /**
227 * Verify that attempt to create individual contact with only
228 * first and last names succeeds
229 */
230 function testCreateNameIndividual() {
231 $params = array(
232 'first_name' => 'abc1',
233 'contact_type' => 'Individual',
234 'last_name' => 'xyz1',
6a488035 235 );
6a488035 236
f6722559 237 $contact = $this->callAPISuccess('contact', 'create', $params);
238 $this->assertEquals(1, $contact['id']);
6a488035
TO
239 }
240
241 /**
242 * Verify that attempt to create individual contact with
243 * first and last names and old key values works
244 */
245 function testCreateNameIndividualOldKeys() {
246 $params = array(
247 'individual_prefix' => 'Dr.',
248 'first_name' => 'abc1',
249 'contact_type' => 'Individual',
250 'last_name' => 'xyz1',
251 'individual_suffix' => 'Jr.',
6a488035
TO
252 );
253
f6722559 254 $contact = $this->callAPISuccess('contact', 'create', $params);
6a488035 255 $this->assertEquals(1, $contact['id'], "In line " . __LINE__);
6a488035
TO
256 }
257
258 /**
259 * Verify that attempt to create individual contact with
260 * first and last names and old key values works
261 */
262 function testCreateNameIndividualOldKeys2() {
263 $params = array(
264 'prefix_id' => 'Dr.',
265 'first_name' => 'abc1',
266 'contact_type' => 'Individual',
267 'last_name' => 'xyz1',
268 'suffix_id' => 'Jr.',
269 'gender_id' => 'Male',
6a488035
TO
270 );
271
f6722559 272 $contact = $this->callAPISuccess('contact', 'create', $params);
6a488035 273 $this->assertEquals(1, $contact['id'], "In line " . __LINE__);
6a488035
TO
274 }
275
276 /**
277 * Verify that attempt to create household contact with only
278 * household name succeeds
279 */
280 function testCreateNameHousehold() {
281 $params = array(
282 'household_name' => 'The abc Household',
283 'contact_type' => 'Household',
6a488035 284 );
f6722559 285 $contact = $this->callAPISuccess('contact', 'create', $params);
6a488035 286 $this->assertEquals(1, $contact['id'], "In line " . __LINE__);
6a488035
TO
287 }
288
289 /**
290 * Verify that attempt to create organization contact with only
291 * organization name succeeds
292 */
293 function testCreateNameOrganization() {
294 $params = array(
295 'organization_name' => 'The abc Organization',
296 'contact_type' => 'Organization',
6a488035 297 );
f6722559 298 $contact = $this->callAPISuccess('contact', 'create', $params);
299 $this->assertEquals(1, $contact['id']);
6a488035
TO
300 }
301 /**
d0e1eff2 302 * Verify that attempt to create organization contact without organization name fails
6a488035
TO
303 */
304 function testCreateNoNameOrganization() {
305 $params = array(
306 'first_name' => 'The abc Organization',
307 'contact_type' => 'Organization',
6a488035 308 );
d0e1eff2 309 $result = $this->callAPIFailure('contact', 'create', $params);
6a488035
TO
310 }
311 /**
312 * check with complete array + custom field
313 * Note that the test is written on purpose without any
314 * variables specific to participant so it can be replicated into other entities
315 * and / or moved to the automated test suite
316 */
317 function testCreateWithCustom() {
318 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__, __FILE__);
319
320 $params = $this->_params;
321 $params['custom_' . $ids['custom_field_id']] = "custom string";
322 $description = "/*this demonstrates setting a custom field through the API ";
323 $subfile = "CustomFieldCreate";
f6722559 324 $result = $this->callAPIAndDocument($this->_entity, 'create', $params, __FUNCTION__, __FILE__, $description, $subfile);
6a488035 325
f6722559 326 $check = $this->callAPISuccess($this->_entity, 'get', array('return.custom_' . $ids['custom_field_id'] => 1, 'id' => $result['id']));
6a488035
TO
327 $this->assertEquals("custom string", $check['values'][$check['id']]['custom_' . $ids['custom_field_id']], ' in line ' . __LINE__);
328
329 $this->customFieldDelete($ids['custom_field_id']);
330 $this->customGroupDelete($ids['custom_group_id']);
331 }
332
fe6daa04 333 /**
334 * CRM-12773 - expectation is that civicrm quietly ignores
335 * fields without values
336 */
337 function testCreateWithNULLCustomCRM12773() {
338 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__, __FILE__);
339 $params = $this->_params;
340 $params['custom_' . $ids['custom_field_id']] = NULL;
f6722559 341 $result = $this->callAPISuccess('contact', 'create', $params);
fe6daa04 342 $this->customFieldDelete($ids['custom_field_id']);
343 $this->customGroupDelete($ids['custom_group_id']);
344 }
345
346
6a488035
TO
347 /*
348 * Test creating a current employer through API
349 */
350 function testContactCreateCurrentEmployer(){
351 //here we will just do the get for set-up purposes
f6722559 352 $count = $this->callAPISuccess('contact', 'getcount', array(
6a488035
TO
353 'organization_name' => 'new employer org',
354 'contact_type' => 'Organization'
355 ));
356 $this->assertEquals(0, $count);
f6722559 357 $employerResult = $this->callAPISuccess('contact', 'create', array_merge($this->_params, array(
6a488035
TO
358 'current_employer' => 'new employer org',)
359 ));
f6722559 360 $expectedCount = 1;
361 $count = $this->callAPISuccess('contact', 'getcount', array(
6a488035
TO
362 'organization_name' => 'new employer org',
363 'contact_type' => 'Organization'
f6722559 364 ),
365 $expectedCount);
6a488035 366
f6722559 367 $result = $this->callAPISuccess('contact', 'getsingle', array(
6a488035
TO
368 'id' => $employerResult['id'],
369 ));
370
371 $this->assertEquals('new employer org', $result['current_employer']);
372
373 }
374
375 /*
376 * Test that sort works - old syntax
377 */
378 function testGetSort() {
f6722559 379 $c1 = $this->callAPISuccess($this->_entity, 'create', $this->_params);
380 $c2 = $this->callAPISuccess($this->_entity, 'create', array('first_name' => 'bb', 'last_name' => 'ccc', 'contact_type' => 'Individual'));
381 $result = $this->callAPISuccess($this->_entity, 'get', array(
6a488035
TO
382 'sort' => 'first_name ASC',
383 'return.first_name' => 1,
384 'sequential' => 1,
385 'rowCount' => 1,
386 ));
6a488035
TO
387
388 $this->assertEquals('abc1', $result['values'][0]['first_name']);
f6722559 389 $result = $this->callAPISuccess($this->_entity, 'get', array(
390 'sort' => 'first_name DESC',
391 'return.first_name' => 1,
392 'sequential' => 1,
393 'rowCount' => 1,
394 ));
6a488035
TO
395 $this->assertEquals('bb', $result['values'][0]['first_name']);
396
f6722559 397 $this->callAPISuccess($this->_entity, 'delete', array('id' => $c1['id']));
398 $this->callAPISuccess($this->_entity, 'delete', array('id' => $c2['id']));
6a488035
TO
399 }
400 /*
401 * Test variants on deleted behaviour
402 */
403 function testGetDeleted() {
404 $params = $this->_params;
f6722559 405 $contact1 = $this->callAPISuccess('contact', 'create', $params);
6a488035
TO
406 $params['is_deleted'] = 1;
407 $params['last_name'] = 'bcd';
f6722559 408 $contact2 = $this->callAPISuccess('contact', 'create', $params);
409 $countActive = $this->callAPISuccess('contact', 'getcount', array('showAll' => 'active'));
410 $countAll = $this->callAPISuccess('contact', 'getcount', array('showAll' => 'all'));
411 $countTrash = $this->callAPISuccess('contact', 'getcount', array('showAll' => 'trash'));
412 $countDefault = $this->callAPISuccess('contact', 'getcount', array());
413 $countDeleted = $this->callAPISuccess('contact', 'getcount', array(
414 'contact_is_deleted' => 1,
6a488035 415 ));
f6722559 416 $countNotDeleted = $this->callAPISuccess('contact', 'getcount', array(
417 'contact_is_deleted' => 0,
6a488035 418 ));
f6722559 419 $this->callAPISuccess('contact', 'delete', array('id' => $contact1['id']));
420 $this->callAPISuccess('contact', 'delete', array('id' => $contact2['id']));
6a488035
TO
421 $this->assertEquals(1, $countNotDeleted, 'contact_is_deleted => 0 is respected in line ' . __LINE__);
422 $this->assertEquals(1, $countActive, 'in line ' . __LINE__);
423 $this->assertEquals(1, $countTrash, 'in line ' . __LINE__);
424 $this->assertEquals(2, $countAll, 'in line ' . __LINE__);
425 $this->assertEquals(1, $countDeleted, 'in line ' . __LINE__);
426 $this->assertEquals(1, $countDefault, 'Only active by default in line ' . __LINE__);
427 }
428 /*
429 * Test that sort works - new syntax
430 */
431 function testGetSortNewSYntax() {
f6722559 432 $c1 = $this->callAPISuccess($this->_entity, 'create', $this->_params);
433 $c2 = $this->callAPISuccess($this->_entity, 'create', array('first_name' => 'bb', 'last_name' => 'ccc', 'contact_type' => 'Individual'));
434 $result = $this->callAPISuccess($this->_entity, 'getvalue', array(
6a488035
TO
435 'return' => 'first_name',
436 'options' => array(
437 'limit' => 1,
438 'sort' => 'first_name',
439 ),
440 ));
441 $this->assertEquals('abc1', $result, 'in line' . __LINE__);
442
f6722559 443 $result = $this->callAPISuccess($this->_entity, 'getvalue', array(
6a488035
TO
444 'return' => 'first_name',
445 'options' => array(
446 'limit' => 1,
447 'sort' => 'first_name DESC',
448 ),
449 ));
450 $this->assertEquals('bb', $result);
451
f6722559 452 $this->callAPISuccess($this->_entity, 'delete', array('id' => $c1['id']));
453 $this->callAPISuccess($this->_entity, 'delete', array('id' => $c2['id']));
6a488035
TO
454 }
455 /*
456 * Test appostrophe works in get & create
457 */
458 function testGetAppostropheCRM10857() {
459 $params = array_merge($this->_params, array('last_name' => "O'Connor"));
f6722559 460 $contact = $this->callAPISuccess($this->_entity, 'create', $params);
461 $result = $this->callAPISuccess($this->_entity, 'getsingle', array(
6a488035
TO
462 'last_name' => "O'Connor",
463 'sequential' => 1,
464 ));
465 $this->assertEquals("O'Connor", $result['last_name'], 'in line' . __LINE__);
466 }
467
468 /**
469 * check with complete array + custom field
470 * Note that the test is written on purpose without any
471 * variables specific to participant so it can be replicated into other entities
472 * and / or moved to the automated test suite
473 */
474 function testGetWithCustom() {
475 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__, __FILE__);
476
477 $params = $this->_params;
478 $params['custom_' . $ids['custom_field_id']] = "custom string";
479 $description = "/*this demonstrates setting a custom field through the API ";
480 $subfile = "CustomFieldGet";
f6722559 481 $result = $this->callAPISuccess($this->_entity, 'create', $params);
6a488035 482
f6722559 483 $check = $this->callAPIAndDocument($this->_entity, 'get', array('return.custom_' . $ids['custom_field_id'] => 1, 'id' => $result['id']), __FUNCTION__, __FILE__, $description, $subfile);
6a488035
TO
484
485 $this->assertEquals("custom string", $check['values'][$check['id']]['custom_' . $ids['custom_field_id']], ' in line ' . __LINE__);
f6722559 486 $fields = ($this->callAPISuccess('contact', 'getfields', $params));
6a488035
TO
487 $this->assertTrue(is_array($fields['values']['custom_' . $ids['custom_field_id']]));
488 $this->customFieldDelete($ids['custom_field_id']);
489 $this->customGroupDelete($ids['custom_group_id']);
490 }
491 /*
492 * check with complete array + custom field
493 * Note that the test is written on purpose without any
494 * variables specific to participant so it can be replicated into other entities
495 * and / or moved to the automated test suite
496 */
497 function testGetWithCustomReturnSyntax() {
498 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__, __FILE__);
499
500 $params = $this->_params;
501 $params['custom_' . $ids['custom_field_id']] = "custom string";
502 $description = "/*this demonstrates setting a custom field through the API ";
503 $subfile = "CustomFieldGetReturnSyntaxVariation";
f6722559 504 $result = $this->callAPISuccess($this->_entity, 'create', $params);
505 $params = array('return' => 'custom_' . $ids['custom_field_id'], 'id' => $result['id']);
506 $check = $this->callAPIAndDocument($this->_entity, 'get', $params, __FUNCTION__, __FILE__, $description, $subfile);
6a488035
TO
507
508 $this->assertEquals("custom string", $check['values'][$check['id']]['custom_' . $ids['custom_field_id']], ' in line ' . __LINE__);
6a488035
TO
509 $this->customFieldDelete($ids['custom_field_id']);
510 $this->customGroupDelete($ids['custom_group_id']);
511 }
512
513 function testGetGroupIDFromContact() {
514 $groupId = $this->groupCreate(NULL);
515 $description = "Get all from group and display contacts";
516 $subfile = "GroupFilterUsingContactAPI";
517 $params = array(
518 'email' => 'man2@yahoo.com',
519 'contact_type' => 'Individual',
520 'location_type_id' => 1,
6a488035
TO
521 'api.group_contact.create' => array('group_id' => $groupId),
522 );
523
f6722559 524 $contact = $this->callAPISuccess('contact', 'create', $params);
6a488035
TO
525 // testing as integer
526 $params = array(
527 'filter.group_id' => $groupId,
6a488035
TO
528 'contact_type' => 'Individual',
529 );
f6722559 530 $result = $this->callAPIAndDocument('contact', 'get', $params, __FUNCTION__, __FILE__, $description, $subfile);
6a488035
TO
531 $this->assertEquals(1, $result['count']);
532 // group 26 doesn't exist, but we can still search contacts in it.
533 $params = array(
534 'filter.group_id' => 26,
6a488035
TO
535 'contact_type' => 'Individual',
536 );
f6722559 537 $result = $this->callAPISuccess('contact', 'get', $params);
6a488035
TO
538 // testing as string
539 $params = array(
f6722559 540 'filter.group_id' => "$groupId, 26",
6a488035
TO
541 'contact_type' => 'Individual',
542 );
f6722559 543 $result = $this->callAPIAndDocument('contact', 'get', $params, __FUNCTION__, __FILE__, $description, $subfile);
6a488035
TO
544 $this->assertEquals(1, $result['count']);
545 $params = array(
546 'filter.group_id' => "26,27",
6a488035
TO
547 'contact_type' => 'Individual',
548 );
f6722559 549 $result = $this->callAPISuccess('contact', 'get', $params);
6a488035
TO
550
551 // testing as string
552 $params = array('filter.group_id' => array($groupId, 26),
6a488035
TO
553 'contact_type' => 'Individual',
554 );
f6722559 555 $result = $this->callAPIAndDocument('contact', 'get', $params, __FUNCTION__, __FILE__, $description, $subfile);
6a488035
TO
556 $this->assertEquals(1, $result['count']);
557
558 //test in conjunction with other criteria
559 $params = array('filter.group_id' => array($groupId, 26),
6a488035
TO
560 'contact_type' => 'Organization',
561 );
f6722559 562 $result = $this->callAPISuccess('contact', 'get', $params);
6a488035 563 $params = array('filter.group_id' => array(26, 27),
6a488035
TO
564 'contact_type' => 'Individual',
565 );
f6722559 566 $result = $this->callAPISuccess('contact', 'get', $params);
6a488035
TO
567 $this->assertEquals(0, $result['count'], " in line " . __LINE__);
568 }
569
570 /**
571 * Verify that attempt to create individual contact with two chained websites succeeds
572 */
573 function testCreateIndividualWithContributionDottedSyntax() {
574 $description = "test demonstrates the syntax to create 2 chained entities";
575 $subfile = "ChainTwoWebsites";
576 $params = array(
577 'first_name' => 'abc3',
578 'last_name' => 'xyz3',
579 'contact_type' => 'Individual',
580 'email' => 'man3@yahoo.com',
6a488035
TO
581 'api.contribution.create' => array(
582 'receive_date' => '2010-01-01',
583 'total_amount' => 100.00,
f6722559 584 'financial_type_id' => $this->_financialTypeId,
6a488035
TO
585 'payment_instrument_id' => 1,
586 'non_deductible_amount' => 10.00,
587 'fee_amount' => 50.00,
588 'net_amount' => 90.00,
589 'trxn_id' => 15345,
590 'invoice_id' => 67990,
591 'source' => 'SSF',
592 'contribution_status_id' => 1,
593 ),
594 'api.website.create' => array(
595 'url' => "http://civicrm.org",
596 ),
597 'api.website.create.2' => array(
598 'url' => "http://chained.org",
599 ),
600 );
601
f6722559 602 $result = $this->callAPIAndDocument('Contact', 'create', $params, __FUNCTION__, __FILE__, $description, $subfile);
6a488035
TO
603
604 $this->assertEquals(1, $result['id'], "In line " . __LINE__);
f6722559 605 // checking child function result not covered in callAPIAndDocument
606 $this->assertAPISuccess($result['values'][$result['id']]['api.website.create']);
6a488035
TO
607 $this->assertEquals("http://chained.org", $result['values'][$result['id']]['api.website.create.2']['values'][0]['url'], "In line " . __LINE__);
608 $this->assertEquals("http://civicrm.org", $result['values'][$result['id']]['api.website.create']['values'][0]['url'], "In line " . __LINE__);
609
610 // delete the contact
f6722559 611 $this->callAPISuccess('contact', 'delete', $result);
6a488035
TO
612 }
613
614 /**
615 * Verify that attempt to create individual contact with chained contribution and website succeeds
616 */
617 function testCreateIndividualWithContributionChainedArrays() {
618 $params = array(
619 'first_name' => 'abc3',
620 'last_name' => 'xyz3',
621 'contact_type' => 'Individual',
622 'email' => 'man3@yahoo.com',
6a488035
TO
623 'api.contribution.create' => array(
624 'receive_date' => '2010-01-01',
625 'total_amount' => 100.00,
f6722559 626 'financial_type_id' => $this->_financialTypeId,
6a488035
TO
627 'payment_instrument_id' => 1,
628 'non_deductible_amount' => 10.00,
629 'fee_amount' => 50.00,
630 'net_amount' => 90.00,
631 'trxn_id' => 12345,
632 'invoice_id' => 67890,
633 'source' => 'SSF',
634 'contribution_status_id' => 1,
635 ),
636 'api.website.create' => array(
637 array(
638 'url' => "http://civicrm.org",
639 ),
640 array(
641 'url' => "http://chained.org",
642 'website_type_id' => 2,
643 ),
644 ),
645 );
646
647 $description = "demonstrates creating two websites as an array";
648 $subfile = "ChainTwoWebsitesSyntax2";
f6722559 649 $result = $this->callAPIAndDocument('Contact', 'create', $params, __FUNCTION__, __FILE__, $description, $subfile);
650
651 $this->assertEquals(1, $result['id']);
652 // the callAndDocument doesn't check the chained call
6a488035
TO
653 $this->assertEquals(0, $result['values'][$result['id']]['api.website.create'][0]['is_error'], "In line " . __LINE__);
654 $this->assertEquals("http://chained.org", $result['values'][$result['id']]['api.website.create'][1]['values'][0]['url'], "In line " . __LINE__);
655 $this->assertEquals("http://civicrm.org", $result['values'][$result['id']]['api.website.create'][0]['values'][0]['url'], "In line " . __LINE__);
656
f6722559 657 $this->callAPISuccess('contact', 'delete', $result);
6a488035
TO
658 }
659
660 /**
661 * Verify that attempt to create individual contact with first
662 * and last names and email succeeds
663 */
664 function testCreateIndividualWithNameEmail() {
665 $params = array(
666 'first_name' => 'abc3',
667 'last_name' => 'xyz3',
668 'contact_type' => 'Individual',
669 'email' => 'man3@yahoo.com',
6a488035
TO
670 );
671
f6722559 672 $contact = $this->callAPISuccess('contact', 'create', $params);
6a488035
TO
673 $this->assertEquals(1, $contact['id'], "In line " . __LINE__);
674
675 // delete the contact
f6722559 676 $this->callAPISuccess('contact', 'delete', $contact);
6a488035
TO
677 }
678 /**
679 * Verify that attempt to create individual contact with no data fails
680 */
681 function testCreateIndividualWithOutNameEmail() {
682 $params = array(
683 'contact_type' => 'Individual',
6a488035
TO
684 );
685
d0e1eff2 686 $result = $this->callAPIFailure('contact', 'create', $params);
6a488035
TO
687 }
688 /**
689 * Verify that attempt to create individual contact with first
690 * and last names, email and location type succeeds
691 */
692 function testCreateIndividualWithNameEmailLocationType() {
693 $params = array(
694 'first_name' => 'abc4',
695 'last_name' => 'xyz4',
696 'email' => 'man4@yahoo.com',
697 'contact_type' => 'Individual',
698 'location_type_id' => 1,
6a488035 699 );
f6722559 700 $result = $this->callAPISuccess('contact', 'create', $params);
6a488035 701
6a488035
TO
702 $this->assertEquals(1, $result['id'], "In line " . __LINE__);
703
f6722559 704 $this->callAPISuccess('contact', 'delete', array('id' => $result['id']));
6a488035
TO
705 }
706
707 /**
708 * Verify that when changing employers
709 * the old employer relationship becomes inactive
710 */
711 function testCreateIndividualWithEmployer() {
712 $employer = $this->organizationCreate();
713 $employer2 = $this->organizationCreate();
714
715 $params = array(
716 'email' => 'man4@yahoo.com',
717 'contact_type' => 'Individual',
6a488035
TO
718 'employer_id' => $employer,
719 );
720
f6722559 721 $result = $this->callAPISuccess('contact', 'create', $params);
722 $relationships = $this->callAPISuccess('relationship', 'get', array(
6a488035
TO
723 'contact_id_a' => $result['id'],
724 'sequential' => 1,
725 ));
726
727 $this->assertEquals($employer, $relationships['values'][0]['contact_id_b']);
728
729 // Add more random relationships to make the test more realistic
730 foreach (array('Employee of', 'Volunteer for') as $rtype) {
731 $relTypeId = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_RelationshipType', $rtype, 'id', 'name_a_b');
f6722559 732 $random_rel = $this->callAPISuccess('relationship', 'create', array(
6a488035
TO
733 'contact_id_a' => $result['id'],
734 'contact_id_b' => $this->organizationCreate(),
735 'is_active' => 1,
736 'relationship_type_id' => $relTypeId,
737 ));
f6722559 738 }
6a488035
TO
739
740 // Add second employer
741 $params['employer_id'] = $employer2;
742 $params['id'] = $result['id'];
f6722559 743 $result = $this->callAPISuccess('contact', 'create', $params);
6a488035 744
f6722559 745 $relationships = $this->callAPISuccess('relationship', 'get', array(
6a488035
TO
746 'contact_id_a' => $result['id'],
747 'sequential' => 1,
748 'is_active' => 0,
749 ));
750
751 $this->assertEquals($employer, $relationships['values'][0]['contact_id_b']);
752 }
753
754 /**
755 * Verify that attempt to create household contact with details
756 * succeeds
757 */
758 function testCreateHouseholdDetails() {
759 $params = array(
760 'household_name' => 'abc8\'s House',
761 'nick_name' => 'x House',
762 'email' => 'man8@yahoo.com',
763 'contact_type' => 'Household',
6a488035
TO
764 );
765
f6722559 766 $contact = $this->callAPISuccess('contact', 'create', $params);
767
6a488035
TO
768 $this->assertEquals(1, $contact['id'], "In line " . __LINE__);
769
f6722559 770 $this->callAPISuccess('contact', 'delete', $contact);
6a488035
TO
771 }
772 /**
773 * Verify that attempt to create household contact with inadequate details
774 * fails
775 */
776 function testCreateHouseholdInadequateDetails() {
777 $params = array(
778 'nick_name' => 'x House',
779 'email' => 'man8@yahoo.com',
780 'contact_type' => 'Household',
6a488035
TO
781 );
782
d0e1eff2 783 $result = $this->callAPIFailure('contact', 'create', $params);
6a488035
TO
784 }
785
6a488035
TO
786 /**
787 * Verify successful update of individual contact
788 */
789 function testUpdateIndividualWithAll() {
790 // Insert a row in civicrm_contact creating individual contact
791 $op = new PHPUnit_Extensions_Database_Operation_Insert();
792 $op->execute($this->_dbconn,
793 new PHPUnit_Extensions_Database_DataSet_XMLDataSet(
794 dirname(__FILE__) . '/dataset/contact_ind.xml'
795 )
796 );
797
798 $params = array(
799 'id' => 23,
800 'first_name' => 'abcd',
801 'contact_type' => 'Individual',
802 'nick_name' => 'This is nickname first',
803 'do_not_email' => '1',
804 'do_not_phone' => '1',
805 'do_not_mail' => '1',
806 'do_not_trade' => '1',
807 'legal_identifier' => 'ABC23853ZZ2235',
808 'external_identifier' => '1928837465',
809 'image_URL' => 'http://some.url.com/image.jpg',
810 'home_url' => 'http://www.example.org',
f6722559 811
812 );
813 $getResult = $this->callAPISuccess('Contact', 'Get', array());
814 $result = $this->callAPISuccess('Contact', 'Update', $params);
815 $getResult = $this->callAPISuccess('Contact', 'Get', $params);
6a488035
TO
816 unset($params['contact_id']);
817 //Todo - neither API v2 or V3 are testing for home_url - not sure if it is being set.
818 //reducing this test partially back to apiv2 level to get it through
819 unset($params['home_url']);
820 foreach ($params as $key => $value) {
821 $this->assertEquals($value, $result['values'][23][$key], "In line " . __LINE__);
822 }
823 // Check updated civicrm_contact against expected
824 $expected = new PHPUnit_Extensions_Database_DataSet_XMLDataSet(
825 dirname(__FILE__) . '/dataset/contact_ind_upd.xml'
826 );
827 $actual = new PHPUnit_Extensions_Database_DataSet_QueryDataset(
828 $this->_dbconn
829 );
830 $actual->addTable('civicrm_contact');
831 $expected->matches($actual);
832 }
833
834 /**
835 * Verify successful update of organization contact
836 */
837 function testUpdateOrganizationWithAll() {
838 // Insert a row in civicrm_contact creating organization contact
839 $op = new PHPUnit_Extensions_Database_Operation_Insert();
840 $op->execute($this->_dbconn,
841 new PHPUnit_Extensions_Database_DataSet_XMLDataSet(
842 dirname(__FILE__) . '/dataset/contact_org.xml'
843 )
844 );
845
846 $params = array(
847 'id' => 24,
848 'organization_name' => 'WebAccess India Pvt Ltd',
849 'legal_name' => 'WebAccess',
850 'sic_code' => 'ABC12DEF',
851 'contact_type' => 'Organization',
6a488035
TO
852 );
853
f6722559 854 $result = $this->callAPISuccess('Contact', 'Update', $params);
6a488035
TO
855
856 // Check updated civicrm_contact against expected
857 $expected = new PHPUnit_Extensions_Database_DataSet_XMLDataSet(
858 dirname(__FILE__) . '/dataset/contact_org_upd.xml'
859 );
860 $actual = new PHPUnit_Extensions_Database_DataSet_QueryDataset(
861 $this->_dbconn
862 );
863 $actual->addTable('civicrm_contact');
864 $expected->matches($actual);
865 }
866
867 /**
868 * Verify successful update of household contact
869 */
870 function testUpdateHouseholdwithAll() {
871 // Insert a row in civicrm_contact creating household contact
872 $op = new PHPUnit_Extensions_Database_Operation_Insert();
873 $op->execute($this->_dbconn,
874 new PHPUnit_Extensions_Database_DataSet_XMLDataSet(
875 dirname(__FILE__) . '/dataset/contact_hld.xml'
876 )
877 );
878
879 $params = array(
880 'id' => 25,
881 'household_name' => 'ABC household',
882 'nick_name' => 'ABC House',
883 'contact_type' => 'Household',
6a488035
TO
884 );
885
f6722559 886 $result = $this->callAPISuccess('Contact', 'Update', $params);
6a488035
TO
887
888 // Check updated civicrm_contact against expected
889 $expected = new PHPUnit_Extensions_Database_DataSet_XMLDataSet(
890 dirname(__FILE__) . '/dataset/contact_hld_upd.xml'
891 );
892 $actual = new PHPUnit_Extensions_Database_DataSet_QueryDataset(
893 $this->_dbconn
894 );
895 $actual->addTable('civicrm_contact');
896 $expected->matches($actual);
897 }
898
899 /**
900 * Test civicrm_update() Deliberately exclude contact_type as it should still
901 * cope using civicrm_api CRM-7645
902 */
903
904 public function testUpdateCreateWithID() {
905 // Insert a row in civicrm_contact creating individual contact
906 $op = new PHPUnit_Extensions_Database_Operation_Insert();
907 $op->execute($this->_dbconn,
908 new PHPUnit_Extensions_Database_DataSet_XMLDataSet(
909 dirname(__FILE__) . '/dataset/contact_ind.xml'
910 )
911 );
912
913
914
915 $params = array(
916 'id' => 23,
917 'first_name' => 'abcd',
918 'last_name' => 'wxyz',
6a488035
TO
919 );
920
f6722559 921 $result = $this->callAPISuccess('Contact', 'Update', $params);
6a488035
TO
922 }
923
924 /**
925 * Test civicrm_contact_delete() with no contact ID
926 */
927 function testContactDeleteNoID() {
928 $params = array(
929 'foo' => 'bar',
6a488035 930 );
f6722559 931 $result = $this->callAPIFailure('contact', 'delete', $params);
6a488035
TO
932 }
933
934 /**
935 * Test civicrm_contact_delete() with error
936 */
937 function testContactDeleteError() {
f6722559 938 $params = array('contact_id' => 999);
939 $result = $this->callAPIFailure('contact', 'delete', $params);
6a488035
TO
940 }
941
942 /**
943 * Test civicrm_contact_delete()
944 */
945 function testContactDelete() {
f6722559 946 $contactID = $this->individualCreate();
6a488035 947 $params = array(
f6722559 948 'id' => $contactID ,
6a488035 949 );
f6722559 950 $result = $this->callAPIAndDocument('contact', 'delete', $params, __FUNCTION__, __FILE__);
6a488035
TO
951 }
952
953 /**
954 * Test civicrm_contact_get() return only first name
955 */
956 public function testContactGetRetFirst() {
f6722559 957 $contact = $this->callAPISuccess('contact', 'create', $this->_params);
6a488035
TO
958 $params = array(
959 'contact_id' => $contact['id'],
960 'return_first_name' => TRUE,
961 'sort' => 'first_name',
6a488035 962 );
f6722559 963 $result = $this->callAPISuccess('contact', 'get', $params);
6a488035
TO
964 $this->assertEquals(1, $result['count'], "In line " . __LINE__);
965 $this->assertEquals($contact['id'], $result['id'], "In line " . __LINE__);
966 $this->assertEquals('abc1', $result['values'][$contact['id']]['first_name'], "In line " . __LINE__);
967 }
968
969 /**
970 * Test civicrm_contact_get() return only first name & last name
971 * Use comma separated string return with a space
972 */
973 public function testContactGetRetFirstLast() {
f6722559 974 $contact = $this->callAPISuccess('contact', 'create', $this->_params);
6a488035
TO
975 $params = array(
976 'contact_id' => $contact['id'],
977 'return' => 'first_name, last_name',
6a488035 978 );
f6722559 979 $result = $this->callAPISuccess('contact', 'getsingle', $params);
6a488035
TO
980 $this->assertEquals('abc1', $result['first_name'], "In line " . __LINE__);
981 $this->assertEquals('xyz1', $result['last_name'], "In line " . __LINE__);
982 //check that other defaults not returns
983 $this->assertArrayNotHasKey('sort_name', $result);
984 $params = array(
985 'contact_id' => $contact['id'],
986 'return' => 'first_name,last_name',
6a488035 987 );
f6722559 988 $result = $this->callAPISuccess('contact', 'getsingle', $params);
6a488035
TO
989 $this->assertEquals('abc1', $result['first_name'], "In line " . __LINE__);
990 $this->assertEquals('xyz1', $result['last_name'], "In line " . __LINE__);
991 //check that other defaults not returns
992 $this->assertArrayNotHasKey('sort_name', $result);
993 }
994
995 /**
996 * Test civicrm_contact_get() return only first name & last name
997 * Use comma separated string return without a space
998 */
999 public function testContactGetRetFirstLastNoComma() {
f6722559 1000 $contact = $this->callAPISuccess('contact', 'create', $this->_params);
6a488035
TO
1001 $params = array(
1002 'contact_id' => $contact['id'],
1003 'return' => 'first_name,last_name',
6a488035 1004 );
f6722559 1005 $result = $this->callAPISuccess('contact', 'getsingle', $params);
6a488035
TO
1006 $this->assertEquals('abc1', $result['first_name'], "In line " . __LINE__);
1007 $this->assertEquals('xyz1', $result['last_name'], "In line " . __LINE__);
1008 //check that other defaults not returns
1009 $this->assertArrayNotHasKey('sort_name', $result);
1010 }
1011
1012 /**
1013 * Test civicrm_contact_get() with default return properties
1014 */
1015 public function testContactGetRetDefault() {
1016 // Insert a row in civicrm_contact creating contact 17
1017 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1018 $op->execute($this->_dbconn,
1019 new PHPUnit_Extensions_Database_DataSet_XMLDataSet(
1020 dirname(__FILE__) . '/dataset/contact_17.xml'
1021 )
1022 );
1023 $params = array(
1024 'contact_id' => 17,
1025 'sort' => 'first_name',
6a488035 1026 );
f6722559 1027 $result = $this->callAPISuccess('contact', 'get', $params);
6a488035
TO
1028 $this->assertEquals(17, $result['values'][17]['contact_id'], "In line " . __LINE__);
1029 $this->assertEquals('Test', $result['values'][17]['first_name'], "In line " . __LINE__);
1030 }
1031
1032 /**
1033 * Test civicrm_contact_quicksearch() with empty name param
1034 */
1035 public function testContactGetQuickEmpty() {
f6722559 1036 $result = $this->callAPIFailure('contact', 'getquick', array());
6a488035
TO
1037 }
1038
1039 /**
1040 * Test civicrm_contact_quicksearch() with empty name param
1041 */
1042 public function testContactGetQuick() {
1043 // Insert a row in civicrm_contact creating individual contact
1044 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1045 $op->execute($this->_dbconn,
1046 new PHPUnit_Extensions_Database_DataSet_XMLDataSet(
1047 dirname(__FILE__) . '/dataset/contact_17.xml'
1048 )
1049 );
1050 $op->execute($this->_dbconn,
1051 new PHPUnit_Extensions_Database_DataSet_XMLDataSet(
1052 dirname(__FILE__) . '/dataset/email_contact_17.xml'
1053 )
1054 );
1055 $params = array(
1056 'name' => "T",
6a488035
TO
1057 );
1058
f6722559 1059 $result = $this->callAPISuccess('contact', 'quicksearch', $params);
6a488035
TO
1060 $this->assertEquals(17, $result['values'][0]['id'], 'in line ' . __LINE__);
1061 }
1062
1063 /**
1064 * Test civicrm_contact_get) with empty params
1065 */
1066 public function testContactGetEmptyParams() {
f6722559 1067 $result = $this->callAPISuccess('contact', 'get', array());
6a488035
TO
1068 }
1069
1070 /**
1071 * Test civicrm_contact_get(,true) with no matches
1072 */
1073 public function testContactGetOldParamsNoMatches() {
1074 // Insert a row in civicrm_contact creating contact 17
1075 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1076 $op->execute($this->_dbconn,
1077 new PHPUnit_Extensions_Database_DataSet_XMLDataSet(
1078 dirname(__FILE__) . '/dataset/contact_17.xml'
1079 )
1080 );
1081
1082 $params = array(
1083 'first_name' => 'Fred',
6a488035 1084 );
f6722559 1085 $result = $this->callAPISuccess('contact', 'get', $params);
6a488035
TO
1086 $this->assertEquals(0, $result['count'], 'in line ' . __LINE__);
1087 }
1088
1089 /**
1090 * Test civicrm_contact_get(,true) with one match
1091 */
1092 public function testContactGetOldParamsOneMatch() {
1093 // Insert a row in civicrm_contact creating contact 17
1094 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1095 $op->execute($this->_dbconn,
1096 new PHPUnit_Extensions_Database_DataSet_XMLDataSet(dirname(__FILE__) . '/dataset/contact_17.xml'
1097 )
1098 );
1099
1100 $params = array(
1101 'first_name' => 'Test',
6a488035 1102 );
f6722559 1103 $result = $this->callAPISuccess('contact', 'get', $params);
6a488035
TO
1104 $this->assertEquals(17, $result['values'][17]['contact_id'], 'in line ' . __LINE__);
1105 $this->assertEquals(17, $result['id'], 'in line ' . __LINE__);
1106 }
6a488035
TO
1107
1108 /**
1109 * Test civicrm_contact_search_count()
1110 */
1111 public function testContactGetEmail() {
1112 $params = array(
1113 'email' => 'man2@yahoo.com',
1114 'contact_type' => 'Individual',
1115 'location_type_id' => 1,
6a488035
TO
1116 );
1117
f6722559 1118 $contact = $this->callAPISuccess('contact', 'create', $params);
1119
6a488035
TO
1120 $this->assertEquals(1, $contact['id'], "In line " . __LINE__);
1121
1122 $params = array(
1123 'email' => 'man2@yahoo.com',
6a488035 1124 );
f6722559 1125 $result = $this->callAPIAndDocument('contact', 'get', $params, __FUNCTION__, __FILE__);
6a488035
TO
1126 $this->assertEquals(1, $result['values'][1]['contact_id'], "In line " . __LINE__);
1127 $this->assertEquals('man2@yahoo.com', $result['values'][1]['email'], "In line " . __LINE__);
1128
1129 // delete the contact
f6722559 1130 $this->callAPISuccess('contact', 'delete', $contact);
6a488035
TO
1131 }
1132
e635f9d4
TO
1133 /**
1134 * Test for Contact.get id=@user:username
1135 */
1136 function testContactGetByUsername() {
1137 // setup - create contact with a uf-match
1138 $cid = $this->individualCreate(array(
1139 'contact_type' => 'Individual',
1140 'first_name' => 'testGetByUsername',
1141 'last_name' => 'testGetByUsername',
1142 ));
1143
1144 $ufMatchParams = array(
1145 'domain_id' => CRM_Core_Config::domainID(),
1146 'uf_id' => 99,
1147 'uf_name' => 'the-email-matching-key-is-not-really-the-username',
1148 'contact_id' => $cid,
1149 );
1150 $ufMatch = CRM_Core_BAO_UFMatch::create($ufMatchParams);
1151 $this->assertTrue(is_numeric($ufMatch->id));
1152
1153 // setup - mock the calls to CRM_Utils_System_*::getUfId
1154 $userSystem = $this->getMock('CRM_Utils_System_UnitTests', array('getUfId'));
1155 $userSystem->expects($this->once())
1156 ->method('getUfId')
1157 ->with($this->equalTo('exampleUser'))
1158 ->will($this->returnValue(99));
1159 CRM_Core_Config::singleton()->userSystem = $userSystem;
1160
1161 // perform a lookup
1162 $result = $this->callAPISuccess('Contact', 'get', array(
e635f9d4
TO
1163 'id' => '@user:exampleUser',
1164 ));
1165 $this->assertEquals('testGetByUsername', $result['values'][$cid]['first_name']);
1166 }
1167
1168 /**
1169 * Test for Contact.get id=@user:username (with an invalid username)
1170 */
1171 function testContactGetByUnknownUsername() {
1172 // setup - mock the calls to CRM_Utils_System_*::getUfId
1173 $userSystem = $this->getMock('CRM_Utils_System_UnitTests', array('getUfId'));
1174 $userSystem->expects($this->once())
1175 ->method('getUfId')
1176 ->with($this->equalTo('exampleUser'))
1177 ->will($this->returnValue(NULL));
1178 CRM_Core_Config::singleton()->userSystem = $userSystem;
1179
1180 // perform a lookup
1181 $result = $this->callAPIFailure('Contact', 'get', array(
e635f9d4
TO
1182 'id' => '@user:exampleUser',
1183 ));
1184 $this->assertRegExp('/cannot be resolved to a contact ID/', $result['error_message']);
1185 }
1186
6a488035
TO
1187 /**
1188 * Verify attempt to create individual with chained arrays
1189 */
1190 function testGetIndividualWithChainedArrays() {
1191 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__, __FILE__);
1192 $params['custom_' . $ids['custom_field_id']] = "custom string";
1193
1194 $moreids = $this->CustomGroupMultipleCreateWithFields();
1195 $description = "/*this demonstrates the usage of chained api functions. In this case no notes or custom fields have been created ";
1196 $subfile = "APIChainedArray";
1197 $params = array(
1198 'first_name' => 'abc3',
1199 'last_name' => 'xyz3',
1200 'contact_type' => 'Individual',
1201 'email' => 'man3@yahoo.com',
6a488035
TO
1202 'api.contribution.create' => array(
1203 'receive_date' => '2010-01-01',
1204 'total_amount' => 100.00,
1205 'financial_type_id' => 1,
1206 'payment_instrument_id' => 1,
1207 'non_deductible_amount' => 10.00,
1208 'fee_amount' => 50.00,
1209 'net_amount' => 90.00,
1210 'trxn_id' => 12345,
1211 'invoice_id' => 67890,
1212 'source' => 'SSF',
1213 'contribution_status_id' => 1,
1214 ),
1215 'api.contribution.create.1' => array(
1216 'receive_date' => '2011-01-01',
1217 'total_amount' => 120.00,
f6722559 1218 'financial_type_id' => $this->_financialTypeId =1,
6a488035
TO
1219 'payment_instrument_id' => 1,
1220 'non_deductible_amount' => 10.00,
1221 'fee_amount' => 50.00,
1222 'net_amount' => 90.00,
1223 'trxn_id' => 12335,
1224 'invoice_id' => 67830,
1225 'source' => 'SSF',
1226 'contribution_status_id' => 1,
1227 ),
1228 'api.website.create' => array(
1229 array(
1230 'url' => "http://civicrm.org",
1231 ),
1232 ),
1233 );
1234
f6722559 1235 $result = $this->callAPISuccess('Contact', 'create', $params);
6a488035 1236 $params = array(
f6722559 1237 'id' => $result['id'],
6a488035
TO
1238 'api.website.get' => array(),
1239 'api.Contribution.get' => array(
1240 'total_amount' => '120.00',
1241 ), 'api.CustomValue.get' => 1,
1242 'api.Note.get' => 1,
1243 );
f6722559 1244 $result = $this->callAPIAndDocument('Contact', 'Get', $params, __FUNCTION__, __FILE__, $description, $subfile);
6a488035 1245 // delete the contact
f6722559 1246 $this->callAPISuccess('contact', 'delete', $result);
6a488035
TO
1247 $this->customGroupDelete($ids['custom_group_id']);
1248 $this->customGroupDelete($moreids['custom_group_id']);
6a488035
TO
1249 $this->assertEquals(1, $result['id'], "In line " . __LINE__);
1250 $this->assertEquals(0, $result['values'][$result['id']]['api.website.get']['is_error'], "In line " . __LINE__);
1251 $this->assertEquals("http://civicrm.org", $result['values'][$result['id']]['api.website.get']['values'][0]['url'], "In line " . __LINE__);
1252 }
1253
1254 function testGetIndividualWithChainedArraysFormats() {
1255 $description = "/*this demonstrates the usage of chained api functions. A variety of return formats are used. Note that no notes
1256 *custom fields or memberships exist";
1257 $subfile = "APIChainedArrayFormats";
1258 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__, __FILE__);
1259 $params['custom_' . $ids['custom_field_id']] = "custom string";
1260
1261 $moreids = $this->CustomGroupMultipleCreateWithFields();
1262 $params = array(
1263 'first_name' => 'abc3',
1264 'last_name' => 'xyz3',
1265 'contact_type' => 'Individual',
1266 'email' => 'man3@yahoo.com',
6a488035
TO
1267 'api.contribution.create' => array(
1268 'receive_date' => '2010-01-01',
1269 'total_amount' => 100.00,
f6722559 1270 'financial_type_id' => $this->_financialTypeId,
6a488035
TO
1271 'payment_instrument_id' => 1,
1272 'non_deductible_amount' => 10.00,
1273 'fee_amount' => 50.00,
1274 'net_amount' => 90.00,
1275 'source' => 'SSF',
1276 'contribution_status_id' => 1,
1277 ),
1278 'api.contribution.create.1' => array(
1279 'receive_date' => '2011-01-01',
1280 'total_amount' => 120.00,
f6722559 1281 'financial_type_id' => $this->_financialTypeId,
6a488035
TO
1282 'payment_instrument_id' => 1,
1283 'non_deductible_amount' => 10.00,
1284 'fee_amount' => 50.00,
1285 'net_amount' => 90.00,
1286 'source' => 'SSF',
1287 'contribution_status_id' => 1,
1288 ),
1289 'api.website.create' => array(
1290 array(
1291 'url' => "http://civicrm.org",
1292 ),
1293 ),
1294 );
1295
1296
f6722559 1297 $result = $this->callAPISuccess('Contact', 'create', $params);
6a488035 1298 $params = array(
f6722559 1299 'id' => $result['id'],
6a488035
TO
1300 'api.website.getValue' => array('return' => 'url'),
1301 'api.Contribution.getCount' => array(),
1302 'api.CustomValue.get' => 1,
1303 'api.Note.get' => 1,
1304 'api.Membership.getCount' => array(),
1305 );
f6722559 1306 $result = $this->callAPIAndDocument('Contact', 'Get', $params, __FUNCTION__, __FILE__, $description, $subfile);
6a488035
TO
1307 $this->assertEquals(1, $result['id'], "In line " . __LINE__);
1308 $this->assertEquals(2, $result['values'][$result['id']]['api.Contribution.getCount'], "In line " . __LINE__);
1309 $this->assertEquals(0, $result['values'][$result['id']]['api.Note.get']['is_error'], "In line " . __LINE__);
1310 $this->assertEquals("http://civicrm.org", $result['values'][$result['id']]['api.website.getValue'], "In line " . __LINE__);
6a488035 1311
f6722559 1312 $this->callAPISuccess('contact', 'delete', $result);
6a488035
TO
1313 $this->customGroupDelete($ids['custom_group_id']);
1314 $this->customGroupDelete($moreids['custom_group_id']);
1315 }
1316
1317 function testGetIndividualWithChainedArraysAndMultipleCustom() {
1318 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__, __FILE__);
1319 $params['custom_' . $ids['custom_field_id']] = "custom string";
1320 $moreids = $this->CustomGroupMultipleCreateWithFields();
1321 $andmoreids = $this->CustomGroupMultipleCreateWithFields(array('title' => "another group"));
1322 $description = "/*this demonstrates the usage of chained api functions. A variety of techniques are used";
1323 $subfile = "APIChainedArrayMultipleCustom";
1324 $params = array(
1325 'first_name' => 'abc3',
1326 'last_name' => 'xyz3',
1327 'contact_type' => 'Individual',
1328 'email' => 'man3@yahoo.com',
6a488035
TO
1329 'api.contribution.create' => array(
1330 'receive_date' => '2010-01-01',
1331 'total_amount' => 100.00,
1332 'financial_type_id' => 1,
1333 'payment_instrument_id' => 1,
1334 'non_deductible_amount' => 10.00,
1335 'fee_amount' => 50.00,
1336 'net_amount' => 90.00,
1337 'trxn_id' => 12345,
1338 'invoice_id' => 67890,
1339 'source' => 'SSF',
1340 'contribution_status_id' => 1,
1341 ),
1342 'api.contribution.create.1' => array(
1343 'receive_date' => '2011-01-01',
1344 'total_amount' => 120.00,
1345 'financial_type_id' => 1,
1346 'payment_instrument_id' => 1,
1347 'non_deductible_amount' => 10.00,
1348 'fee_amount' => 50.00,
1349 'net_amount' => 90.00,
1350 'trxn_id' => 12335,
1351 'invoice_id' => 67830,
1352 'source' => 'SSF',
1353 'contribution_status_id' => 1,
1354 ),
1355 'api.website.create' => array(
1356 array(
1357 'url' => "http://civicrm.org",
1358 ),
1359 ),
1360 'custom_' . $ids['custom_field_id'] => "value 1",
1361 'custom_' . $moreids['custom_field_id'][0] => "value 2",
1362 'custom_' . $moreids['custom_field_id'][1] => "warm beer",
1363 'custom_' . $andmoreids['custom_field_id'][1] => "vegemite",
1364 );
1365
1366
f6722559 1367 $result = $this->callAPISuccess('Contact', 'create', $params);
1368 $result = $this->callAPISuccess('Contact', 'create', array(
1369 'contact_type' => 'Individual', 'id' => $result['id'], 'custom_' . $moreids['custom_field_id'][0] => "value 3", 'custom_' . $ids['custom_field_id'] => "value 4",
6a488035
TO
1370 ));
1371
1372 $params = array(
f6722559 1373 'id' => $result['id'],
6a488035
TO
1374 'api.website.getValue' => array('return' => 'url'),
1375 'api.Contribution.getCount' => array(),
1376 'api.CustomValue.get' => 1,
1377 );
f6722559 1378 $result = $this->callAPIAndDocument('Contact', 'Get', $params, __FUNCTION__, __FILE__, $description, $subfile);
1379
6a488035
TO
1380 $this->customGroupDelete($ids['custom_group_id']);
1381 $this->customGroupDelete($moreids['custom_group_id']);
1382 $this->customGroupDelete($andmoreids['custom_group_id']);
6a488035
TO
1383 $this->assertEquals(1, $result['id'], "In line " . __LINE__);
1384 $this->assertEquals(0, $result['values'][$result['id']]['api.CustomValue.get']['is_error'], "In line " . __LINE__);
1385 $this->assertEquals('http://civicrm.org', $result['values'][$result['id']]['api.website.getValue'], "In line " . __LINE__);
1386 }
1387 /*
1388 * Test checks siusage of $values to pick & choose inputs
1389 */
1390 function testChainingValuesCreate() {
1391 $description = "/*this demonstrates the usage of chained api functions. Specifically it has one 'parent function' &
1392 2 child functions - one receives values from the parent (Contact) and the other child (Tag). ";
1393 $subfile = "APIChainedArrayValuesFromSiblingFunction";
1394 $params = array(
f6722559 1395 'display_name' => 'batman', 'contact_type' => 'Individual',
6a488035
TO
1396 'api.tag.create' => array('name' => '$value.id', 'description' => '$value.display_name', 'format.only_id' => 1),
1397 'api.entity_tag.create' => array('tag_id' => '$value.api.tag.create'),
1398 );
f6722559 1399 $result = $this->callAPIAndDocument('Contact', 'Create', $params, __FUNCTION__, __FILE__, $description, $subfile);
6a488035 1400 $this->assertEquals(0, $result['values'][$result['id']]['api.entity_tag.create']['is_error']);
f6722559 1401
6a488035
TO
1402 $tablesToTruncate = array(
1403 'civicrm_contact',
1404 'civicrm_activity',
1405 'civicrm_entity_tag',
1406 'civicrm_tag',
1407 );
1408 $this->quickCleanup($tablesToTruncate, TRUE);
1409 }
1410
1411 /*
1412 * test TrueFalse format - I couldn't come up with an easy way to get an error on Get
1413 */
1414 function testContactGetFormatIsSuccessTrue() {
1415 $this->createContactFromXML();
1416 $description = "This demonstrates use of the 'format.is_success' param.
1417 This param causes only the success or otherwise of the function to be returned as BOOLEAN";
1418 $subfile = "FormatIsSuccess_True";
f6722559 1419 $params = array('id' => 17, 'format.is_success' => 1);
1420 $result = $this->callAPIAndDocument('Contact', 'Get', $params, __FUNCTION__, __FILE__, $description, $subfile);
6a488035 1421 $this->assertEquals(1, $result);
f6722559 1422 $this->callAPISuccess('Contact', 'Delete', $params);
6a488035
TO
1423 }
1424 /*
1425 * test TrueFalse format
1426 */
1427 function testContactCreateFormatIsSuccessFalse() {
1428
1429 $description = "This demonstrates use of the 'format.is_success' param.
1430 This param causes only the success or otherwise of the function to be returned as BOOLEAN";
1431 $subfile = "FormatIsSuccess_Fail";
f6722559 1432 $params = array('id' => 500, 'format.is_success' => 1);
1433 $result = $this->callAPIAndDocument('Contact', 'Create', $params, __FUNCTION__, __FILE__, $description, $subfile);
6a488035
TO
1434 $this->assertEquals(0, $result);
1435 }
1436 /*
1437 * test Single Entity format
1438 */
1439 function testContactGetSingle_entity_array() {
1440 $this->createContactFromXML();
1441 $description = "This demonstrates use of the 'format.single_entity_array' param.
1442 /* This param causes the only contact to be returned as an array without the other levels.
1443 /* it will be ignored if there is not exactly 1 result";
1444 $subfile = "GetSingleContact";
f6722559 1445 $params = array('id' => 17);
1446 $result = $this->callAPIAndDocument('Contact', 'GetSingle', $params, __FUNCTION__, __FILE__, $description, $subfile);
6a488035 1447 $this->assertEquals('Test Contact', $result['display_name'], "in line " . __LINE__);
f6722559 1448 $this->callAPISuccess('Contact', 'Delete', $params);
6a488035
TO
1449 }
1450
1451 /*
1452 * test Single Entity format
1453 */
1454 function testContactGetFormatcount_only() {
1455 $this->createContactFromXML();
1456 $description = "/*This demonstrates use of the 'getCount' action
1457 /* This param causes the count of the only function to be returned as an integer";
1458 $subfile = "GetCountContact";
f6722559 1459 $params = array('id' => 17);
1460 $result = $this->callAPIAndDocument('Contact', 'GetCount', $params, __FUNCTION__, __FILE__, $description, $subfile);
6a488035 1461 $this->assertEquals('1', $result, "in line " . __LINE__);
f6722559 1462 $this->callAPISuccess('Contact', 'Delete', $params);
6a488035
TO
1463 }
1464 /*
1465 * Test id only format
1466 */
1467 function testContactGetFormatID_only() {
1468 $this->createContactFromXML();
1469 $description = "This demonstrates use of the 'format.id_only' param.
1470 /* This param causes the id of the only entity to be returned as an integer.
1471 /* it will be ignored if there is not exactly 1 result";
1472 $subfile = "FormatOnlyID";
f6722559 1473 $params = array('id' => 17, 'format.only_id' => 1);
1474 $result = $this->callAPIAndDocument('Contact', 'Get', $params, __FUNCTION__, __FILE__, $description, $subfile);
6a488035 1475 $this->assertEquals('17', $result, "in line " . __LINE__);
f6722559 1476 $this->callAPISuccess('Contact', 'Delete', $params);
6a488035
TO
1477 }
1478
1479 /*
1480 * Test id only format
1481 */
1482 function testContactGetFormatSingleValue() {
1483 $this->createContactFromXML();
1484 $description = "This demonstrates use of the 'format.single_value' param.
1485 /* This param causes only a single value of the only entity to be returned as an string.
1486 /* it will be ignored if there is not exactly 1 result";
1487 $subfile = "FormatSingleValue";
f6722559 1488 $params = array('id' => 17, 'return' => 'display_name');
1489 $result = $this->callAPIAndDocument('Contact', 'getvalue', $params, __FUNCTION__, __FILE__, $description, $subfile,'getvalue');
6a488035 1490 $this->assertEquals('Test Contact', $result, "in line " . __LINE__);
f6722559 1491 $this->callAPISuccess('Contact', 'Delete', $params);
6a488035
TO
1492 }
1493
1494 function testContactCreationPermissions() {
1495 $params = array(
1496 'contact_type' => 'Individual', 'first_name' => 'Foo',
1497 'last_name' => 'Bear',
1498 'check_permissions' => TRUE,
6a488035
TO
1499 );
1500 $config = CRM_Core_Config::singleton();
1501 $config->userPermissionClass->permissions = array('access CiviCRM');
d0e1eff2 1502 $result = $this->callAPIFailure('contact', 'create', $params);
6a488035
TO
1503 $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');
1504
1505 $config->userPermissionClass->permissions = array('access CiviCRM', 'add contacts', 'import contacts');
f6722559 1506 $result = $this->callAPISuccess('contact', 'create', $params, NULL, 'overfluous permissions should be enough to create a contact');
6a488035
TO
1507 }
1508
1509 function testContactUpdatePermissions() {
f6722559 1510 $params = array('contact_type' => 'Individual', 'first_name' => 'Foo', 'last_name' => 'Bear', 'check_permissions' => TRUE,);
1511 $result = $this->callAPISuccess('contact', 'create', $params);
6a488035 1512 $config = CRM_Core_Config::singleton();
f6722559 1513 $params = array('id' => $result['id'], 'contact_type' => 'Individual', 'last_name' => 'Bar', 'check_permissions' => TRUE,);
6a488035
TO
1514
1515 $config->userPermissionClass->permissions = array('access CiviCRM');
d0e1eff2 1516 $result = $this->callAPIFailure('contact', 'update', $params);
6a488035
TO
1517 $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');
1518
1519 $config->userPermissionClass->permissions = array('access CiviCRM', 'add contacts', 'view all contacts', 'edit all contacts', 'import contacts');
f6722559 1520 $result = $this->callAPISuccess('contact', 'update', $params, NULL, 'overfluous permissions should be enough to update a contact');
6a488035
TO
1521 }
1522
1523 function createContactFromXML() {
1524 // Insert a row in civicrm_contact creating contact 17
1525 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1526 $op->execute($this->_dbconn,
1527 new PHPUnit_Extensions_Database_DataSet_XMLDataSet(
1528 dirname(__FILE__) . '/dataset/contact_17.xml'
1529 )
1530 );
1531 }
1532
1533 function testContactProximity() {
1534 // first create a contact with a SF location with a specific
1535 // geocode
1536 $contactID = $this->organizationCreate();
1537
1538 // now create the address
1539 $params = array(
1540 'street_address' => '123 Main Street',
1541 'city' => 'San Francisco',
1542 'is_primary' => 1,
1543 'country_id' => 1228,
1544 'state_province_id' => 1004,
1545 'geo_code_1' => '37.79',
1546 'geo_code_2' => '-122.40',
1547 'location_type_id' => 1,
1548 'contact_id' => $contactID,
6a488035
TO
1549 );
1550
f6722559 1551 $result = $this->callAPISuccess('address', 'create', $params);
6a488035
TO
1552 $this->assertEquals(1, $result['count'], 'In line ' . __LINE__);
1553
1554 // now do a proximity search with a close enough geocode and hope to match
1555 // that specific contact only!
1556 $proxParams = array(
1557 'latitude' => 37.7,
1558 'longitude' => -122.3,
1559 'unit' => 'mile',
1560 'distance' => 10,
6a488035 1561 );
f6722559 1562 $result = $this->callAPISuccess('contact', 'proximity', $proxParams);
6a488035
TO
1563 $this->assertEquals(1, $result['count'], 'In line ' . __LINE__);
1564 }
1565}