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