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