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