Merge pull request #4296 from mrpaulc/CRM-14751
[civicrm-core.git] / tests / phpunit / api / v3 / ContactTest.php
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 */
34 require_once 'CiviTest/CiviUnitTestCase.php';
35
36
37 /**
38 * Test APIv3 civicrm_contact* functions
39 *
40 * @package CiviCRM_APIv3
41 * @subpackage API_Contact
42 */
43
44 class api_v3_ContactTest extends CiviUnitTestCase {
45 public $DBResetRequired = FALSE;
46 protected $_apiversion;
47 protected $_entity;
48 protected $_params;
49
50 protected $_contactID;
51 protected $_financialTypeId =1;
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;
72 $this->_entity = 'contact';
73 $this->_params = array(
74 'first_name' => 'abc1',
75 'contact_type' => 'Individual',
76 'last_name' => 'xyz1',
77 );
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',
88 'civicrm_relationship',
89 'civicrm_uf_match',
90 'civicrm_phone',
91 );
92
93 $this->quickCleanup($tablesToTruncate, TRUE);
94 }
95
96 /**
97 * Test civicrm_contact_create
98 *
99 * Verify that attempt to create individual contact with only
100 * first and last names succeeds
101 */
102 function testAddCreateIndividual() {
103 $oldCount = CRM_Core_DAO::singleValueQuery('select count(*) from civicrm_contact');
104 $params = array(
105 'first_name' => 'abc1',
106 'contact_type' => 'Individual',
107 'last_name' => 'xyz1',
108 );
109
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);
115
116 $this->assertDBState('CRM_Contact_DAO_Contact',
117 $contact['id'],
118 $params
119 );
120 }
121
122 /**
123 * Test civicrm_contact_create with sub-types
124 *
125 * Verify that sub-types are created successfully and not deleted by subsequent updates
126 */
127 function testIndividualSubType() {
128 $params = array(
129 'first_name' => 'test abc',
130 'contact_type' => 'Individual',
131 'last_name' => 'test xyz',
132 'contact_sub_type' => array('Student', 'Staff'),
133 );
134 $contact = $this->callAPISuccess('contact', 'create', $params);
135 $cid = $contact['id'];
136
137 $params = array(
138 'id' => $cid,
139 'middle_name' => 'foo',
140 );
141 $this->callAPISuccess('contact', 'create', $params);
142 unset($params['middle_name']);
143
144 $contact = $this->callAPISuccess('contact', 'get', $params);
145
146 $this->assertEquals(array('Student', 'Staff'), $contact['values'][$cid]['contact_sub_type'], "In line " . __LINE__);
147 }
148
149 /**
150 * Verify that attempt to create contact with empty params fails
151 */
152 function testCreateEmptyContact() {
153 $this->callAPIFailure('contact', 'create', array());
154 }
155
156 /**
157 * Verify that attempt to create contact with bad contact type fails
158 */
159 function testCreateBadTypeContact() {
160 $params = array(
161 'email' => 'man1@yahoo.com',
162 'contact_type' => 'Does not Exist',
163 );
164 $this->callAPIFailure('contact', 'create', $params,"'Does not Exist' is not a valid option for field contact_type");
165 }
166
167 /**
168 * Verify that attempt to create individual contact with required
169 * fields missing fails
170 */
171 function testCreateBadRequiredFieldsIndividual() {
172 $params = array(
173 'middle_name' => 'This field is not required',
174 'contact_type' => 'Individual',
175 );
176 $this->callAPIFailure('contact', 'create', $params);
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 );
188 $this->callAPIFailure('contact', 'create', $params);
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
201 $this->callAPIFailure('contact', 'create', $params);
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,
214 );
215
216 $contact = $this->callAPISuccess('contact', 'create', $params);
217
218 $this->assertEquals(1, $contact['id'], "In line " . __LINE__);
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']);
222
223 $this->callAPISuccess('contact', 'delete', $contact);
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',
235 );
236
237 $contact = $this->callAPISuccess('contact', 'create', $params);
238 $this->assertEquals(1, $contact['id']);
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.',
252 );
253
254 $contact = $this->callAPISuccess('contact', 'create', $params);
255 $result = $this->callAPISuccess('contact', 'getsingle', array('id' => $contact['id']));
256
257 $this->assertArrayKeyExists('prefix_id', $result);
258 $this->assertArrayKeyExists('suffix_id', $result);
259 $this->assertArrayKeyExists('gender_id', $result);
260 $this->assertEquals(4, $result['prefix_id']);
261 $this->assertEquals(1, $result['suffix_id']);
262 }
263
264 /**
265 * Verify that attempt to create individual contact with
266 * first and last names and old key values works
267 */
268 function testCreateNameIndividualrecommendedKeys2() {
269 $params = array(
270 'prefix_id' => 'Dr.',
271 'first_name' => 'abc1',
272 'contact_type' => 'Individual',
273 'last_name' => 'xyz1',
274 'suffix_id' => 'Jr.',
275 'gender_id' => 'Male',
276 );
277
278 $contact = $this->callAPISuccess('contact', 'create', $params);
279 $result = $this->callAPISuccess('contact', 'getsingle', array('id' => $contact['id']));
280
281 $this->assertArrayKeyExists('prefix_id', $result);
282 $this->assertArrayKeyExists('suffix_id', $result);
283 $this->assertArrayKeyExists('gender_id', $result);
284 $this->assertEquals(4, $result['prefix_id']);
285 $this->assertEquals(1, $result['suffix_id']);
286 }
287
288 /**
289 * Verify that attempt to create household contact with only
290 * household name succeeds
291 */
292 function testCreateNameHousehold() {
293 $params = array(
294 'household_name' => 'The abc Household',
295 'contact_type' => 'Household',
296 );
297 $contact = $this->callAPISuccess('contact', 'create', $params);
298 $this->assertEquals(1, $contact['id'], "In line " . __LINE__);
299 }
300
301 /**
302 * Verify that attempt to create organization contact with only
303 * organization name succeeds
304 */
305 function testCreateNameOrganization() {
306 $params = array(
307 'organization_name' => 'The abc Organization',
308 'contact_type' => 'Organization',
309 );
310 $contact = $this->callAPISuccess('contact', 'create', $params);
311 $this->assertEquals(1, $contact['id']);
312 }
313 /**
314 * Verify that attempt to create organization contact without organization name fails
315 */
316 function testCreateNoNameOrganization() {
317 $params = array(
318 'first_name' => 'The abc Organization',
319 'contact_type' => 'Organization',
320 );
321 $this->callAPIFailure('contact', 'create', $params);
322 }
323 /**
324 * check with complete array + custom field
325 * Note that the test is written on purpose without any
326 * variables specific to participant so it can be replicated into other entities
327 * and / or moved to the automated test suite
328 */
329 function testCreateWithCustom() {
330 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__, __FILE__);
331
332 $params = $this->_params;
333 $params['custom_' . $ids['custom_field_id']] = "custom string";
334 $description = "/*this demonstrates setting a custom field through the API ";
335 $result = $this->callAPIAndDocument($this->_entity, 'create', $params, __FUNCTION__, __FILE__, $description);
336
337 $check = $this->callAPISuccess($this->_entity, 'get', array('return.custom_' . $ids['custom_field_id'] => 1, 'id' => $result['id']));
338 $this->assertEquals("custom string", $check['values'][$check['id']]['custom_' . $ids['custom_field_id']]);
339
340 $this->customFieldDelete($ids['custom_field_id']);
341 $this->customGroupDelete($ids['custom_group_id']);
342 }
343
344 /**
345 * CRM-12773 - expectation is that civicrm quietly ignores
346 * fields without values
347 */
348 function testCreateWithNULLCustomCRM12773() {
349 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__, __FILE__);
350 $params = $this->_params;
351 $params['custom_' . $ids['custom_field_id']] = NULL;
352 $this->callAPISuccess('contact', 'create', $params);
353 $this->customFieldDelete($ids['custom_field_id']);
354 $this->customGroupDelete($ids['custom_group_id']);
355 }
356
357
358 /*
359 * Test creating a current employer through API
360 */
361 function testContactCreateCurrentEmployer(){
362 //here we will just do the get for set-up purposes
363 $count = $this->callAPISuccess('contact', 'getcount', array(
364 'organization_name' => 'new employer org',
365 'contact_type' => 'Organization'
366 ));
367 $this->assertEquals(0, $count);
368 $employerResult = $this->callAPISuccess('contact', 'create', array_merge($this->_params, array(
369 'current_employer' => 'new employer org',)
370 ));
371 // do it again as an update to check it doesn't cause an error
372 $employerResult = $this->callAPISuccess('contact', 'create', array_merge($this->_params, array(
373 'current_employer' => 'new employer org', 'id' => $employerResult['id'])
374 ));
375 $expectedCount = 1;
376 $this->callAPISuccess('contact', 'getcount', array(
377 'organization_name' => 'new employer org',
378 'contact_type' => 'Organization'
379 ),
380 $expectedCount);
381
382 $result = $this->callAPISuccess('contact', 'getsingle', array(
383 'id' => $employerResult['id'],
384 ));
385
386 $this->assertEquals('new employer org', $result['current_employer']);
387
388 }
389 /*
390 * Test creating a current employer through API
391 * - check it will re-activate a de-activated employer
392 */
393 function testContactCreateDuplicateCurrentEmployerEnables(){
394 //set up - create employer relationship
395 $employerResult = $this->callAPISuccess('contact', 'create', array_merge($this->_params, array(
396 'current_employer' => 'new employer org',)
397 ));
398 $relationship = $this->callAPISuccess('relationship','get', array(
399 'contact_id_a' => $employerResult['id'],
400 ));
401
402 //disable & check it is disabled
403 $this->callAPISuccess('relationship', 'create', array('id' => $relationship['id'], 'is_active' => 0));
404 $this->callAPISuccess('relationship','getvalue', array(
405 'id' => $relationship['id'],
406 'return' => 'is_active'
407 ), 0);
408
409 //re-set the current employer - thus enabling the relationshp
410 $this->callAPISuccess('contact', 'create', array_merge($this->_params, array(
411 'current_employer' => 'new employer org', 'id' => $employerResult['id'])
412 ));
413 //check is_active is now 1
414 $relationship = $this->callAPISuccess('relationship','getsingle', array(
415 'return' => 'is_active',));
416 $this->assertEquals(1, $relationship['is_active']);
417 }
418
419 /**
420 * Check deceased contacts are not retrieved
421 * Note at time of writing the default is to return default. This should possibly be changed & test added
422 *
423 */
424 function testGetDeceasedRetrieved() {
425 $this->callAPISuccess($this->_entity, 'create', $this->_params);
426 $c2 = $this->callAPISuccess($this->_entity, 'create', array('first_name' => 'bb', 'last_name' => 'ccc', 'contact_type' => 'Individual', 'is_deceased' => 1));
427 $result = $this->callAPISuccess($this->_entity, 'get', array('is_deceased' => 0));
428 $this->assertFalse(array_key_exists($c2['id'], $result['values']));
429 }
430
431 /*
432 * Test that sort works - old syntax
433 */
434 function testGetSort() {
435 $c1 = $this->callAPISuccess($this->_entity, 'create', $this->_params);
436 $c2 = $this->callAPISuccess($this->_entity, 'create', array('first_name' => 'bb', 'last_name' => 'ccc', 'contact_type' => 'Individual'));
437 $result = $this->callAPISuccess($this->_entity, 'get', array(
438 'sort' => 'first_name ASC',
439 'return.first_name' => 1,
440 'sequential' => 1,
441 'rowCount' => 1,
442 ));
443
444 $this->assertEquals('abc1', $result['values'][0]['first_name']);
445 $result = $this->callAPISuccess($this->_entity, 'get', array(
446 'sort' => 'first_name DESC',
447 'return.first_name' => 1,
448 'sequential' => 1,
449 'rowCount' => 1,
450 ));
451 $this->assertEquals('bb', $result['values'][0]['first_name']);
452
453 $this->callAPISuccess($this->_entity, 'delete', array('id' => $c1['id']));
454 $this->callAPISuccess($this->_entity, 'delete', array('id' => $c2['id']));
455 }
456 /*
457 * Test that we can retrieve contacts using
458 * 'id' => array('IN' => array('3,4')) syntax
459 */
460 function testGetINIDArray() {
461 $c1 = $this->callAPISuccess($this->_entity, 'create', $this->_params);
462 $c2 = $this->callAPISuccess($this->_entity, 'create', array('first_name' => 'bb', 'last_name' => 'ccc', 'contact_type' => 'Individual'));
463 $c3 = $this->callAPISuccess($this->_entity, 'create', array('first_name' => 'hh', 'last_name' => 'll', 'contact_type' => 'Individual'));
464 $result = $this->callAPISuccess($this->_entity, 'get', array('id' => array('IN' => array($c1['id'], $c3['id']))));
465 $this->assertEquals(2, $result['count']);
466 $this->assertEquals(array($c1['id'], $c3['id']), array_keys($result['values']));
467 $this->callAPISuccess($this->_entity, 'delete', array('id' => $c1['id']));
468 $this->callAPISuccess($this->_entity, 'delete', array('id' => $c2['id']));
469 $this->callAPISuccess($this->_entity, 'delete', array('id' => $c3['id']));
470 }
471 /*
472 * Test variants on deleted behaviour
473 */
474 function testGetDeleted() {
475 $params = $this->_params;
476 $contact1 = $this->callAPISuccess('contact', 'create', $params);
477 $params['is_deleted'] = 1;
478 $params['last_name'] = 'bcd';
479 $contact2 = $this->callAPISuccess('contact', 'create', $params);
480 $countActive = $this->callAPISuccess('contact', 'getcount', array('showAll' => 'active'));
481 $countAll = $this->callAPISuccess('contact', 'getcount', array('showAll' => 'all'));
482 $countTrash = $this->callAPISuccess('contact', 'getcount', array('showAll' => 'trash'));
483 $countDefault = $this->callAPISuccess('contact', 'getcount', array());
484 $countDeleted = $this->callAPISuccess('contact', 'getcount', array(
485 'contact_is_deleted' => 1,
486 ));
487 $countNotDeleted = $this->callAPISuccess('contact', 'getcount', array(
488 'contact_is_deleted' => 0,
489 ));
490 $this->callAPISuccess('contact', 'delete', array('id' => $contact1['id']));
491 $this->callAPISuccess('contact', 'delete', array('id' => $contact2['id']));
492 $this->assertEquals(1, $countNotDeleted, 'contact_is_deleted => 0 is respected in line ' . __LINE__);
493 $this->assertEquals(1, $countActive, 'in line ' . __LINE__);
494 $this->assertEquals(1, $countTrash, 'in line ' . __LINE__);
495 $this->assertEquals(2, $countAll, 'in line ' . __LINE__);
496 $this->assertEquals(1, $countDeleted, 'in line ' . __LINE__);
497 $this->assertEquals(1, $countDefault, 'Only active by default in line ' . __LINE__);
498 }
499 /*
500 * Test that sort works - new syntax
501 */
502 function testGetSortNewSYntax() {
503 $c1 = $this->callAPISuccess($this->_entity, 'create', $this->_params);
504 $c2 = $this->callAPISuccess($this->_entity, 'create', array('first_name' => 'bb', 'last_name' => 'ccc', 'contact_type' => 'Individual'));
505 $result = $this->callAPISuccess($this->_entity, 'getvalue', array(
506 'return' => 'first_name',
507 'options' => array(
508 'limit' => 1,
509 'sort' => 'first_name',
510 ),
511 ));
512 $this->assertEquals('abc1', $result, 'in line' . __LINE__);
513
514 $result = $this->callAPISuccess($this->_entity, 'getvalue', array(
515 'return' => 'first_name',
516 'options' => array(
517 'limit' => 1,
518 'sort' => 'first_name DESC',
519 ),
520 ));
521 $this->assertEquals('bb', $result);
522
523 $this->callAPISuccess($this->_entity, 'delete', array('id' => $c1['id']));
524 $this->callAPISuccess($this->_entity, 'delete', array('id' => $c2['id']));
525 }
526 /*
527 * Test apostrophe works in get & create
528 */
529 function testGetApostropheCRM10857() {
530 $params = array_merge($this->_params, array('last_name' => "O'Connor"));
531 $this->callAPISuccess($this->_entity, 'create', $params);
532 $result = $this->callAPISuccess($this->_entity, 'getsingle', array(
533 'last_name' => "O'Connor",
534 'sequential' => 1,
535 ));
536 $this->assertEquals("O'Connor", $result['last_name'], 'in line' . __LINE__);
537 }
538
539 /**
540 * check with complete array + custom field
541 * Note that the test is written on purpose without any
542 * variables specific to participant so it can be replicated into other entities
543 * and / or moved to the automated test suite
544 */
545 function testGetWithCustom() {
546 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__, __FILE__);
547
548 $params = $this->_params;
549 $params['custom_' . $ids['custom_field_id']] = "custom string";
550 $description = "/*this demonstrates setting a custom field through the API ";
551 $subfile = "CustomFieldGet";
552 $result = $this->callAPISuccess($this->_entity, 'create', $params);
553
554 $check = $this->callAPIAndDocument($this->_entity, 'get', array('return.custom_' . $ids['custom_field_id'] => 1, 'id' => $result['id']), __FUNCTION__, __FILE__, $description, $subfile);
555
556 $this->assertEquals("custom string", $check['values'][$check['id']]['custom_' . $ids['custom_field_id']]);
557 $fields = ($this->callAPISuccess('contact', 'getfields', $params));
558 $this->assertTrue(is_array($fields['values']['custom_' . $ids['custom_field_id']]));
559 $this->customFieldDelete($ids['custom_field_id']);
560 $this->customGroupDelete($ids['custom_group_id']);
561 }
562 /*
563 * check with complete array + custom field
564 * Note that the test is written on purpose without any
565 * variables specific to participant so it can be replicated into other entities
566 * and / or moved to the automated test suite
567 */
568 function testGetWithCustomReturnSyntax() {
569 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__, __FILE__);
570
571 $params = $this->_params;
572 $params['custom_' . $ids['custom_field_id']] = "custom string";
573 $description = "/*this demonstrates setting a custom field through the API ";
574 $subfile = "CustomFieldGetReturnSyntaxVariation";
575 $result = $this->callAPISuccess($this->_entity, 'create', $params);
576 $params = array('return' => 'custom_' . $ids['custom_field_id'], 'id' => $result['id']);
577 $check = $this->callAPIAndDocument($this->_entity, 'get', $params, __FUNCTION__, __FILE__, $description, $subfile);
578
579 $this->assertEquals("custom string", $check['values'][$check['id']]['custom_' . $ids['custom_field_id']]);
580 $this->customFieldDelete($ids['custom_field_id']);
581 $this->customGroupDelete($ids['custom_group_id']);
582 }
583
584 /**
585 * Check that address name is returned if required
586 */
587 function testGetReturnAddressName () {
588 $contactID = $this->individualCreate();
589 $this->callAPISuccess('address', 'create', array('contact_id' => $contactID, 'address_name' => 'My house', 'location_type_id' => 'Home', 'street_address' => '1 my road'));
590 $result = $this->callAPISuccessGetSingle('contact', array('return' => 'address_name, street_address', 'id' => $contactID));
591 $this->assertEquals('1 my road', $result['street_address']);
592 $this->assertEquals('My house', $result['address_name']);
593
594 }
595
596 function testGetGroupIDFromContact() {
597 $groupId = $this->groupCreate();
598 $description = "Get all from group and display contacts";
599 $subFile = "GroupFilterUsingContactAPI";
600 $params = array(
601 'email' => 'man2@yahoo.com',
602 'contact_type' => 'Individual',
603 'location_type_id' => 1,
604 'api.group_contact.create' => array('group_id' => $groupId),
605 );
606
607 $this->callAPISuccess('contact', 'create', $params);
608 // testing as integer
609 $params = array(
610 'filter.group_id' => $groupId,
611 'contact_type' => 'Individual',
612 );
613 $result = $this->callAPIAndDocument('contact', 'get', $params, __FUNCTION__, __FILE__, $description, $subFile);
614 $this->assertEquals(1, $result['count']);
615 // group 26 doesn't exist, but we can still search contacts in it.
616 $params = array(
617 'filter.group_id' => 26,
618 'contact_type' => 'Individual',
619 );
620 $this->callAPISuccess('contact', 'get', $params);
621 // testing as string
622 $params = array(
623 'filter.group_id' => "$groupId, 26",
624 'contact_type' => 'Individual',
625 );
626 $result = $this->callAPIAndDocument('contact', 'get', $params, __FUNCTION__, __FILE__, $description, $subFile);
627 $this->assertEquals(1, $result['count']);
628 $params = array(
629 'filter.group_id' => "26,27",
630 'contact_type' => 'Individual',
631 );
632 $this->callAPISuccess('contact', 'get', $params);
633
634 // testing as string
635 $params = array('filter.group_id' => array($groupId, 26),
636 'contact_type' => 'Individual',
637 );
638 $result = $this->callAPIAndDocument('contact', 'get', $params, __FUNCTION__, __FILE__, $description, $subFile);
639 $this->assertEquals(1, $result['count']);
640
641 //test in conjunction with other criteria
642 $params = array('filter.group_id' => array($groupId, 26),
643 'contact_type' => 'Organization',
644 );
645 $this->callAPISuccess('contact', 'get', $params);
646 $params = array('filter.group_id' => array(26, 27),
647 'contact_type' => 'Individual',
648 );
649 $result = $this->callAPISuccess('contact', 'get', $params);
650 $this->assertEquals(0, $result['count']);
651 }
652
653 /**
654 * Verify that attempt to create individual contact with two chained websites succeeds
655 */
656 function testCreateIndividualWithContributionDottedSyntax() {
657 $description = "test demonstrates the syntax to create 2 chained entities";
658 $subFile = "ChainTwoWebsites";
659 $params = array(
660 'first_name' => 'abc3',
661 'last_name' => 'xyz3',
662 'contact_type' => 'Individual',
663 'email' => 'man3@yahoo.com',
664 'api.contribution.create' => array(
665 'receive_date' => '2010-01-01',
666 'total_amount' => 100.00,
667 'financial_type_id' => $this->_financialTypeId,
668 'payment_instrument_id' => 1,
669 'non_deductible_amount' => 10.00,
670 'fee_amount' => 50.00,
671 'net_amount' => 90.00,
672 'trxn_id' => 15345,
673 'invoice_id' => 67990,
674 'source' => 'SSF',
675 'contribution_status_id' => 1,
676 ),
677 'api.website.create' => array(
678 'url' => "http://civicrm.org",
679 ),
680 'api.website.create.2' => array(
681 'url' => "http://chained.org",
682 ),
683 );
684
685 $result = $this->callAPIAndDocument('Contact', 'create', $params, __FUNCTION__, __FILE__, $description, $subFile);
686
687 $this->assertEquals(1, $result['id'], "In line " . __LINE__);
688 // checking child function result not covered in callAPIAndDocument
689 $this->assertAPISuccess($result['values'][$result['id']]['api.website.create']);
690 $this->assertEquals("http://chained.org", $result['values'][$result['id']]['api.website.create.2']['values'][0]['url'], "In line " . __LINE__);
691 $this->assertEquals("http://civicrm.org", $result['values'][$result['id']]['api.website.create']['values'][0]['url'], "In line " . __LINE__);
692
693 // delete the contact
694 $this->callAPISuccess('contact', 'delete', $result);
695 }
696
697 /**
698 * Verify that attempt to create individual contact with chained contribution and website succeeds
699 */
700 function testCreateIndividualWithContributionChainedArrays() {
701 $params = array(
702 'first_name' => 'abc3',
703 'last_name' => 'xyz3',
704 'contact_type' => 'Individual',
705 'email' => 'man3@yahoo.com',
706 'api.contribution.create' => array(
707 'receive_date' => '2010-01-01',
708 'total_amount' => 100.00,
709 'financial_type_id' => $this->_financialTypeId,
710 'payment_instrument_id' => 1,
711 'non_deductible_amount' => 10.00,
712 'fee_amount' => 50.00,
713 'net_amount' => 90.00,
714 'trxn_id' => 12345,
715 'invoice_id' => 67890,
716 'source' => 'SSF',
717 'contribution_status_id' => 1,
718 ),
719 'api.website.create' => array(
720 array(
721 'url' => "http://civicrm.org",
722 ),
723 array(
724 'url' => "http://chained.org",
725 'website_type_id' => 2,
726 ),
727 ),
728 );
729
730 $description = "demonstrates creating two websites as an array";
731 $subfile = "ChainTwoWebsitesSyntax2";
732 $result = $this->callAPIAndDocument('Contact', 'create', $params, __FUNCTION__, __FILE__, $description, $subfile);
733
734 $this->assertEquals(1, $result['id']);
735 // the callAndDocument doesn't check the chained call
736 $this->assertEquals(0, $result['values'][$result['id']]['api.website.create'][0]['is_error'], "In line " . __LINE__);
737 $this->assertEquals("http://chained.org", $result['values'][$result['id']]['api.website.create'][1]['values'][0]['url'], "In line " . __LINE__);
738 $this->assertEquals("http://civicrm.org", $result['values'][$result['id']]['api.website.create'][0]['values'][0]['url'], "In line " . __LINE__);
739
740 $this->callAPISuccess('contact', 'delete', $result);
741 }
742
743 /**
744 * Verify that attempt to create individual contact with first
745 * and last names and email succeeds
746 */
747 function testCreateIndividualWithNameEmail() {
748 $params = array(
749 'first_name' => 'abc3',
750 'last_name' => 'xyz3',
751 'contact_type' => 'Individual',
752 'email' => 'man3@yahoo.com',
753 );
754
755 $contact = $this->callAPISuccess('contact', 'create', $params);
756 $this->assertEquals(1, $contact['id'], "In line " . __LINE__);
757
758 // delete the contact
759 $this->callAPISuccess('contact', 'delete', $contact);
760 }
761 /**
762 * Verify that attempt to create individual contact with no data fails
763 */
764 function testCreateIndividualWithOutNameEmail() {
765 $params = array(
766 'contact_type' => 'Individual',
767 );
768 $this->callAPIFailure('contact', 'create', $params);
769 }
770 /**
771 * Verify that attempt to create individual contact with first
772 * and last names, email and location type succeeds
773 */
774 function testCreateIndividualWithNameEmailLocationType() {
775 $params = array(
776 'first_name' => 'abc4',
777 'last_name' => 'xyz4',
778 'email' => 'man4@yahoo.com',
779 'contact_type' => 'Individual',
780 'location_type_id' => 1,
781 );
782 $result = $this->callAPISuccess('contact', 'create', $params);
783
784 $this->assertEquals(1, $result['id'], "In line " . __LINE__);
785
786 $this->callAPISuccess('contact', 'delete', array('id' => $result['id']));
787 }
788
789 /**
790 * Verify that when changing employers
791 * the old employer relationship becomes inactive
792 */
793 function testCreateIndividualWithEmployer() {
794 $employer = $this->organizationCreate();
795 $employer2 = $this->organizationCreate();
796
797 $params = array(
798 'email' => 'man4@yahoo.com',
799 'contact_type' => 'Individual',
800 'employer_id' => $employer,
801 );
802
803 $result = $this->callAPISuccess('contact', 'create', $params);
804 $relationships = $this->callAPISuccess('relationship', 'get', array(
805 'contact_id_a' => $result['id'],
806 'sequential' => 1,
807 ));
808
809 $this->assertEquals($employer, $relationships['values'][0]['contact_id_b']);
810
811 // Add more random relationships to make the test more realistic
812 foreach (array('Employee of', 'Volunteer for') as $relationshipType) {
813 $relTypeId = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_RelationshipType', $relationshipType, 'id', 'name_a_b');
814 $this->callAPISuccess('relationship', 'create', array(
815 'contact_id_a' => $result['id'],
816 'contact_id_b' => $this->organizationCreate(),
817 'is_active' => 1,
818 'relationship_type_id' => $relTypeId,
819 ));
820 }
821
822 // Add second employer
823 $params['employer_id'] = $employer2;
824 $params['id'] = $result['id'];
825 $result = $this->callAPISuccess('contact', 'create', $params);
826
827 $relationships = $this->callAPISuccess('relationship', 'get', array(
828 'contact_id_a' => $result['id'],
829 'sequential' => 1,
830 'is_active' => 0,
831 ));
832
833 $this->assertEquals($employer, $relationships['values'][0]['contact_id_b']);
834 }
835
836 /**
837 * Verify that attempt to create household contact with details
838 * succeeds
839 */
840 function testCreateHouseholdDetails() {
841 $params = array(
842 'household_name' => 'abc8\'s House',
843 'nick_name' => 'x House',
844 'email' => 'man8@yahoo.com',
845 'contact_type' => 'Household',
846 );
847
848 $contact = $this->callAPISuccess('contact', 'create', $params);
849
850 $this->assertEquals(1, $contact['id'], "In line " . __LINE__);
851
852 $this->callAPISuccess('contact', 'delete', $contact);
853 }
854 /**
855 * Verify that attempt to create household contact with inadequate details
856 * fails
857 */
858 function testCreateHouseholdInadequateDetails() {
859 $params = array(
860 'nick_name' => 'x House',
861 'email' => 'man8@yahoo.com',
862 'contact_type' => 'Household',
863 );
864 $this->callAPIFailure('contact', 'create', $params);
865 }
866
867 /**
868 * Verify successful update of individual contact
869 */
870 function testUpdateIndividualWithAll() {
871 // Insert a row in civicrm_contact creating individual contact
872 $op = new PHPUnit_Extensions_Database_Operation_Insert();
873 $op->execute($this->_dbconn,
874 $this->createXMLDataSet(
875 dirname(__FILE__) . '/dataset/contact_ind.xml'
876 )
877 );
878
879 $params = array(
880 'id' => 23,
881 'first_name' => 'abcd',
882 'contact_type' => 'Individual',
883 'nick_name' => 'This is nickname first',
884 'do_not_email' => '1',
885 'do_not_phone' => '1',
886 'do_not_mail' => '1',
887 'do_not_trade' => '1',
888 'legal_identifier' => 'ABC23853ZZ2235',
889 'external_identifier' => '1928837465',
890 'image_URL' => 'http://some.url.com/image.jpg',
891 'home_url' => 'http://www.example.org',
892
893 );
894
895 $this->callAPISuccess('Contact', 'Update', $params);
896 $getResult = $this->callAPISuccess('Contact', 'Get', $params);
897 unset($params['contact_id']);
898 //Todo - neither API v2 or V3 are testing for home_url - not sure if it is being set.
899 //reducing this test partially back to api v2 level to get it through
900 unset($params['home_url']);
901 foreach ($params as $key => $value) {
902 $this->assertEquals($value, $getResult['values'][23][$key]);
903 }
904 // Check updated civicrm_contact against expected
905 $expected = $this->createXMLDataSet(
906 dirname(__FILE__) . '/dataset/contact_ind_upd.xml'
907 );
908 $actual = new PHPUnit_Extensions_Database_DataSet_QueryDataSet(
909 $this->_dbconn
910 );
911 $actual->addTable('civicrm_contact');
912 $expected->matches($actual);
913 }
914
915 /**
916 * Verify successful update of organization contact
917 */
918 function testUpdateOrganizationWithAll() {
919 // Insert a row in civicrm_contact creating organization contact
920 $op = new PHPUnit_Extensions_Database_Operation_Insert();
921 $op->execute($this->_dbconn,
922 $this->createXMLDataSet(
923 dirname(__FILE__) . '/dataset/contact_org.xml'
924 )
925 );
926
927 $params = array(
928 'id' => 24,
929 'organization_name' => 'WebAccess India Pvt Ltd',
930 'legal_name' => 'WebAccess',
931 'sic_code' => 'ABC12DEF',
932 'contact_type' => 'Organization',
933 );
934
935 $this->callAPISuccess('Contact', 'Update', $params);
936
937 // Check updated civicrm_contact against expected
938 $expected = $this->createXMLDataSet(
939 dirname(__FILE__) . '/dataset/contact_org_upd.xml'
940 );
941 $actual = new PHPUnit_Extensions_Database_DataSet_QueryDataSet(
942 $this->_dbconn
943 );
944 $actual->addTable('civicrm_contact');
945 $expected->matches($actual);
946 }
947
948 /**
949 * Verify successful update of household contact
950 */
951 function testUpdateHouseholdwithAll() {
952 // Insert a row in civicrm_contact creating household contact
953 $op = new PHPUnit_Extensions_Database_Operation_Insert();
954 $op->execute($this->_dbconn,
955 $this->createXMLDataSet(
956 dirname(__FILE__) . '/dataset/contact_hld.xml'
957 )
958 );
959
960 $params = array(
961 'id' => 25,
962 'household_name' => 'ABC household',
963 'nick_name' => 'ABC House',
964 'contact_type' => 'Household',
965 );
966
967 $result = $this->callAPISuccess('Contact', 'Update', $params);
968
969 $expected = array(
970 'contact_type' => 'Household',
971 'is_opt_out' => 0,
972 'sort_name' => 'ABC household',
973 'display_name' => 'ABC household',
974 'nick_name' => 'ABC House',
975 );
976 $this->getAndCheck($expected, $result['id'], 'contact');
977 }
978
979 /**
980 * Test civicrm_update() Deliberately exclude contact_type as it should still
981 * cope using civicrm_api CRM-7645
982 */
983
984 public function testUpdateCreateWithID() {
985 // Insert a row in civicrm_contact creating individual contact
986 $op = new PHPUnit_Extensions_Database_Operation_Insert();
987 $op->execute($this->_dbconn,
988 $this->createXMLDataSet(
989 dirname(__FILE__) . '/dataset/contact_ind.xml'
990 )
991 );
992
993
994
995 $params = array(
996 'id' => 23,
997 'first_name' => 'abcd',
998 'last_name' => 'wxyz',
999 );
1000 $this->callAPISuccess('Contact', 'Update', $params);
1001 }
1002
1003 /**
1004 * Test civicrm_contact_delete() with no contact ID
1005 */
1006 function testContactDeleteNoID() {
1007 $params = array(
1008 'foo' => 'bar',
1009 );
1010 $this->callAPIFailure('contact', 'delete', $params);
1011 }
1012
1013 /**
1014 * Test civicrm_contact_delete() with error
1015 */
1016 function testContactDeleteError() {
1017 $params = array('contact_id' => 999);
1018 $this->callAPIFailure('contact', 'delete', $params);
1019 }
1020
1021 /**
1022 * Test civicrm_contact_delete()
1023 */
1024 function testContactDelete() {
1025 $contactID = $this->individualCreate();
1026 $params = array(
1027 'id' => $contactID ,
1028 );
1029 $this->callAPIAndDocument('contact', 'delete', $params, __FUNCTION__, __FILE__);
1030 }
1031
1032 /**
1033 * Test civicrm_contact_get() return only first name
1034 */
1035 public function testContactGetRetFirst() {
1036 $contact = $this->callAPISuccess('contact', 'create', $this->_params);
1037 $params = array(
1038 'contact_id' => $contact['id'],
1039 'return_first_name' => TRUE,
1040 'sort' => 'first_name',
1041 );
1042 $result = $this->callAPISuccess('contact', 'get', $params);
1043 $this->assertEquals(1, $result['count']);
1044 $this->assertEquals($contact['id'], $result['id']);
1045 $this->assertEquals('abc1', $result['values'][$contact['id']]['first_name']);
1046 }
1047
1048 /**
1049 * Test civicrm_contact_get() return only first name & last name
1050 * Use comma separated string return with a space
1051 */
1052 public function testContactGetRetFirstLast() {
1053 $contact = $this->callAPISuccess('contact', 'create', $this->_params);
1054 $params = array(
1055 'contact_id' => $contact['id'],
1056 'return' => 'first_name, last_name',
1057 );
1058 $result = $this->callAPISuccess('contact', 'getsingle', $params);
1059 $this->assertEquals('abc1', $result['first_name']);
1060 $this->assertEquals('xyz1', $result['last_name']);
1061 //check that other defaults not returns
1062 $this->assertArrayNotHasKey('sort_name', $result);
1063 $params = array(
1064 'contact_id' => $contact['id'],
1065 'return' => 'first_name,last_name',
1066 );
1067 $result = $this->callAPISuccess('contact', 'getsingle', $params);
1068 $this->assertEquals('abc1', $result['first_name']);
1069 $this->assertEquals('xyz1', $result['last_name']);
1070 //check that other defaults not returns
1071 $this->assertArrayNotHasKey('sort_name', $result);
1072 }
1073
1074 /**
1075 * Test civicrm_contact_get() return only first name & last name
1076 * Use comma separated string return without a space
1077 */
1078 public function testContactGetRetFirstLastNoComma() {
1079 $contact = $this->callAPISuccess('contact', 'create', $this->_params);
1080 $params = array(
1081 'contact_id' => $contact['id'],
1082 'return' => 'first_name,last_name',
1083 );
1084 $result = $this->callAPISuccess('contact', 'getsingle', $params);
1085 $this->assertEquals('abc1', $result['first_name']);
1086 $this->assertEquals('xyz1', $result['last_name']);
1087 //check that other defaults not returns
1088 $this->assertArrayNotHasKey('sort_name', $result);
1089 }
1090
1091 /**
1092 * Test civicrm_contact_get() with default return properties
1093 */
1094 public function testContactGetRetDefault() {
1095 $contactID = $this->individualCreate();
1096 $params = array(
1097 'contact_id' => $contactID,
1098 'sort' => 'first_name',
1099 );
1100 $result = $this->callAPISuccess('contact', 'get', $params);
1101 $this->assertEquals($contactID, $result['values'][$contactID]['contact_id']);
1102 $this->assertEquals('Anthony', $result['values'][$contactID]['first_name']);
1103 }
1104
1105 /**
1106 * Test civicrm_contact_getquick() with empty name param
1107 */
1108 public function testContactGetQuick() {
1109 // Insert a row in civicrm_contact creating individual contact
1110 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1111 $op->execute($this->_dbconn,
1112 $this->createXMLDataSet(
1113 dirname(__FILE__) . '/dataset/contact_17.xml'
1114 )
1115 );
1116 $op->execute($this->_dbconn,
1117 $this->createXMLDataSet(
1118 dirname(__FILE__) . '/dataset/email_contact_17.xml'
1119 )
1120 );
1121 $params = array(
1122 'name' => "T",
1123 );
1124
1125 $result = $this->callAPISuccess('contact', 'getquick', $params);
1126 $this->assertEquals(17, $result['values'][0]['id'], 'in line ' . __LINE__);
1127 }
1128
1129 /**
1130 * Test civicrm_contact_get) with empty params
1131 */
1132 public function testContactGetEmptyParams() {
1133 $this->callAPISuccess('contact', 'get', array());
1134 }
1135
1136 /**
1137 * Test civicrm_contact_get(,true) with no matches
1138 */
1139 public function testContactGetOldParamsNoMatches() {
1140 // Insert a row in civicrm_contact creating contact 17
1141 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1142 $op->execute($this->_dbconn,
1143 $this->createXMLDataSet(
1144 dirname(__FILE__) . '/dataset/contact_17.xml'
1145 )
1146 );
1147
1148 $params = array(
1149 'first_name' => 'Fred',
1150 );
1151 $result = $this->callAPISuccess('contact', 'get', $params);
1152 $this->assertEquals(0, $result['count'], 'in line ' . __LINE__);
1153 }
1154
1155 /**
1156 * Test civicrm_contact_get(,true) with one match
1157 */
1158 public function testContactGetOldParamsOneMatch() {
1159 // Insert a row in civicrm_contact creating contact 17
1160 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1161 $op->execute($this->_dbconn,
1162 $this->createXMLDataSet(dirname(__FILE__) . '/dataset/contact_17.xml'
1163 )
1164 );
1165
1166 $params = array(
1167 'first_name' => 'Test',
1168 );
1169 $result = $this->callAPISuccess('contact', 'get', $params);
1170 $this->assertEquals(17, $result['values'][17]['contact_id'], 'in line ' . __LINE__);
1171 $this->assertEquals(17, $result['id'], 'in line ' . __LINE__);
1172 }
1173
1174 /**
1175 * Test civicrm_contact_search_count()
1176 */
1177 public function testContactGetEmail() {
1178 $params = array(
1179 'email' => 'man2@yahoo.com',
1180 'contact_type' => 'Individual',
1181 'location_type_id' => 1,
1182 );
1183
1184 $contact = $this->callAPISuccess('contact', 'create', $params);
1185
1186 $this->assertEquals(1, $contact['id']);
1187
1188 $params = array(
1189 'email' => 'man2@yahoo.com',
1190 );
1191 $result = $this->callAPIAndDocument('contact', 'get', $params, __FUNCTION__, __FILE__);
1192 $this->assertEquals(1, $result['values'][1]['contact_id']);
1193 $this->assertEquals('man2@yahoo.com', $result['values'][1]['email']);
1194
1195 // delete the contact
1196 $this->callAPISuccess('contact', 'delete', $contact);
1197 }
1198
1199 /**
1200 * Test birth date params incl value, array & birth_date_high, birth_date_low
1201 * && deceased
1202 */
1203 public function testContactGetBirthDate() {
1204 $contact1 = $this->callAPISuccess('contact', 'create', array_merge($this->_params, array('birth_date' => 'first day of next month - 2 years')));
1205 $contact2 = $this->callAPISuccess('contact', 'create', array_merge($this->_params, array('birth_date' => 'first day of next month - 5 years')));
1206 $contact3 = $this->callAPISuccess('contact', 'create', array_merge($this->_params, array('birth_date' => 'first day of next month -20 years')));
1207
1208 $result = $this->callAPISuccess('contact', 'get', array());
1209 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -2 years')), $result['values'][$contact1['id']]['birth_date']);
1210 $result = $this->callAPISuccess('contact', 'get', array('birth_date' => 'first day of next month -5 years'));
1211 $this->assertEquals(1, $result['count']);
1212 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -5 years')), $result['values'][$contact2['id']]['birth_date']);
1213 $result = $this->callAPISuccess('contact', 'get', array('birth_date_high' => date('Y-m-d', strtotime('-6 years'))));
1214 $this->assertEquals(1, $result['count']);
1215 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -20 years')), $result['values'][$contact3['id']]['birth_date']);
1216 $result = $this->callAPISuccess('contact', 'get', array('birth_date_low' => date('Y-m-d', strtotime('-6 years')), 'birth_date_high' => date('Y-m-d', strtotime('- 3 years'))));
1217 $this->assertEquals(1, $result['count']);
1218 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -5 years')), $result['values'][$contact2['id']]['birth_date']);
1219 $result = $this->callAPISuccess('contact', 'get', array('birth_date_low' => '-6 years', 'birth_date_high' => '- 3 years'));
1220 $this->assertEquals(1, $result['count']);
1221 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -5 years')), $result['values'][$contact2['id']]['birth_date']);
1222 }
1223
1224 /**
1225 * Test Deceaseddate params incl value, array & Deceased_date_high, Deceaseddate_low
1226 * && deceased
1227 */
1228 public function testContactGetDeceasedDate() {
1229 $contact1 = $this->callAPISuccess('contact', 'create', array_merge($this->_params, array('deceased_date' => 'first day of next month - 2 years')));
1230 $contact2 = $this->callAPISuccess('contact', 'create', array_merge($this->_params, array('deceased_date' => 'first day of next month - 5 years')));
1231 $contact3 = $this->callAPISuccess('contact', 'create', array_merge($this->_params, array('deceased_date' => 'first day of next month -20 years')));
1232
1233 $result = $this->callAPISuccess('contact', 'get', array());
1234 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -2 years')), $result['values'][$contact1['id']]['deceased_date']);
1235 $result = $this->callAPISuccess('contact', 'get', array('deceased_date' => 'first day of next month -5 years'));
1236 $this->assertEquals(1, $result['count']);
1237 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -5 years')), $result['values'][$contact2['id']]['deceased_date']);
1238 $result = $this->callAPISuccess('contact', 'get', array('deceased_date_high' => date('Y-m-d', strtotime('-6 years'))));
1239 $this->assertEquals(1, $result['count']);
1240 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -20 years')), $result['values'][$contact3['id']]['deceased_date']);
1241 $result = $this->callAPISuccess('contact', 'get', array('deceased_date_low' => '-6 years', 'deceased_date_high' => date('Y-m-d', strtotime('- 3 years'))));
1242 $this->assertEquals(1, $result['count']);
1243 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -5 years')), $result['values'][$contact2['id']]['deceased_date']);
1244 }
1245
1246 /**
1247 * Test for Contact.get id=@user:username
1248 */
1249 function testContactGetByUsername() {
1250 // setup - create contact with a uf-match
1251 $cid = $this->individualCreate(array(
1252 'contact_type' => 'Individual',
1253 'first_name' => 'testGetByUsername',
1254 'last_name' => 'testGetByUsername',
1255 ));
1256
1257 $ufMatchParams = array(
1258 'domain_id' => CRM_Core_Config::domainID(),
1259 'uf_id' => 99,
1260 'uf_name' => 'the-email-matching-key-is-not-really-the-username',
1261 'contact_id' => $cid,
1262 );
1263 $ufMatch = CRM_Core_BAO_UFMatch::create($ufMatchParams);
1264 $this->assertTrue(is_numeric($ufMatch->id));
1265
1266 // setup - mock the calls to CRM_Utils_System_*::getUfId
1267 $userSystem = $this->getMock('CRM_Utils_System_UnitTests', array('getUfId'));
1268 $userSystem->expects($this->once())
1269 ->method('getUfId')
1270 ->with($this->equalTo('exampleUser'))
1271 ->will($this->returnValue(99));
1272 CRM_Core_Config::singleton()->userSystem = $userSystem;
1273
1274 // perform a lookup
1275 $result = $this->callAPISuccess('Contact', 'get', array(
1276 'id' => '@user:exampleUser',
1277 ));
1278 $this->assertEquals('testGetByUsername', $result['values'][$cid]['first_name']);
1279 }
1280
1281 /**
1282 * Test to check return works OK
1283 */
1284 function testContactGetReturnValues() {
1285 $extraParams = array('nick_name' => 'Bob', 'phone' => '456', 'email' => 'e@mail.com');
1286 $contactID = $this->individualCreate($extraParams);
1287 //actually it turns out the above doesn't create a phone
1288 $this->callAPISuccess('phone', 'create', array('contact_id' => $contactID, 'phone' => '456',));
1289 $result = $this->callAPISuccess('contact', 'getsingle', array('id' => $contactID));
1290 foreach ($extraParams as $key => $value) {
1291 $this->assertEquals($result[$key], $value);
1292 }
1293 //now we check they are still returned with 'return' key
1294 $result = $this->callAPISuccess('contact', 'getsingle', array('id' => $contactID, 'return' => array_keys($extraParams)));
1295 foreach ($extraParams as $key => $value) {
1296 $this->assertEquals($result[$key], $value);
1297 }
1298 }
1299
1300 function testCRM13252MultipleChainedPhones() {
1301 $contactID = $this->householdCreate();
1302 $this->callAPISuccessGetCount('phone', array('contact_id' => $contactID), 0);
1303 $params = array(
1304 'contact_id' => $contactID,
1305 'household_name' => 'Household 1',
1306 'contact_type' => 'Household',
1307 'api.phone.create' => array(
1308 0 => array(
1309 'phone' => '111-111-1111',
1310 'location_type_id' => 1,
1311 'phone_type_id' => 1,
1312 ),
1313 1 => array(
1314 'phone' => '222-222-2222',
1315 'location_type_id' => 1,
1316 'phone_type_id' => 2,
1317 )
1318 )
1319 );
1320 $this->callAPISuccess('contact', 'create', $params);
1321 $this->callAPISuccessGetCount('phone', array('contact_id' => $contactID), 2);
1322
1323 }
1324 /**
1325 * Test for Contact.get id=@user:username (with an invalid username)
1326 */
1327 function testContactGetByUnknownUsername() {
1328 // setup - mock the calls to CRM_Utils_System_*::getUfId
1329 $userSystem = $this->getMock('CRM_Utils_System_UnitTests', array('getUfId'));
1330 $userSystem->expects($this->once())
1331 ->method('getUfId')
1332 ->with($this->equalTo('exampleUser'))
1333 ->will($this->returnValue(NULL));
1334 CRM_Core_Config::singleton()->userSystem = $userSystem;
1335
1336 // perform a lookup
1337 $result = $this->callAPIFailure('Contact', 'get', array(
1338 'id' => '@user:exampleUser',
1339 ));
1340 $this->assertRegExp('/cannot be resolved to a contact ID/', $result['error_message']);
1341 }
1342
1343 /**
1344 * Verify attempt to create individual with chained arrays
1345 */
1346 function testGetIndividualWithChainedArrays() {
1347 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__, __FILE__);
1348 $params['custom_' . $ids['custom_field_id']] = "custom string";
1349
1350 $moreids = $this->CustomGroupMultipleCreateWithFields();
1351 $description = "/*this demonstrates the usage of chained api functions. In this case no notes or custom fields have been created ";
1352 $subfile = "APIChainedArray";
1353 $params = array(
1354 'first_name' => 'abc3',
1355 'last_name' => 'xyz3',
1356 'contact_type' => 'Individual',
1357 'email' => 'man3@yahoo.com',
1358 'api.contribution.create' => array(
1359 'receive_date' => '2010-01-01',
1360 'total_amount' => 100.00,
1361 'financial_type_id' => 1,
1362 'payment_instrument_id' => 1,
1363 'non_deductible_amount' => 10.00,
1364 'fee_amount' => 50.00,
1365 'net_amount' => 90.00,
1366 'trxn_id' => 12345,
1367 'invoice_id' => 67890,
1368 'source' => 'SSF',
1369 'contribution_status_id' => 1,
1370 ),
1371 'api.contribution.create.1' => array(
1372 'receive_date' => '2011-01-01',
1373 'total_amount' => 120.00,
1374 'financial_type_id' => $this->_financialTypeId =1,
1375 'payment_instrument_id' => 1,
1376 'non_deductible_amount' => 10.00,
1377 'fee_amount' => 50.00,
1378 'net_amount' => 90.00,
1379 'trxn_id' => 12335,
1380 'invoice_id' => 67830,
1381 'source' => 'SSF',
1382 'contribution_status_id' => 1,
1383 ),
1384 'api.website.create' => array(
1385 array(
1386 'url' => "http://civicrm.org",
1387 ),
1388 ),
1389 );
1390
1391 $result = $this->callAPISuccess('Contact', 'create', $params);
1392 $params = array(
1393 'id' => $result['id'],
1394 'api.website.get' => array(),
1395 'api.Contribution.get' => array(
1396 'total_amount' => '120.00',
1397 ), 'api.CustomValue.get' => 1,
1398 'api.Note.get' => 1,
1399 );
1400 $result = $this->callAPIAndDocument('Contact', 'Get', $params, __FUNCTION__, __FILE__, $description, $subfile);
1401 // delete the contact
1402 $this->callAPISuccess('contact', 'delete', $result);
1403 $this->customGroupDelete($ids['custom_group_id']);
1404 $this->customGroupDelete($moreids['custom_group_id']);
1405 $this->assertEquals(1, $result['id']);
1406 $this->assertEquals(0, $result['values'][$result['id']]['api.website.get']['is_error']);
1407 $this->assertEquals("http://civicrm.org", $result['values'][$result['id']]['api.website.get']['values'][0]['url']);
1408 }
1409
1410 function testGetIndividualWithChainedArraysFormats() {
1411 $description = "/*this demonstrates the usage of chained api functions. A variety of return formats are used. Note that no notes
1412 *custom fields or memberships exist";
1413 $subfile = "APIChainedArrayFormats";
1414 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__, __FILE__);
1415 $params['custom_' . $ids['custom_field_id']] = "custom string";
1416
1417 $moreids = $this->CustomGroupMultipleCreateWithFields();
1418 $params = array(
1419 'first_name' => 'abc3',
1420 'last_name' => 'xyz3',
1421 'contact_type' => 'Individual',
1422 'email' => 'man3@yahoo.com',
1423 'api.contribution.create' => array(
1424 'receive_date' => '2010-01-01',
1425 'total_amount' => 100.00,
1426 'financial_type_id' => $this->_financialTypeId,
1427 'payment_instrument_id' => 1,
1428 'non_deductible_amount' => 10.00,
1429 'fee_amount' => 50.00,
1430 'net_amount' => 90.00,
1431 'source' => 'SSF',
1432 'contribution_status_id' => 1,
1433 ),
1434 'api.contribution.create.1' => array(
1435 'receive_date' => '2011-01-01',
1436 'total_amount' => 120.00,
1437 'financial_type_id' => $this->_financialTypeId,
1438 'payment_instrument_id' => 1,
1439 'non_deductible_amount' => 10.00,
1440 'fee_amount' => 50.00,
1441 'net_amount' => 90.00,
1442 'source' => 'SSF',
1443 'contribution_status_id' => 1,
1444 ),
1445 'api.website.create' => array(
1446 array(
1447 'url' => "http://civicrm.org",
1448 ),
1449 ),
1450 );
1451
1452
1453 $result = $this->callAPISuccess('Contact', 'create', $params);
1454 $params = array(
1455 'id' => $result['id'],
1456 'api.website.getValue' => array('return' => 'url'),
1457 'api.Contribution.getCount' => array(),
1458 'api.CustomValue.get' => 1,
1459 'api.Note.get' => 1,
1460 'api.Membership.getCount' => array(),
1461 );
1462 $result = $this->callAPIAndDocument('Contact', 'Get', $params, __FUNCTION__, __FILE__, $description, $subfile);
1463 $this->assertEquals(1, $result['id']);
1464 $this->assertEquals(2, $result['values'][$result['id']]['api.Contribution.getCount']);
1465 $this->assertEquals(0, $result['values'][$result['id']]['api.Note.get']['is_error']);
1466 $this->assertEquals("http://civicrm.org", $result['values'][$result['id']]['api.website.getValue']);
1467
1468 $this->callAPISuccess('contact', 'delete', $result);
1469 $this->customGroupDelete($ids['custom_group_id']);
1470 $this->customGroupDelete($moreids['custom_group_id']);
1471 }
1472
1473 function testGetIndividualWithChainedArraysAndMultipleCustom() {
1474 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__, __FILE__);
1475 $params['custom_' . $ids['custom_field_id']] = "custom string";
1476 $moreids = $this->CustomGroupMultipleCreateWithFields();
1477 $andmoreids = $this->CustomGroupMultipleCreateWithFields(array('title' => "another group", 'name' => 'another name'));
1478 $description = "/*this demonstrates the usage of chained api functions. A variety of techniques are used";
1479 $subfile = "APIChainedArrayMultipleCustom";
1480 $params = array(
1481 'first_name' => 'abc3',
1482 'last_name' => 'xyz3',
1483 'contact_type' => 'Individual',
1484 'email' => 'man3@yahoo.com',
1485 'api.contribution.create' => array(
1486 'receive_date' => '2010-01-01',
1487 'total_amount' => 100.00,
1488 'financial_type_id' => 1,
1489 'payment_instrument_id' => 1,
1490 'non_deductible_amount' => 10.00,
1491 'fee_amount' => 50.00,
1492 'net_amount' => 90.00,
1493 'trxn_id' => 12345,
1494 'invoice_id' => 67890,
1495 'source' => 'SSF',
1496 'contribution_status_id' => 1,
1497 ),
1498 'api.contribution.create.1' => array(
1499 'receive_date' => '2011-01-01',
1500 'total_amount' => 120.00,
1501 'financial_type_id' => 1,
1502 'payment_instrument_id' => 1,
1503 'non_deductible_amount' => 10.00,
1504 'fee_amount' => 50.00,
1505 'net_amount' => 90.00,
1506 'trxn_id' => 12335,
1507 'invoice_id' => 67830,
1508 'source' => 'SSF',
1509 'contribution_status_id' => 1,
1510 ),
1511 'api.website.create' => array(
1512 array(
1513 'url' => "http://civicrm.org",
1514 ),
1515 ),
1516 'custom_' . $ids['custom_field_id'] => "value 1",
1517 'custom_' . $moreids['custom_field_id'][0] => "value 2",
1518 'custom_' . $moreids['custom_field_id'][1] => "warm beer",
1519 'custom_' . $andmoreids['custom_field_id'][1] => "vegemite",
1520 );
1521
1522
1523 $result = $this->callAPISuccess('Contact', 'create', $params);
1524 $result = $this->callAPISuccess('Contact', 'create', array(
1525 'contact_type' => 'Individual', 'id' => $result['id'], 'custom_' . $moreids['custom_field_id'][0] => "value 3", 'custom_' . $ids['custom_field_id'] => "value 4",
1526 ));
1527
1528 $params = array(
1529 'id' => $result['id'],
1530 'api.website.getValue' => array('return' => 'url'),
1531 'api.Contribution.getCount' => array(),
1532 'api.CustomValue.get' => 1,
1533 );
1534 $result = $this->callAPIAndDocument('Contact', 'Get', $params, __FUNCTION__, __FILE__, $description, $subfile);
1535
1536 $this->customGroupDelete($ids['custom_group_id']);
1537 $this->customGroupDelete($moreids['custom_group_id']);
1538 $this->customGroupDelete($andmoreids['custom_group_id']);
1539 $this->assertEquals(1, $result['id']);
1540 $this->assertEquals(0, $result['values'][$result['id']]['api.CustomValue.get']['is_error']);
1541 $this->assertEquals('http://civicrm.org', $result['values'][$result['id']]['api.website.getValue']);
1542 }
1543 /*
1544 * Test checks siusage of $values to pick & choose inputs
1545 */
1546 function testChainingValuesCreate() {
1547 $description = "/*this demonstrates the usage of chained api functions. Specifically it has one 'parent function' &
1548 2 child functions - one receives values from the parent (Contact) and the other child (Tag). ";
1549 $subfile = "APIChainedArrayValuesFromSiblingFunction";
1550 $params = array(
1551 'display_name' => 'batman', 'contact_type' => 'Individual',
1552 'api.tag.create' => array('name' => '$value.id', 'description' => '$value.display_name', 'format.only_id' => 1),
1553 'api.entity_tag.create' => array('tag_id' => '$value.api.tag.create'),
1554 );
1555 $result = $this->callAPIAndDocument('Contact', 'Create', $params, __FUNCTION__, __FILE__, $description, $subfile);
1556 $this->assertEquals(0, $result['values'][$result['id']]['api.entity_tag.create']['is_error']);
1557
1558 $tablesToTruncate = array(
1559 'civicrm_contact',
1560 'civicrm_activity',
1561 'civicrm_entity_tag',
1562 'civicrm_tag',
1563 );
1564 $this->quickCleanup($tablesToTruncate, TRUE);
1565 }
1566
1567 /*
1568 * test TrueFalse format - I couldn't come up with an easy way to get an error on Get
1569 */
1570 function testContactGetFormatIsSuccessTrue() {
1571 $this->createContactFromXML();
1572 $description = "This demonstrates use of the 'format.is_success' param.
1573 This param causes only the success or otherwise of the function to be returned as BOOLEAN";
1574 $subfile = "FormatIsSuccess_True";
1575 $params = array('id' => 17, 'format.is_success' => 1);
1576 $result = $this->callAPIAndDocument('Contact', 'Get', $params, __FUNCTION__, __FILE__, $description, $subfile);
1577 $this->assertEquals(1, $result);
1578 $this->callAPISuccess('Contact', 'Delete', $params);
1579 }
1580 /*
1581 * test TrueFalse format
1582 */
1583 function testContactCreateFormatIsSuccessFalse() {
1584
1585 $description = "This demonstrates use of the 'format.is_success' param.
1586 This param causes only the success or otherwise of the function to be returned as BOOLEAN";
1587 $subfile = "FormatIsSuccess_Fail";
1588 $params = array('id' => 500, 'format.is_success' => 1);
1589 $result = $this->callAPIAndDocument('Contact', 'Create', $params, __FUNCTION__, __FILE__, $description, $subfile);
1590 $this->assertEquals(0, $result);
1591 }
1592 /*
1593 * test Single Entity format
1594 */
1595 function testContactGetSingle_entity_array() {
1596 $this->createContactFromXML();
1597 $description = "This demonstrates use of the 'format.single_entity_array' param.
1598 /* This param causes the only contact to be returned as an array without the other levels.
1599 /* it will be ignored if there is not exactly 1 result";
1600 $subfile = "GetSingleContact";
1601 $params = array('id' => 17);
1602 $result = $this->callAPIAndDocument('Contact', 'GetSingle', $params, __FUNCTION__, __FILE__, $description, $subfile);
1603 $this->assertEquals('Test Contact', $result['display_name']);
1604 $this->callAPISuccess('Contact', 'Delete', $params);
1605 }
1606
1607 /*
1608 * test Single Entity format
1609 */
1610 function testContactGetFormatcount_only() {
1611 $this->createContactFromXML();
1612 $description = "/*This demonstrates use of the 'getCount' action
1613 /* This param causes the count of the only function to be returned as an integer";
1614 $subfile = "GetCountContact";
1615 $params = array('id' => 17);
1616 $result = $this->callAPIAndDocument('Contact', 'GetCount', $params, __FUNCTION__, __FILE__, $description, $subfile);
1617 $this->assertEquals('1', $result);
1618 $this->callAPISuccess('Contact', 'Delete', $params);
1619 }
1620 /*
1621 * Test id only format
1622 */
1623 function testContactGetFormatID_only() {
1624 $this->createContactFromXML();
1625 $description = "This demonstrates use of the 'format.id_only' param.
1626 /* This param causes the id of the only entity to be returned as an integer.
1627 /* it will be ignored if there is not exactly 1 result";
1628 $subfile = "FormatOnlyID";
1629 $params = array('id' => 17, 'format.only_id' => 1);
1630 $result = $this->callAPIAndDocument('Contact', 'Get', $params, __FUNCTION__, __FILE__, $description, $subfile);
1631 $this->assertEquals('17', $result);
1632 $this->callAPISuccess('Contact', 'Delete', $params);
1633 }
1634
1635 /*
1636 * Test id only format
1637 */
1638 function testContactGetFormatSingleValue() {
1639 $this->createContactFromXML();
1640 $description = "This demonstrates use of the 'format.single_value' param.
1641 /* This param causes only a single value of the only entity to be returned as an string.
1642 /* it will be ignored if there is not exactly 1 result";
1643 $subFile = "FormatSingleValue";
1644 $params = array('id' => 17, 'return' => 'display_name');
1645 $result = $this->callAPIAndDocument('Contact', 'getvalue', $params, __FUNCTION__, __FILE__, $description, $subFile,'getvalue');
1646 $this->assertEquals('Test Contact', $result);
1647 $this->callAPISuccess('Contact', 'Delete', $params);
1648 }
1649
1650 /**
1651 * test that permissions are respected when creating contacts
1652 */
1653 function testContactCreationPermissions() {
1654 $params = array(
1655 'contact_type' => 'Individual', 'first_name' => 'Foo',
1656 'last_name' => 'Bear',
1657 'check_permissions' => TRUE,
1658 );
1659 $config = CRM_Core_Config::singleton();
1660 $config->userPermissionClass->permissions = array('access CiviCRM');
1661 $result = $this->callAPIFailure('contact', 'create', $params);
1662 $this->assertEquals('API permission check failed for contact/create call; insufficient permission: require access CiviCRM and add contacts', $result['error_message'], 'lacking permissions should not be enough to create a contact');
1663
1664 $config->userPermissionClass->permissions = array('access CiviCRM', 'add contacts', 'import contacts');
1665 $this->callAPISuccess('contact', 'create', $params, NULL, 'overfluous permissions should be enough to create a contact');
1666 }
1667
1668 function testContactUpdatePermissions() {
1669 $params = array('contact_type' => 'Individual', 'first_name' => 'Foo', 'last_name' => 'Bear', 'check_permissions' => TRUE,);
1670 $result = $this->callAPISuccess('contact', 'create', $params);
1671 $config = CRM_Core_Config::singleton();
1672 $params = array('id' => $result['id'], 'contact_type' => 'Individual', 'last_name' => 'Bar', 'check_permissions' => TRUE,);
1673
1674 $config->userPermissionClass->permissions = array('access CiviCRM');
1675 $result = $this->callAPIFailure('contact', 'update', $params);
1676 $this->assertEquals('API permission check failed for contact/update call; insufficient permission: require access CiviCRM and edit all contacts', $result['error_message'], 'lacking permissions should not be enough to update a contact');
1677
1678 $config->userPermissionClass->permissions = array('access CiviCRM', 'add contacts', 'view all contacts', 'edit all contacts', 'import contacts');
1679 $this->callAPISuccess('contact', 'update', $params, NULL, 'overfluous permissions should be enough to update a contact');
1680 }
1681
1682 function createContactFromXML() {
1683 // Insert a row in civicrm_contact creating contact 17
1684 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1685 $op->execute($this->_dbconn,
1686 $this->createXMLDataSet(
1687 dirname(__FILE__) . '/dataset/contact_17.xml'
1688 )
1689 );
1690 }
1691
1692 function testContactProximity() {
1693 // first create a contact with a SF location with a specific
1694 // geocode
1695 $contactID = $this->organizationCreate();
1696
1697 // now create the address
1698 $params = array(
1699 'street_address' => '123 Main Street',
1700 'city' => 'San Francisco',
1701 'is_primary' => 1,
1702 'country_id' => 1228,
1703 'state_province_id' => 1004,
1704 'geo_code_1' => '37.79',
1705 'geo_code_2' => '-122.40',
1706 'location_type_id' => 1,
1707 'contact_id' => $contactID,
1708 );
1709
1710 $result = $this->callAPISuccess('address', 'create', $params);
1711 $this->assertEquals(1, $result['count'], 'In line ' . __LINE__);
1712
1713 // now do a proximity search with a close enough geocode and hope to match
1714 // that specific contact only!
1715 $proxParams = array(
1716 'latitude' => 37.7,
1717 'longitude' => -122.3,
1718 'unit' => 'mile',
1719 'distance' => 10,
1720 );
1721 $result = $this->callAPISuccess('contact', 'proximity', $proxParams);
1722 $this->assertEquals(1, $result['count'], 'In line ' . __LINE__);
1723 }
1724
1725 /**
1726 * Test that Ajax API permission is sufficient to access getquick api
1727 * (note that getquick api is required for autocomplete & has ACL permissions applied)
1728 */
1729 function testGetquickPermission_CRM_13744() {
1730 CRM_Core_Config::singleton()->userPermissionClass->permissions = array('access CiviEvent');
1731 $this->callAPIFailure('contact', 'getquick', array('name' => 'b', 'check_permissions' => TRUE));
1732 CRM_Core_Config::singleton()->userPermissionClass->permissions = array('access CiviCRM');
1733 $this->callAPISuccess('contact', 'getquick', array('name' => 'b', 'check_permissions' => TRUE));
1734 CRM_Core_Config::singleton()->userPermissionClass->permissions = array('access AJAX API');
1735 $this->callAPISuccess('contact', 'getquick', array('name' => 'b', 'check_permissions' => TRUE));
1736 }
1737
1738 /**
1739 * test get ref api - gets a list of references to an entity
1740 */
1741 function testGetReferenceCounts() {
1742 $result = $this->callAPISuccess('Contact', 'create', array(
1743 'first_name' => 'Testily',
1744 'last_name' => 'McHaste',
1745 'contact_type' => 'Individual',
1746 'api.Address.replace' => array(
1747 'values' => array(),
1748 ),
1749 'api.Email.replace' => array(
1750 'values' => array(
1751 array(
1752 'email' => 'spam@dev.null',
1753 'is_primary' => 0,
1754 'location_type_id' => 1,
1755 )
1756 ),
1757 ),
1758 'api.Phone.replace' => array(
1759 'values' => array(
1760 array(
1761 'phone' => '234-567-0001',
1762 'is_primary' => 1,
1763 'location_type_id' => 1,
1764 ),
1765 array(
1766 'phone' => '234-567-0002',
1767 'is_primary' => 0,
1768 'location_type_id' => 1,
1769 ),
1770 ),
1771 ),
1772 ));
1773
1774 //$dao = new CRM_Contact_BAO_Contact();
1775 //$dao->id = $result['id'];
1776 //$this->assertTrue((bool) $dao->find(TRUE));
1777 //
1778 //$refCounts = $dao->getReferenceCounts();
1779 //$this->assertTrue(is_array($refCounts));
1780 //$refCountsIdx = CRM_Utils_Array::index(array('name'), $refCounts);
1781
1782 $refCounts = $this->callAPISuccess('Contact', 'getrefcount', array(
1783 'id' => $result['id']
1784 ));
1785 $refCountsIdx = CRM_Utils_Array::index(array('name'), $refCounts['values']);
1786
1787 $this->assertEquals(1, $refCountsIdx['sql:civicrm_email:contact_id']['count']);
1788 $this->assertEquals('civicrm_email', $refCountsIdx['sql:civicrm_email:contact_id']['table']);
1789 $this->assertEquals(2, $refCountsIdx['sql:civicrm_phone:contact_id']['count']);
1790 $this->assertEquals('civicrm_phone', $refCountsIdx['sql:civicrm_phone:contact_id']['table']);
1791 $this->assertTrue(!isset($refCountsIdx['sql:civicrm_address:contact_id']));
1792 }
1793
1794 function testSQLOperatorsOnContactAPI() {
1795 $this->individualCreate();
1796 $this->organizationCreate();
1797 $this->householdCreate();
1798 $contacts = $this->callAPISuccess('contact', 'get', array('legal_name' => array('IS NOT NULL' => TRUE)));
1799 $this->assertEquals($contacts['count'], CRM_Core_DAO::singleValueQuery('select count(*) FROM civicrm_contact WHERE legal_name IS NOT NULL'));
1800 $contacts = $this->callAPISuccess('contact', 'get', array('legal_name' => array('IS NULL' => TRUE)));
1801 $this->assertEquals($contacts['count'], CRM_Core_DAO::singleValueQuery('select count(*) FROM civicrm_contact WHERE legal_name IS NULL'));
1802 }
1803
1804 /**
1805 * CRM-14743 - test api respects search operators
1806 */
1807 function testGetModifiedDateByOperators() {
1808 $preExistingContactCount = CRM_Core_DAO::singleValueQuery('select count(*) FROM civicrm_contact');
1809 $contact1 = $this->individualCreate();
1810 $sql = "UPDATE civicrm_contact SET created_date = '2012-01-01', modified_date = '2013-01-01' WHERE id = " . $contact1;
1811 CRM_Core_DAO::executeQuery($sql);
1812 $contact2 = $this->individualCreate();
1813 $sql = "UPDATE civicrm_contact SET created_date = '2012-02-01', modified_date = '2013-02-01' WHERE id = " . $contact2;
1814 CRM_Core_DAO::executeQuery($sql);
1815 $contact3 = $this->householdCreate();
1816 $sql = "UPDATE civicrm_contact SET created_date = '2012-03-01', modified_date = '2013-03-01' WHERE id = " . $contact3;
1817 CRM_Core_DAO::executeQuery($sql);
1818 $contacts = $this->callAPISuccess('contact', 'get', array('modified_date' => array('<' => '2014-01-01')));
1819 $this->assertEquals($contacts['count'], 3);
1820 $contacts = $this->callAPISuccess('contact', 'get', array('modified_date' => array('>' => '2014-01-01')));
1821 $this->assertEquals($contacts['count'], $preExistingContactCount);
1822 }
1823
1824 /**
1825 * CRM-14743 - test api respects search operators
1826 */
1827 function testGetCreatedDateByOperators() {
1828 $preExistingContactCount = CRM_Core_DAO::singleValueQuery('select count(*) FROM civicrm_contact');
1829 $contact1 = $this->individualCreate();
1830 $sql = "UPDATE civicrm_contact SET created_date = '2012-01-01' WHERE id = " . $contact1;
1831 CRM_Core_DAO::executeQuery($sql);
1832 $contact2 = $this->individualCreate();
1833 $sql = "UPDATE civicrm_contact SET created_date = '2012-02-01' WHERE id = " . $contact2;
1834 CRM_Core_DAO::executeQuery($sql);
1835 $contact3 = $this->householdCreate();
1836 $sql = "UPDATE civicrm_contact SET created_date = '2012-03-01' WHERE id = " . $contact3;
1837 CRM_Core_DAO::executeQuery($sql);
1838 $contacts = $this->callAPISuccess('contact', 'get', array('created_date' => array('<' => '2014-01-01')));
1839 $this->assertEquals($contacts['count'], 3);
1840 $contacts = $this->callAPISuccess('contact', 'get', array('created_date' => array('>' => '2014-01-01')));
1841 $this->assertEquals($contacts['count'], $preExistingContactCount);
1842 }
1843
1844 /**
1845 * CRM-14263 check that API is not affected by search profile related bug
1846 */
1847 function testReturnCityProfile () {
1848 $contactID = $this->individualCreate();
1849 CRM_Core_Config::singleton()->defaultSearchProfileID = 1;
1850 $this->callAPISuccess('address', 'create', array('contact_id' => $contactID, 'city' => 'Cool City', 'location_type_id' => 1,));
1851 $result = $this->callAPISuccess('contact', 'get', array('city' => 'Cool City', 'return' => 'contact_type'));
1852 $this->assertEquals(1, $result['count']);
1853 }
1854
1855 /**
1856 * CRM-15443 - ensure getlist api does not return deleted contacts
1857 */
1858 function testGetlistExcludeConditions() {
1859 $name = md5(time());
1860 $contact = $this->individualCreate(array('last_name' => $name));
1861 $deceasedContact = $this->individualCreate(array('last_name' => $name, 'is_deceased' => 1));
1862 $deletedContact = $this->individualCreate(array('last_name' => $name, 'is_deleted' => 1));
1863 // We should get all but the deleted contact
1864 $result = $this->callAPISuccess('contact', 'getlist', array('input' => $name));
1865 $this->assertEquals(2, $result['count'], 'In line ' . __LINE__);
1866 // Force-exclude the deceased contact
1867 $result = $this->callAPISuccess('contact', 'getlist', array('input' => $name, 'params' => array('is_deceased' => 0)));
1868 $this->assertEquals(1, $result['count'], 'In line ' . __LINE__);
1869 $this->assertEquals($contact, $result['values'][0]['id'], 'In line ' . __LINE__);
1870 }
1871
1872 /**
1873 * Test contact.getactions
1874 */
1875 function testGetActions() {
1876 $description = "Getting the available actions for an entity.";
1877 $result = $this->callAPIAndDocument($this->_entity, 'getactions', array(), __FUNCTION__, __FILE__, $description);
1878 $expected = array(
1879 'create',
1880 'delete',
1881 'get',
1882 'getactions',
1883 'getcount',
1884 'getfields',
1885 'getlist',
1886 'getoptions',
1887 'getquick',
1888 'getrefcount',
1889 'getsingle',
1890 'getvalue',
1891 'merge',
1892 'proximity',
1893 'replace',
1894 'setvalue',
1895 'update',
1896 );
1897 $deprecated = array(
1898 'update',
1899 'getquick',
1900 );
1901 foreach ($expected as $action) {
1902 $this->assertTrue(in_array($action, $result['values']), "Expected action $action");
1903 }
1904 foreach ($deprecated as $action) {
1905 $this->assertArrayKeyExists($action, $result['deprecated']);
1906 }
1907 }
1908 }