Merge pull request #7913 from uelenpaulo/CRM-17571
[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 * Test APIv3 civicrm_contact* functions
34 *
35 * @package CiviCRM_APIv3
36 * @subpackage API_Contact
37 * @group headless
38 */
39 class api_v3_ContactTest extends CiviUnitTestCase {
40 public $DBResetRequired = FALSE;
41 protected $_apiversion;
42 protected $_entity;
43 protected $_params;
44
45 protected $_contactID;
46 protected $_financialTypeId = 1;
47
48 /**
49 * Test setup for every test.
50 *
51 * Connect to the database, truncate the tables that will be used
52 * and redirect stdin to a temporary file
53 */
54 public function setUp() {
55 // Connect to the database.
56 parent::setUp();
57 $this->_apiversion = 3;
58 $this->_entity = 'contact';
59 $this->_params = array(
60 'first_name' => 'abc1',
61 'contact_type' => 'Individual',
62 'last_name' => 'xyz1',
63 );
64 }
65
66 /**
67 * Restore the DB for the next test.
68 *
69 * @throws \Exception
70 */
71 public function tearDown() {
72 $this->callAPISuccess('Setting', 'create', array('includeOrderByClause' => TRUE));
73 // truncate a few tables
74 $tablesToTruncate = array(
75 'civicrm_email',
76 'civicrm_contribution',
77 'civicrm_line_item',
78 'civicrm_website',
79 'civicrm_relationship',
80 'civicrm_uf_match',
81 'civicrm_phone',
82 'civicrm_address',
83 'civicrm_acl_contact_cache',
84 'civicrm_activity_contact',
85 'civicrm_activity',
86 );
87
88 $this->quickCleanup($tablesToTruncate, TRUE);
89 parent::tearDown();
90 }
91
92 /**
93 * Test civicrm_contact_create.
94 *
95 * Verify that attempt to create individual contact with only
96 * first and last names succeeds
97 */
98 public function testAddCreateIndividual() {
99 $oldCount = CRM_Core_DAO::singleValueQuery('select count(*) from civicrm_contact');
100 $params = array(
101 'first_name' => 'abc1',
102 'contact_type' => 'Individual',
103 'last_name' => 'xyz1',
104 );
105
106 $contact = $this->callAPISuccess('contact', 'create', $params);
107 $this->assertTrue(is_numeric($contact['id']));
108 $this->assertTrue($contact['id'] > 0);
109 $newCount = CRM_Core_DAO::singleValueQuery('select count(*) from civicrm_contact');
110 $this->assertEquals($oldCount + 1, $newCount);
111
112 $this->assertDBState('CRM_Contact_DAO_Contact',
113 $contact['id'],
114 $params
115 );
116 }
117
118 /**
119 * Test civicrm_contact_create.
120 *
121 * Verify that preferred language can be set.
122 */
123 public function testAddCreateIndividualWithPreferredLanguage() {
124 $params = array(
125 'first_name' => 'abc1',
126 'contact_type' => 'Individual',
127 'last_name' => 'xyz1',
128 'preferred_language' => 'es_ES',
129 );
130
131 $contact = $this->callAPISuccess('contact', 'create', $params);
132 $this->getAndCheck($params, $contact['id'], 'Contact');
133 }
134
135 /**
136 * Test civicrm_contact_create with sub-types.
137 *
138 * Verify that sub-types are created successfully and not deleted by subsequent updates.
139 */
140 public function testIndividualSubType() {
141 $params = array(
142 'first_name' => 'test abc',
143 'contact_type' => 'Individual',
144 'last_name' => 'test xyz',
145 'contact_sub_type' => array('Student', 'Staff'),
146 );
147 $contact = $this->callAPISuccess('contact', 'create', $params);
148 $cid = $contact['id'];
149
150 $params = array(
151 'id' => $cid,
152 'middle_name' => 'foo',
153 );
154 $this->callAPISuccess('contact', 'create', $params);
155 unset($params['middle_name']);
156
157 $contact = $this->callAPISuccess('contact', 'get', $params);
158
159 $this->assertEquals(array('Student', 'Staff'), $contact['values'][$cid]['contact_sub_type']);
160 }
161
162 /**
163 * Verify that attempt to create contact with empty params fails.
164 */
165 public function testCreateEmptyContact() {
166 $this->callAPIFailure('contact', 'create', array());
167 }
168
169 /**
170 * Verify that attempt to create contact with bad contact type fails.
171 */
172 public function testCreateBadTypeContact() {
173 $params = array(
174 'email' => 'man1@yahoo.com',
175 'contact_type' => 'Does not Exist',
176 );
177 $this->callAPIFailure('contact', 'create', $params, "'Does not Exist' is not a valid option for field contact_type");
178 }
179
180 /**
181 * Verify that attempt to create individual contact without required fields fails.
182 */
183 public function testCreateBadRequiredFieldsIndividual() {
184 $params = array(
185 'middle_name' => 'This field is not required',
186 'contact_type' => 'Individual',
187 );
188 $this->callAPIFailure('contact', 'create', $params);
189 }
190
191 /**
192 * Verify that attempt to create household contact without required fields fails.
193 */
194 public function testCreateBadRequiredFieldsHousehold() {
195 $params = array(
196 'middle_name' => 'This field is not required',
197 'contact_type' => 'Household',
198 );
199 $this->callAPIFailure('contact', 'create', $params);
200 }
201
202 /**
203 * Test required field check.
204 *
205 * Verify that attempt to create organization contact without required fields fails.
206 */
207 public function testCreateBadRequiredFieldsOrganization() {
208 $params = array(
209 'middle_name' => 'This field is not required',
210 'contact_type' => 'Organization',
211 );
212
213 $this->callAPIFailure('contact', 'create', $params);
214 }
215
216 /**
217 * Verify that attempt to create individual contact with only an email succeeds.
218 */
219 public function testCreateEmailIndividual() {
220
221 $params = array(
222 'email' => 'man3@yahoo.com',
223 'contact_type' => 'Individual',
224 'location_type_id' => 1,
225 );
226
227 $contact = $this->callAPISuccess('contact', 'create', $params);
228
229 $this->assertEquals(3, $contact['id']);
230 $email = $this->callAPISuccess('email', 'get', array('contact_id' => $contact['id']));
231 $this->assertEquals(1, $email['count']);
232 $this->assertEquals('man3@yahoo.com', $email['values'][$email['id']]['email']);
233
234 $this->callAPISuccess('contact', 'delete', $contact);
235 }
236
237 /**
238 * Test creating individual by name.
239 *
240 * Verify create individual contact with only first and last names succeeds.
241 */
242 public function testCreateNameIndividual() {
243 $params = array(
244 'first_name' => 'abc1',
245 'contact_type' => 'Individual',
246 'last_name' => 'xyz1',
247 );
248
249 $this->callAPISuccess('contact', 'create', $params);
250 }
251
252 /**
253 * Test creating individual by display_name.
254 *
255 * Display name & sort name should be set.
256 */
257 public function testCreateDisplayNameIndividual() {
258 $params = array(
259 'display_name' => 'abc1',
260 'contact_type' => 'Individual',
261 );
262
263 $contact = $this->callAPISuccess('contact', 'create', $params);
264 $params['sort_name'] = 'abc1';
265 $this->getAndCheck($params, $contact['id'], 'contact');
266 }
267
268 /**
269 * Test old keys still work.
270 *
271 * Verify that attempt to create individual contact with
272 * first and last names and old key values works
273 */
274 public function testCreateNameIndividualOldKeys() {
275 $params = array(
276 'individual_prefix' => 'Dr.',
277 'first_name' => 'abc1',
278 'contact_type' => 'Individual',
279 'last_name' => 'xyz1',
280 'individual_suffix' => 'Jr.',
281 );
282
283 $contact = $this->callAPISuccess('contact', 'create', $params);
284 $result = $this->callAPISuccess('contact', 'getsingle', array('id' => $contact['id']));
285
286 $this->assertArrayKeyExists('prefix_id', $result);
287 $this->assertArrayKeyExists('suffix_id', $result);
288 $this->assertArrayKeyExists('gender_id', $result);
289 $this->assertEquals(4, $result['prefix_id']);
290 $this->assertEquals(1, $result['suffix_id']);
291 }
292
293 /**
294 * Test preferred keys work.
295 *
296 * Verify that attempt to create individual contact with
297 * first and last names and old key values works
298 */
299 public function testCreateNameIndividualRecommendedKeys2() {
300 $params = array(
301 'prefix_id' => 'Dr.',
302 'first_name' => 'abc1',
303 'contact_type' => 'Individual',
304 'last_name' => 'xyz1',
305 'suffix_id' => 'Jr.',
306 'gender_id' => 'Male',
307 );
308
309 $contact = $this->callAPISuccess('contact', 'create', $params);
310 $result = $this->callAPISuccess('contact', 'getsingle', array('id' => $contact['id']));
311
312 $this->assertArrayKeyExists('prefix_id', $result);
313 $this->assertArrayKeyExists('suffix_id', $result);
314 $this->assertArrayKeyExists('gender_id', $result);
315 $this->assertEquals(4, $result['prefix_id']);
316 $this->assertEquals(1, $result['suffix_id']);
317 }
318
319 /**
320 * Test household name is sufficient for create.
321 *
322 * Verify that attempt to create household contact with only
323 * household name succeeds
324 */
325 public function testCreateNameHousehold() {
326 $params = array(
327 'household_name' => 'The abc Household',
328 'contact_type' => 'Household',
329 );
330 $this->callAPISuccess('contact', 'create', $params);
331 }
332
333 /**
334 * Test organization name is sufficient for create.
335 *
336 * Verify that attempt to create organization contact with only
337 * organization name succeeds.
338 */
339 public function testCreateNameOrganization() {
340 $params = array(
341 'organization_name' => 'The abc Organization',
342 'contact_type' => 'Organization',
343 );
344 $this->callAPISuccess('contact', 'create', $params);
345 }
346
347 /**
348 * Verify that attempt to create organization contact without organization name fails.
349 */
350 public function testCreateNoNameOrganization() {
351 $params = array(
352 'first_name' => 'The abc Organization',
353 'contact_type' => 'Organization',
354 );
355 $this->callAPIFailure('contact', 'create', $params);
356 }
357
358 /**
359 * Check with complete array + custom field.
360 *
361 * Note that the test is written on purpose without any
362 * variables specific to participant so it can be replicated into other entities
363 * and / or moved to the automated test suite
364 */
365 public function testCreateWithCustom() {
366 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__, __FILE__);
367
368 $params = $this->_params;
369 $params['custom_' . $ids['custom_field_id']] = "custom string";
370 $description = "This demonstrates setting a custom field through the API.";
371 $result = $this->callAPIAndDocument($this->_entity, 'create', $params, __FUNCTION__, __FILE__, $description);
372
373 $check = $this->callAPISuccess($this->_entity, 'get', array(
374 'return.custom_' . $ids['custom_field_id'] => 1,
375 'id' => $result['id'],
376 ));
377 $this->assertEquals("custom string", $check['values'][$check['id']]['custom_' . $ids['custom_field_id']]);
378
379 $this->customFieldDelete($ids['custom_field_id']);
380 $this->customGroupDelete($ids['custom_group_id']);
381 }
382
383 /**
384 * CRM-12773 - expectation is that civicrm quietly ignores fields without values.
385 */
386 public function testCreateWithNULLCustomCRM12773() {
387 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__, __FILE__);
388 $params = $this->_params;
389 $params['custom_' . $ids['custom_field_id']] = NULL;
390 $this->callAPISuccess('contact', 'create', $params);
391 $this->customFieldDelete($ids['custom_field_id']);
392 $this->customGroupDelete($ids['custom_group_id']);
393 }
394
395 /**
396 * CRM-14232 test preferred language set to site default if not passed.
397 */
398 public function testCreatePreferredLanguageUnset() {
399 $this->callAPISuccess('Contact', 'create', array(
400 'first_name' => 'Snoop',
401 'last_name' => 'Dog',
402 'contact_type' => 'Individual')
403 );
404 $result = $this->callAPISuccessGetSingle('Contact', array('last_name' => 'Dog'));
405 $this->assertEquals('en_US', $result['preferred_language']);
406 }
407
408 /**
409 * CRM-14232 test preferred language returns setting if not passed.
410 */
411 public function testCreatePreferredLanguageSet() {
412 $this->callAPISuccess('Setting', 'create', array('contact_default_language' => 'fr_FR'));
413 $this->callAPISuccess('Contact', 'create', array(
414 'first_name' => 'Snoop',
415 'last_name' => 'Dog',
416 'contact_type' => 'Individual',
417 ));
418 $result = $this->callAPISuccessGetSingle('Contact', array('last_name' => 'Dog'));
419 $this->assertEquals('fr_FR', $result['preferred_language']);
420 }
421
422 /**
423 * CRM-14232 test preferred language returns setting if not passed where setting is NULL.
424 */
425 public function testCreatePreferredLanguageNull() {
426 $this->callAPISuccess('Setting', 'create', array('contact_default_language' => 'null'));
427 $this->callAPISuccess('Contact', 'create', array(
428 'first_name' => 'Snoop',
429 'last_name' => 'Dog',
430 'contact_type' => 'Individual',
431 )
432 );
433 $result = $this->callAPISuccessGetSingle('Contact', array('last_name' => 'Dog'));
434 $this->assertEquals(NULL, $result['preferred_language']);
435 }
436
437 /**
438 * CRM-14232 test preferred language returns setting if not passed where setting is NULL.
439 */
440 public function testCreatePreferredLanguagePassed() {
441 $this->callAPISuccess('Setting', 'create', array('contact_default_language' => 'null'));
442 $this->callAPISuccess('Contact', 'create', array(
443 'first_name' => 'Snoop',
444 'last_name' => 'Dog',
445 'contact_type' => 'Individual',
446 'preferred_language' => 'en_AU',
447 ));
448 $result = $this->callAPISuccessGetSingle('Contact', array('last_name' => 'Dog'));
449 $this->assertEquals('en_AU', $result['preferred_language']);
450 }
451
452 /**
453 * CRM-15792 - create/update datetime field for contact.
454 */
455 public function testCreateContactCustomFldDateTime() {
456 $customGroup = $this->customGroupCreate(array('extends' => 'Individual', 'title' => 'datetime_test_group'));
457 $dateTime = CRM_Utils_Date::currentDBDate();
458 //check date custom field is saved along with time when time_format is set
459 $params = array(
460 'first_name' => 'abc3',
461 'last_name' => 'xyz3',
462 'contact_type' => 'Individual',
463 'email' => 'man3@yahoo.com',
464 'api.CustomField.create' => array(
465 'custom_group_id' => $customGroup['id'],
466 'name' => 'test_datetime',
467 'label' => 'Demo Date',
468 'html_type' => 'Select Date',
469 'data_type' => 'Date',
470 'time_format' => 2,
471 'weight' => 4,
472 'is_required' => 1,
473 'is_searchable' => 0,
474 'is_active' => 1,
475 ),
476 );
477
478 $result = $this->callAPIAndDocument('Contact', 'create', $params, __FUNCTION__, __FILE__);
479 $customFldId = $result['values'][$result['id']]['api.CustomField.create']['id'];
480 $this->assertNotNull($result['id']);
481 $this->assertNotNull($customFldId);
482
483 $params = array(
484 'id' => $result['id'],
485 "custom_{$customFldId}" => $dateTime,
486 'api.CustomValue.get' => 1,
487 );
488
489 $result = $this->callAPIAndDocument('Contact', 'create', $params, __FUNCTION__, __FILE__);
490 $this->assertNotNull($result['id']);
491 $customFldDate = date("YmdHis", strtotime($result['values'][$result['id']]['api.CustomValue.get']['values'][0]['latest']));
492 $this->assertNotNull($customFldDate);
493 $this->assertEquals($dateTime, $customFldDate);
494 $customValueId = $result['values'][$result['id']]['api.CustomValue.get']['values'][0]['id'];
495 $dateTime = date('Ymd');
496 //date custom field should not contain time part when time_format is null
497 $params = array(
498 'id' => $result['id'],
499 'api.CustomField.create' => array(
500 'id' => $customFldId,
501 'html_type' => 'Select Date',
502 'data_type' => 'Date',
503 'time_format' => '',
504 ),
505 'api.CustomValue.create' => array(
506 'id' => $customValueId,
507 'entity_id' => $result['id'],
508 "custom_{$customFldId}" => $dateTime,
509 ),
510 'api.CustomValue.get' => 1,
511 );
512 $result = $this->callAPIAndDocument('Contact', 'create', $params, __FUNCTION__, __FILE__);
513 $this->assertNotNull($result['id']);
514 $customFldDate = date("Ymd", strtotime($result['values'][$result['id']]['api.CustomValue.get']['values'][0]['latest']));
515 $customFldTime = date("His", strtotime($result['values'][$result['id']]['api.CustomValue.get']['values'][0]['latest']));
516 $this->assertNotNull($customFldDate);
517 $this->assertEquals($dateTime, $customFldDate);
518 $this->assertEquals(000000, $customFldTime);
519 $this->callAPIAndDocument('Contact', 'create', $params, __FUNCTION__, __FILE__);
520 }
521
522
523 /**
524 * Test creating a current employer through API.
525 */
526 public function testContactCreateCurrentEmployer() {
527 // Here we will just do the get for set-up purposes.
528 $count = $this->callAPISuccess('contact', 'getcount', array(
529 'organization_name' => 'new employer org',
530 'contact_type' => 'Organization',
531 ));
532 $this->assertEquals(0, $count);
533 $employerResult = $this->callAPISuccess('contact', 'create', array_merge($this->_params, array(
534 'current_employer' => 'new employer org',
535 )
536 ));
537 // do it again as an update to check it doesn't cause an error
538 $employerResult = $this->callAPISuccess('contact', 'create', array_merge($this->_params, array(
539 'current_employer' => 'new employer org',
540 'id' => $employerResult['id'],
541 )
542 ));
543 $expectedCount = 1;
544 $this->callAPISuccess('contact', 'getcount', array(
545 'organization_name' => 'new employer org',
546 'contact_type' => 'Organization',
547 ),
548 $expectedCount);
549
550 $result = $this->callAPISuccess('contact', 'getsingle', array(
551 'id' => $employerResult['id'],
552 ));
553
554 $this->assertEquals('new employer org', $result['current_employer']);
555
556 }
557
558 /**
559 * Test creating a current employer through API.
560 *
561 * Check it will re-activate a de-activated employer
562 */
563 public function testContactCreateDuplicateCurrentEmployerEnables() {
564 // Set up - create employer relationship.
565 $employerResult = $this->callAPISuccess('contact', 'create', array_merge($this->_params, array(
566 'current_employer' => 'new employer org',
567 )
568 ));
569 $relationship = $this->callAPISuccess('relationship', 'get', array(
570 'contact_id_a' => $employerResult['id'],
571 ));
572
573 //disable & check it is disabled
574 $this->callAPISuccess('relationship', 'create', array('id' => $relationship['id'], 'is_active' => 0));
575 $this->callAPISuccess('relationship', 'getvalue', array(
576 'id' => $relationship['id'],
577 'return' => 'is_active',
578 ), 0);
579
580 // Re-set the current employer - thus enabling the relationship.
581 $this->callAPISuccess('contact', 'create', array_merge($this->_params, array(
582 'current_employer' => 'new employer org',
583 'id' => $employerResult['id'],
584 )
585 ));
586 //check is_active is now 1
587 $relationship = $this->callAPISuccess('relationship', 'getsingle', array(
588 'return' => 'is_active',
589 ));
590 $this->assertEquals(1, $relationship['is_active']);
591 }
592
593 /**
594 * Check deceased contacts are not retrieved.
595 *
596 * Note at time of writing the default is to return default. This should possibly be changed & test added.
597 */
598 public function testGetDeceasedRetrieved() {
599 $this->callAPISuccess($this->_entity, 'create', $this->_params);
600 $c2 = $this->callAPISuccess($this->_entity, 'create', array(
601 'first_name' => 'bb',
602 'last_name' => 'ccc',
603 'contact_type' => 'Individual',
604 'is_deceased' => 1,
605 ));
606 $result = $this->callAPISuccess($this->_entity, 'get', array('is_deceased' => 0));
607 $this->assertFalse(array_key_exists($c2['id'], $result['values']));
608 }
609
610 /**
611 * Test that sort works - old syntax.
612 */
613 public function testGetSort() {
614 $c1 = $this->callAPISuccess($this->_entity, 'create', $this->_params);
615 $c2 = $this->callAPISuccess($this->_entity, 'create', array(
616 'first_name' => 'bb',
617 'last_name' => 'ccc',
618 'contact_type' => 'Individual',
619 ));
620 $result = $this->callAPISuccess($this->_entity, 'get', array(
621 'sort' => 'first_name ASC',
622 'return.first_name' => 1,
623 'sequential' => 1,
624 'rowCount' => 1,
625 'contact_type' => 'Individual',
626 ));
627
628 $this->assertEquals('abc1', $result['values'][0]['first_name']);
629 $result = $this->callAPISuccess($this->_entity, 'get', array(
630 'sort' => 'first_name DESC',
631 'return.first_name' => 1,
632 'sequential' => 1,
633 'rowCount' => 1,
634 ));
635 $this->assertEquals('bb', $result['values'][0]['first_name']);
636
637 $this->callAPISuccess($this->_entity, 'delete', array('id' => $c1['id']));
638 $this->callAPISuccess($this->_entity, 'delete', array('id' => $c2['id']));
639 }
640
641 /**
642 * Test that we can retrieve contacts using array syntax.
643 *
644 * I.e 'id' => array('IN' => array('3,4')).
645 */
646 public function testGetINIDArray() {
647 $c1 = $this->callAPISuccess($this->_entity, 'create', $this->_params);
648 $c2 = $this->callAPISuccess($this->_entity, 'create', array(
649 'first_name' => 'bb',
650 'last_name' => 'ccc',
651 'contact_type' => 'Individual',
652 ));
653 $c3 = $this->callAPISuccess($this->_entity, 'create', array(
654 'first_name' => 'hh',
655 'last_name' => 'll',
656 'contact_type' => 'Individual',
657 ));
658 $result = $this->callAPISuccess($this->_entity, 'get', array('id' => array('IN' => array($c1['id'], $c3['id']))));
659 $this->assertEquals(2, $result['count']);
660 $this->assertEquals(array($c1['id'], $c3['id']), array_keys($result['values']));
661 $this->callAPISuccess($this->_entity, 'delete', array('id' => $c1['id']));
662 $this->callAPISuccess($this->_entity, 'delete', array('id' => $c2['id']));
663 $this->callAPISuccess($this->_entity, 'delete', array('id' => $c3['id']));
664 }
665
666 /**
667 * Test variants on deleted behaviour.
668 */
669 public function testGetDeleted() {
670 $params = $this->_params;
671 $contact1 = $this->callAPISuccess('contact', 'create', $params);
672 $params['is_deleted'] = 1;
673 $params['last_name'] = 'bcd';
674 $contact2 = $this->callAPISuccess('contact', 'create', $params);
675 $countActive = $this->callAPISuccess('contact', 'getcount', array(
676 'showAll' => 'active',
677 'contact_type' => 'Individual',
678 ));
679 $countAll = $this->callAPISuccess('contact', 'getcount', array('showAll' => 'all', 'contact_type' => 'Individual'));
680 $countTrash = $this->callAPISuccess('contact', 'getcount', array('showAll' => 'trash', 'contact_type' => 'Individual'));
681 $countDefault = $this->callAPISuccess('contact', 'getcount', array('contact_type' => 'Individual'));
682 $countDeleted = $this->callAPISuccess('contact', 'getcount', array(
683 'contact_type' => 'Individual',
684 'contact_is_deleted' => 1,
685 ));
686 $countNotDeleted = $this->callAPISuccess('contact', 'getcount', array(
687 'contact_is_deleted' => 0,
688 'contact_type' => 'Individual',
689 ));
690 $this->callAPISuccess('contact', 'delete', array('id' => $contact1['id']));
691 $this->callAPISuccess('contact', 'delete', array('id' => $contact2['id']));
692 $this->assertEquals(1, $countNotDeleted, 'contact_is_deleted => 0 is respected');
693 $this->assertEquals(1, $countActive);
694 $this->assertEquals(1, $countTrash);
695 $this->assertEquals(2, $countAll);
696 $this->assertEquals(1, $countDeleted);
697 $this->assertEquals(1, $countDefault, 'Only active by default in line');
698 }
699
700 /**
701 * Test that sort works - new syntax.
702 */
703 public function testGetSortNewSyntax() {
704 $c1 = $this->callAPISuccess($this->_entity, 'create', $this->_params);
705 $c2 = $this->callAPISuccess($this->_entity, 'create', array(
706 'first_name' => 'bb',
707 'last_name' => 'ccc',
708 'contact_type' => 'Individual',
709 ));
710 $result = $this->callAPISuccess($this->_entity, 'getvalue', array(
711 'return' => 'first_name',
712 'contact_type' => 'Individual',
713 'options' => array(
714 'limit' => 1,
715 'sort' => 'first_name',
716 ),
717 ));
718 $this->assertEquals('abc1', $result);
719
720 $result = $this->callAPISuccess($this->_entity, 'getvalue', array(
721 'return' => 'first_name',
722 'contact_type' => 'Individual',
723 'options' => array(
724 'limit' => 1,
725 'sort' => 'first_name DESC',
726 ),
727 ));
728 $this->assertEquals('bb', $result);
729
730 $this->callAPISuccess($this->_entity, 'delete', array('id' => $c1['id']));
731 $this->callAPISuccess($this->_entity, 'delete', array('id' => $c2['id']));
732 }
733
734 /**
735 * Test sort and limit for chained relationship get.
736 *
737 * https://issues.civicrm.org/jira/browse/CRM-15983
738 */
739 public function testSortLimitChainedRelationshipGetCRM15983() {
740 // Some contact
741 $create_result_1 = $this->callAPISuccess('contact', 'create', array(
742 'first_name' => 'Jules',
743 'last_name' => 'Smos',
744 'contact_type' => 'Individual',
745 ));
746
747 // Create another contact with two relationships.
748 $create_params = array(
749 'first_name' => 'Jos',
750 'last_name' => 'Smos',
751 'contact_type' => 'Individual',
752 'api.relationship.create' => array(
753 array(
754 'contact_id_a' => '$value.id',
755 'contact_id_b' => $create_result_1['id'],
756 // spouse of:
757 'relationship_type_id' => 2,
758 'start_date' => '2005-01-12',
759 'end_date' => '2006-01-11',
760 'description' => 'old',
761 ),
762 array(
763 'contact_id_a' => '$value.id',
764 'contact_id_b' => $create_result_1['id'],
765 // spouse of (was married twice :))
766 'relationship_type_id' => 2,
767 'start_date' => '2006-07-01',
768 'end_date' => '2010-07-01',
769 'description' => 'new',
770 ),
771 ),
772 );
773 $create_result = $this->callAPISuccess('contact', 'create', $create_params);
774
775 // Try to retrieve the contact and the most recent relationship.
776 $get_params = array(
777 'sequential' => 1,
778 'id' => $create_result['id'],
779 'api.relationship.get' => array(
780 'contact_id_a' => '$value.id',
781 'options' => array(
782 'limit' => '1',
783 'sort' => 'start_date DESC',
784 )),
785 );
786 $get_result = $this->callAPISuccess('contact', 'getsingle', $get_params);
787
788 // Clean up.
789 $this->callAPISuccess('contact', 'delete', array(
790 'id' => $create_result['id'],
791 ));
792
793 // Assert.
794 $this->assertEquals(1, $get_result['api.relationship.get']['count']);
795 $this->assertEquals('new', $get_result['api.relationship.get']['values'][0]['description']);
796 }
797
798 /**
799 * Test apostrophe works in get & create.
800 */
801 public function testGetApostropheCRM10857() {
802 $params = array_merge($this->_params, array('last_name' => "O'Connor"));
803 $this->callAPISuccess($this->_entity, 'create', $params);
804 $result = $this->callAPISuccess($this->_entity, 'getsingle', array(
805 'last_name' => "O'Connor",
806 'sequential' => 1,
807 ));
808 $this->assertEquals("O'Connor", $result['last_name'], 'in line' . __LINE__);
809 }
810
811 /**
812 * Check with complete array + custom field.
813 *
814 * Note that the test is written on purpose without any
815 * variables specific to participant so it can be replicated into other entities
816 * and / or moved to the automated test suite
817 */
818 public function testGetWithCustom() {
819 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__, __FILE__);
820
821 $params = $this->_params;
822 $params['custom_' . $ids['custom_field_id']] = "custom string";
823 $description = "This demonstrates setting a custom field through the API.";
824 $subfile = "CustomFieldGet";
825 $result = $this->callAPISuccess($this->_entity, 'create', $params);
826
827 $check = $this->callAPIAndDocument($this->_entity, 'get', array(
828 'return.custom_' . $ids['custom_field_id'] => 1,
829 'id' => $result['id'],
830 ), __FUNCTION__, __FILE__, $description, $subfile);
831
832 $this->assertEquals("custom string", $check['values'][$check['id']]['custom_' . $ids['custom_field_id']]);
833 $fields = ($this->callAPISuccess('contact', 'getfields', $params));
834 $this->assertTrue(is_array($fields['values']['custom_' . $ids['custom_field_id']]));
835 $this->customFieldDelete($ids['custom_field_id']);
836 $this->customGroupDelete($ids['custom_group_id']);
837 }
838
839 /**
840 * Check with complete array + custom field.
841 *
842 * Note that the test is written on purpose without any
843 * variables specific to participant so it can be replicated into other entities
844 * and / or moved to the automated test suite
845 */
846 public function testGetWithCustomReturnSyntax() {
847 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__, __FILE__);
848
849 $params = $this->_params;
850 $params['custom_' . $ids['custom_field_id']] = "custom string";
851 $description = "This demonstrates setting a custom field through the API.";
852 $subfile = "CustomFieldGetReturnSyntaxVariation";
853 $result = $this->callAPISuccess($this->_entity, 'create', $params);
854 $params = array('return' => 'custom_' . $ids['custom_field_id'], 'id' => $result['id']);
855 $check = $this->callAPIAndDocument($this->_entity, 'get', $params, __FUNCTION__, __FILE__, $description, $subfile);
856
857 $this->assertEquals("custom string", $check['values'][$check['id']]['custom_' . $ids['custom_field_id']]);
858 $this->customFieldDelete($ids['custom_field_id']);
859 $this->customGroupDelete($ids['custom_group_id']);
860 }
861
862 /**
863 * Check that address name is returned if required.
864 */
865 public function testGetReturnAddressName() {
866 $contactID = $this->individualCreate();
867 $this->callAPISuccess('address', 'create', array(
868 'contact_id' => $contactID,
869 'address_name' => 'My house',
870 'location_type_id' => 'Home',
871 'street_address' => '1 my road',
872 ));
873 $result = $this->callAPISuccessGetSingle('contact', array(
874 'return' => 'address_name, street_address',
875 'id' => $contactID,
876 ));
877 $this->assertEquals('1 my road', $result['street_address']);
878 $this->assertEquals('My house', $result['address_name']);
879
880 }
881
882 /**
883 * Test group filter syntaxes.
884 */
885 public function testGetGroupIDFromContact() {
886 $groupId = $this->groupCreate();
887 $description = "Get all from group and display contacts.";
888 $subFile = "GroupFilterUsingContactAPI";
889 $params = array(
890 'email' => 'man2@yahoo.com',
891 'contact_type' => 'Individual',
892 'location_type_id' => 1,
893 'api.group_contact.create' => array('group_id' => $groupId),
894 );
895
896 $this->callAPISuccess('contact', 'create', $params);
897 // testing as integer
898 $params = array(
899 'filter.group_id' => $groupId,
900 'contact_type' => 'Individual',
901 );
902 $result = $this->callAPIAndDocument('contact', 'get', $params, __FUNCTION__, __FILE__, $description, $subFile);
903 $this->assertEquals(1, $result['count']);
904 // group 26 doesn't exist, but we can still search contacts in it.
905 $params = array(
906 'filter.group_id' => 26,
907 'contact_type' => 'Individual',
908 );
909 $this->callAPISuccess('contact', 'get', $params);
910 // testing as string
911 $params = array(
912 'filter.group_id' => "$groupId, 26",
913 'contact_type' => 'Individual',
914 );
915 $result = $this->callAPIAndDocument('contact', 'get', $params, __FUNCTION__, __FILE__, $description, $subFile);
916 $this->assertEquals(1, $result['count']);
917 $params = array(
918 'filter.group_id' => "26,27",
919 'contact_type' => 'Individual',
920 );
921 $this->callAPISuccess('contact', 'get', $params);
922
923 // testing as string
924 $params = array(
925 'filter.group_id' => array($groupId, 26),
926 'contact_type' => 'Individual',
927 );
928 $result = $this->callAPIAndDocument('contact', 'get', $params, __FUNCTION__, __FILE__, $description, $subFile);
929 $this->assertEquals(1, $result['count']);
930
931 //test in conjunction with other criteria
932 $params = array(
933 'filter.group_id' => array($groupId, 26),
934 'contact_type' => 'Organization',
935 );
936 $this->callAPISuccess('contact', 'get', $params);
937 $params = array(
938 'filter.group_id' => array(26, 27),
939 'contact_type' => 'Individual',
940 );
941 $result = $this->callAPISuccess('contact', 'get', $params);
942 $this->assertEquals(0, $result['count']);
943 }
944
945 /**
946 * Verify that attempt to create individual contact with two chained websites succeeds.
947 */
948 public function testCreateIndividualWithContributionDottedSyntax() {
949 $description = "This demonstrates the syntax to create 2 chained entities.";
950 $subFile = "ChainTwoWebsites";
951 $params = array(
952 'first_name' => 'abc3',
953 'last_name' => 'xyz3',
954 'contact_type' => 'Individual',
955 'email' => 'man3@yahoo.com',
956 'api.contribution.create' => array(
957 'receive_date' => '2010-01-01',
958 'total_amount' => 100.00,
959 'financial_type_id' => $this->_financialTypeId,
960 'payment_instrument_id' => 1,
961 'non_deductible_amount' => 10.00,
962 'fee_amount' => 50.00,
963 'net_amount' => 90.00,
964 'trxn_id' => 15345,
965 'invoice_id' => 67990,
966 'source' => 'SSF',
967 'contribution_status_id' => 1,
968 ),
969 'api.website.create' => array(
970 'url' => "http://civicrm.org",
971 ),
972 'api.website.create.2' => array(
973 'url' => "http://chained.org",
974 ),
975 );
976
977 $result = $this->callAPIAndDocument('Contact', 'create', $params, __FUNCTION__, __FILE__, $description, $subFile);
978
979 // checking child function result not covered in callAPIAndDocument
980 $this->assertAPISuccess($result['values'][$result['id']]['api.website.create']);
981 $this->assertEquals("http://chained.org", $result['values'][$result['id']]['api.website.create.2']['values'][0]['url']);
982 $this->assertEquals("http://civicrm.org", $result['values'][$result['id']]['api.website.create']['values'][0]['url']);
983
984 // delete the contact
985 $this->callAPISuccess('contact', 'delete', $result);
986 }
987
988 /**
989 * Verify that attempt to create individual contact with chained contribution and website succeeds.
990 */
991 public function testCreateIndividualWithContributionChainedArrays() {
992 $params = array(
993 'first_name' => 'abc3',
994 'last_name' => 'xyz3',
995 'contact_type' => 'Individual',
996 'email' => 'man3@yahoo.com',
997 'api.contribution.create' => array(
998 'receive_date' => '2010-01-01',
999 'total_amount' => 100.00,
1000 'financial_type_id' => $this->_financialTypeId,
1001 'payment_instrument_id' => 1,
1002 'non_deductible_amount' => 10.00,
1003 'fee_amount' => 50.00,
1004 'net_amount' => 90.00,
1005 'trxn_id' => 12345,
1006 'invoice_id' => 67890,
1007 'source' => 'SSF',
1008 'contribution_status_id' => 1,
1009 ),
1010 'api.website.create' => array(
1011 array(
1012 'url' => "http://civicrm.org",
1013 ),
1014 array(
1015 'url' => "http://chained.org",
1016 'website_type_id' => 2,
1017 ),
1018 ),
1019 );
1020
1021 $description = "Demonstrates creating two websites as an array.";
1022 $subfile = "ChainTwoWebsitesSyntax2";
1023 $result = $this->callAPIAndDocument('Contact', 'create', $params, __FUNCTION__, __FILE__, $description, $subfile);
1024
1025 // the callAndDocument doesn't check the chained call
1026 $this->assertEquals(0, $result['values'][$result['id']]['api.website.create'][0]['is_error']);
1027 $this->assertEquals("http://chained.org", $result['values'][$result['id']]['api.website.create'][1]['values'][0]['url']);
1028 $this->assertEquals("http://civicrm.org", $result['values'][$result['id']]['api.website.create'][0]['values'][0]['url']);
1029
1030 $this->callAPISuccess('contact', 'delete', $result);
1031 }
1032
1033 /**
1034 * Test for direction when chaining relationships.
1035 *
1036 * https://issues.civicrm.org/jira/browse/CRM-16084
1037 */
1038 public function testDirectionChainingRelationshipsCRM16084() {
1039 // Some contact, called Jules.
1040 $create_result_1 = $this->callAPISuccess('contact', 'create', array(
1041 'first_name' => 'Jules',
1042 'last_name' => 'Smos',
1043 'contact_type' => 'Individual',
1044 ));
1045
1046 // Another contact: Jos, child of Jules.
1047 $create_params = array(
1048 'first_name' => 'Jos',
1049 'last_name' => 'Smos',
1050 'contact_type' => 'Individual',
1051 'api.relationship.create' => array(
1052 array(
1053 'contact_id_a' => '$value.id',
1054 'contact_id_b' => $create_result_1['id'],
1055 // child of
1056 'relationship_type_id' => 1,
1057 ),
1058 ),
1059 );
1060 $create_result_2 = $this->callAPISuccess('contact', 'create', $create_params);
1061
1062 // Mia is the child of Jos.
1063 $create_params = array(
1064 'first_name' => 'Mia',
1065 'last_name' => 'Smos',
1066 'contact_type' => 'Individual',
1067 'api.relationship.create' => array(
1068 array(
1069 'contact_id_a' => '$value.id',
1070 'contact_id_b' => $create_result_2['id'],
1071 // child of
1072 'relationship_type_id' => 1,
1073 ),
1074 ),
1075 );
1076 $create_result_3 = $this->callAPISuccess('contact', 'create', $create_params);
1077
1078 // Get Jos and his children.
1079 $get_params = array(
1080 'sequential' => 1,
1081 'id' => $create_result_2['id'],
1082 'api.relationship.get' => array(
1083 'contact_id_b' => '$value.id',
1084 'relationship_type_id' => 1,
1085 ),
1086 );
1087 $get_result = $this->callAPISuccess('contact', 'getsingle', $get_params);
1088
1089 // Clean up first.
1090 $this->callAPISuccess('contact', 'delete', array(
1091 'id' => $create_result_1['id'],
1092 ));
1093 $this->callAPISuccess('contact', 'delete', array(
1094 'id' => $create_result_2['id'],
1095 ));
1096 $this->callAPISuccess('contact', 'delete', array(
1097 'id' => $create_result_2['id'],
1098 ));
1099
1100 // Assert.
1101 $this->assertEquals(1, $get_result['api.relationship.get']['count']);
1102 $this->assertEquals($create_result_3['id'], $get_result['api.relationship.get']['values'][0]['contact_id_a']);
1103 }
1104
1105 /**
1106 * Verify that attempt to create individual contact with first, and last names and email succeeds.
1107 */
1108 public function testCreateIndividualWithNameEmail() {
1109 $params = array(
1110 'first_name' => 'abc3',
1111 'last_name' => 'xyz3',
1112 'contact_type' => 'Individual',
1113 'email' => 'man3@yahoo.com',
1114 );
1115
1116 $contact = $this->callAPISuccess('contact', 'create', $params);
1117
1118 $this->callAPISuccess('contact', 'delete', $contact);
1119 }
1120
1121 /**
1122 * Verify that attempt to create individual contact with no data fails.
1123 */
1124 public function testCreateIndividualWithOutNameEmail() {
1125 $params = array(
1126 'contact_type' => 'Individual',
1127 );
1128 $this->callAPIFailure('contact', 'create', $params);
1129 }
1130
1131 /**
1132 * Test create individual contact with first &last names, email and location type succeeds.
1133 */
1134 public function testCreateIndividualWithNameEmailLocationType() {
1135 $params = array(
1136 'first_name' => 'abc4',
1137 'last_name' => 'xyz4',
1138 'email' => 'man4@yahoo.com',
1139 'contact_type' => 'Individual',
1140 'location_type_id' => 1,
1141 );
1142 $result = $this->callAPISuccess('contact', 'create', $params);
1143
1144 $this->callAPISuccess('contact', 'delete', array('id' => $result['id']));
1145 }
1146
1147 /**
1148 * Verify that when changing employers the old employer relationship becomes inactive.
1149 */
1150 public function testCreateIndividualWithEmployer() {
1151 $employer = $this->organizationCreate();
1152 $employer2 = $this->organizationCreate();
1153
1154 $params = array(
1155 'email' => 'man4@yahoo.com',
1156 'contact_type' => 'Individual',
1157 'employer_id' => $employer,
1158 );
1159
1160 $result = $this->callAPISuccess('contact', 'create', $params);
1161 $relationships = $this->callAPISuccess('relationship', 'get', array(
1162 'contact_id_a' => $result['id'],
1163 'sequential' => 1,
1164 ));
1165
1166 $this->assertEquals($employer, $relationships['values'][0]['contact_id_b']);
1167
1168 // Add more random relationships to make the test more realistic
1169 foreach (array('Employee of', 'Volunteer for') as $relationshipType) {
1170 $relTypeId = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_RelationshipType', $relationshipType, 'id', 'name_a_b');
1171 $this->callAPISuccess('relationship', 'create', array(
1172 'contact_id_a' => $result['id'],
1173 'contact_id_b' => $this->organizationCreate(),
1174 'is_active' => 1,
1175 'relationship_type_id' => $relTypeId,
1176 ));
1177 }
1178
1179 // Add second employer
1180 $params['employer_id'] = $employer2;
1181 $params['id'] = $result['id'];
1182 $result = $this->callAPISuccess('contact', 'create', $params);
1183
1184 $relationships = $this->callAPISuccess('relationship', 'get', array(
1185 'contact_id_a' => $result['id'],
1186 'sequential' => 1,
1187 'is_active' => 0,
1188 ));
1189
1190 $this->assertEquals($employer, $relationships['values'][0]['contact_id_b']);
1191 }
1192
1193 /**
1194 * Verify that attempt to create household contact with details succeeds.
1195 */
1196 public function testCreateHouseholdDetails() {
1197 $params = array(
1198 'household_name' => 'abc8\'s House',
1199 'nick_name' => 'x House',
1200 'email' => 'man8@yahoo.com',
1201 'contact_type' => 'Household',
1202 );
1203
1204 $contact = $this->callAPISuccess('contact', 'create', $params);
1205
1206 $this->callAPISuccess('contact', 'delete', $contact);
1207 }
1208
1209 /**
1210 * Verify that attempt to create household contact with inadequate details fails.
1211 */
1212 public function testCreateHouseholdInadequateDetails() {
1213 $params = array(
1214 'nick_name' => 'x House',
1215 'email' => 'man8@yahoo.com',
1216 'contact_type' => 'Household',
1217 );
1218 $this->callAPIFailure('contact', 'create', $params);
1219 }
1220
1221 /**
1222 * Verify successful update of individual contact.
1223 */
1224 public function testUpdateIndividualWithAll() {
1225 // Insert a row in civicrm_contact creating individual contact.
1226 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1227 $op->execute($this->_dbconn,
1228 $this->createXMLDataSet(
1229 dirname(__FILE__) . '/dataset/contact_ind.xml'
1230 )
1231 );
1232
1233 $params = array(
1234 'id' => 23,
1235 'first_name' => 'abcd',
1236 'contact_type' => 'Individual',
1237 'nick_name' => 'This is nickname first',
1238 'do_not_email' => '1',
1239 'do_not_phone' => '1',
1240 'do_not_mail' => '1',
1241 'do_not_trade' => '1',
1242 'legal_identifier' => 'ABC23853ZZ2235',
1243 'external_identifier' => '1928837465',
1244 'image_URL' => 'http://some.url.com/image.jpg',
1245 'home_url' => 'http://www.example.org',
1246
1247 );
1248
1249 $this->callAPISuccess('Contact', 'Update', $params);
1250 $getResult = $this->callAPISuccess('Contact', 'Get', $params);
1251 unset($params['contact_id']);
1252 //Todo - neither API v2 or V3 are testing for home_url - not sure if it is being set.
1253 //reducing this test partially back to api v2 level to get it through
1254 unset($params['home_url']);
1255 foreach ($params as $key => $value) {
1256 $this->assertEquals($value, $getResult['values'][23][$key]);
1257 }
1258 // Check updated civicrm_contact against expected.
1259 $expected = $this->createXMLDataSet(
1260 dirname(__FILE__) . '/dataset/contact_ind_upd.xml'
1261 );
1262 $actual = new PHPUnit_Extensions_Database_DataSet_QueryDataSet(
1263 $this->_dbconn
1264 );
1265 $actual->addTable('civicrm_contact');
1266 $expected->matches($actual);
1267 }
1268
1269 /**
1270 * Verify successful update of organization contact.
1271 */
1272 public function testUpdateOrganizationWithAll() {
1273 // Insert a row in civicrm_contact creating organization contact
1274 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1275 $op->execute($this->_dbconn,
1276 $this->createXMLDataSet(
1277 dirname(__FILE__) . '/dataset/contact_org.xml'
1278 )
1279 );
1280
1281 $params = array(
1282 'id' => 24,
1283 'organization_name' => 'WebAccess India Pvt Ltd',
1284 'legal_name' => 'WebAccess',
1285 'sic_code' => 'ABC12DEF',
1286 'contact_type' => 'Organization',
1287 );
1288
1289 $this->callAPISuccess('Contact', 'Update', $params);
1290
1291 // Check updated civicrm_contact against expected.
1292 $expected = $this->createXMLDataSet(
1293 dirname(__FILE__) . '/dataset/contact_org_upd.xml'
1294 );
1295 $actual = new PHPUnit_Extensions_Database_DataSet_QueryDataSet(
1296 $this->_dbconn
1297 );
1298 $actual->addTable('civicrm_contact');
1299 $expected->matches($actual);
1300 }
1301
1302 /**
1303 * Verify successful update of household contact.
1304 */
1305 public function testUpdateHouseholdWithAll() {
1306 // Insert a row in civicrm_contact creating household contact
1307 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1308 $op->execute($this->_dbconn,
1309 $this->createXMLDataSet(
1310 dirname(__FILE__) . '/dataset/contact_hld.xml'
1311 )
1312 );
1313
1314 $params = array(
1315 'id' => 25,
1316 'household_name' => 'ABC household',
1317 'nick_name' => 'ABC House',
1318 'contact_type' => 'Household',
1319 );
1320
1321 $result = $this->callAPISuccess('Contact', 'Update', $params);
1322
1323 $expected = array(
1324 'contact_type' => 'Household',
1325 'is_opt_out' => 0,
1326 'sort_name' => 'ABC household',
1327 'display_name' => 'ABC household',
1328 'nick_name' => 'ABC House',
1329 );
1330 $this->getAndCheck($expected, $result['id'], 'contact');
1331 }
1332
1333 /**
1334 * Test civicrm_update() without contact type.
1335 *
1336 * Deliberately exclude contact_type as it should still cope using civicrm_api.
1337 *
1338 * CRM-7645.
1339 */
1340 public function testUpdateCreateWithID() {
1341 // Insert a row in civicrm_contact creating individual contact.
1342 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1343 $op->execute($this->_dbconn,
1344 $this->createXMLDataSet(
1345 dirname(__FILE__) . '/dataset/contact_ind.xml'
1346 )
1347 );
1348
1349 $params = array(
1350 'id' => 23,
1351 'first_name' => 'abcd',
1352 'last_name' => 'wxyz',
1353 );
1354 $this->callAPISuccess('Contact', 'Update', $params);
1355 }
1356
1357 /**
1358 * Test civicrm_contact_delete() with no contact ID.
1359 */
1360 public function testContactDeleteNoID() {
1361 $params = array(
1362 'foo' => 'bar',
1363 );
1364 $this->callAPIFailure('contact', 'delete', $params);
1365 }
1366
1367 /**
1368 * Test civicrm_contact_delete() with error.
1369 */
1370 public function testContactDeleteError() {
1371 $params = array('contact_id' => 999);
1372 $this->callAPIFailure('contact', 'delete', $params);
1373 }
1374
1375 /**
1376 * Test civicrm_contact_delete().
1377 */
1378 public function testContactDelete() {
1379 $contactID = $this->individualCreate();
1380 $params = array(
1381 'id' => $contactID,
1382 );
1383 $this->callAPIAndDocument('contact', 'delete', $params, __FUNCTION__, __FILE__);
1384 }
1385
1386 /**
1387 * Test civicrm_contact_get() return only first name.
1388 */
1389 public function testContactGetRetFirst() {
1390 $contact = $this->callAPISuccess('contact', 'create', $this->_params);
1391 $params = array(
1392 'contact_id' => $contact['id'],
1393 'return_first_name' => TRUE,
1394 'sort' => 'first_name',
1395 );
1396 $result = $this->callAPISuccess('contact', 'get', $params);
1397 $this->assertEquals(1, $result['count']);
1398 $this->assertEquals($contact['id'], $result['id']);
1399 $this->assertEquals('abc1', $result['values'][$contact['id']]['first_name']);
1400 }
1401
1402 /**
1403 * Test civicrm_contact_get() return only first name & last name.
1404 *
1405 * Use comma separated string return with a space.
1406 */
1407 public function testContactGetReturnFirstLast() {
1408 $contact = $this->callAPISuccess('contact', 'create', $this->_params);
1409 $params = array(
1410 'contact_id' => $contact['id'],
1411 'return' => 'first_name, last_name',
1412 );
1413 $result = $this->callAPISuccess('contact', 'getsingle', $params);
1414 $this->assertEquals('abc1', $result['first_name']);
1415 $this->assertEquals('xyz1', $result['last_name']);
1416 //check that other defaults not returns
1417 $this->assertArrayNotHasKey('sort_name', $result);
1418 $params = array(
1419 'contact_id' => $contact['id'],
1420 'return' => 'first_name,last_name',
1421 );
1422 $result = $this->callAPISuccess('contact', 'getsingle', $params);
1423 $this->assertEquals('abc1', $result['first_name']);
1424 $this->assertEquals('xyz1', $result['last_name']);
1425 //check that other defaults not returns
1426 $this->assertArrayNotHasKey('sort_name', $result);
1427 }
1428
1429 /**
1430 * Test civicrm_contact_get() return only first name & last name.
1431 *
1432 * Use comma separated string return without a space
1433 */
1434 public function testContactGetReturnFirstLastNoComma() {
1435 $contact = $this->callAPISuccess('contact', 'create', $this->_params);
1436 $params = array(
1437 'contact_id' => $contact['id'],
1438 'return' => 'first_name,last_name',
1439 );
1440 $result = $this->callAPISuccess('contact', 'getsingle', $params);
1441 $this->assertEquals('abc1', $result['first_name']);
1442 $this->assertEquals('xyz1', $result['last_name']);
1443 //check that other defaults not returns
1444 $this->assertArrayNotHasKey('sort_name', $result);
1445 }
1446
1447 /**
1448 * Test civicrm_contact_get() with default return properties.
1449 */
1450 public function testContactGetRetDefault() {
1451 $contactID = $this->individualCreate();
1452 $params = array(
1453 'contact_id' => $contactID,
1454 'sort' => 'first_name',
1455 );
1456 $result = $this->callAPISuccess('contact', 'get', $params);
1457 $this->assertEquals($contactID, $result['values'][$contactID]['contact_id']);
1458 $this->assertEquals('Anthony', $result['values'][$contactID]['first_name']);
1459 }
1460
1461 /**
1462 * Test civicrm_contact_getquick() with empty name param.
1463 */
1464 public function testContactGetQuick() {
1465 // Insert a row in civicrm_contact creating individual contact.
1466 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1467 $op->execute($this->_dbconn,
1468 $this->createXMLDataSet(
1469 dirname(__FILE__) . '/dataset/contact_17.xml'
1470 )
1471 );
1472 $op->execute($this->_dbconn,
1473 $this->createXMLDataSet(
1474 dirname(__FILE__) . '/dataset/email_contact_17.xml'
1475 )
1476 );
1477 $params = array(
1478 'name' => "T",
1479 );
1480
1481 $result = $this->callAPISuccess('contact', 'getquick', $params);
1482 $this->assertEquals(17, $result['values'][0]['id']);
1483 }
1484
1485 /**
1486 * Test civicrm_contact_get) with empty params.
1487 */
1488 public function testContactGetEmptyParams() {
1489 $this->callAPISuccess('contact', 'get', array());
1490 }
1491
1492 /**
1493 * Test civicrm_contact_get(,true) with no matches.
1494 */
1495 public function testContactGetOldParamsNoMatches() {
1496 // Insert a row in civicrm_contact creating contact 17.
1497 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1498 $op->execute($this->_dbconn,
1499 $this->createXMLDataSet(
1500 dirname(__FILE__) . '/dataset/contact_17.xml'
1501 )
1502 );
1503
1504 $params = array(
1505 'first_name' => 'Fred',
1506 );
1507 $result = $this->callAPISuccess('contact', 'get', $params);
1508 $this->assertEquals(0, $result['count']);
1509 }
1510
1511 /**
1512 * Test civicrm_contact_get(,true) with one match.
1513 */
1514 public function testContactGetOldParamsOneMatch() {
1515 // Insert a row in civicrm_contact creating contact 17
1516 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1517 $op->execute($this->_dbconn,
1518 $this->createXMLDataSet(dirname(__FILE__) . '/dataset/contact_17.xml'
1519 )
1520 );
1521
1522 $params = array(
1523 'first_name' => 'Test',
1524 );
1525 $result = $this->callAPISuccess('contact', 'get', $params);
1526 $this->assertEquals(17, $result['values'][17]['contact_id']);
1527 $this->assertEquals(17, $result['id']);
1528 }
1529
1530 /**
1531 * Test civicrm_contact_search_count().
1532 */
1533 public function testContactGetEmail() {
1534 $params = array(
1535 'email' => 'man2@yahoo.com',
1536 'contact_type' => 'Individual',
1537 'location_type_id' => 1,
1538 );
1539
1540 $contact = $this->callAPISuccess('contact', 'create', $params);
1541
1542 $params = array(
1543 'email' => 'man2@yahoo.com',
1544 );
1545 $result = $this->callAPIAndDocument('contact', 'get', $params, __FUNCTION__, __FILE__);
1546 $this->assertEquals('man2@yahoo.com', $result['values'][$result['id']]['email']);
1547
1548 $this->callAPISuccess('contact', 'delete', $contact);
1549 }
1550
1551 /**
1552 * Test birth date parameters.
1553 *
1554 * These include value, array & birth_date_high, birth_date_low
1555 * && deceased.
1556 */
1557 public function testContactGetBirthDate() {
1558 $contact1 = $this->callAPISuccess('contact', 'create', array_merge($this->_params, array('birth_date' => 'first day of next month - 2 years')));
1559 $contact2 = $this->callAPISuccess('contact', 'create', array_merge($this->_params, array('birth_date' => 'first day of next month - 5 years')));
1560 $contact3 = $this->callAPISuccess('contact', 'create', array_merge($this->_params, array('birth_date' => 'first day of next month -20 years')));
1561
1562 $result = $this->callAPISuccess('contact', 'get', array());
1563 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -2 years')), $result['values'][$contact1['id']]['birth_date']);
1564 $result = $this->callAPISuccess('contact', 'get', array('birth_date' => 'first day of next month -5 years'));
1565 $this->assertEquals(1, $result['count']);
1566 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -5 years')), $result['values'][$contact2['id']]['birth_date']);
1567 $result = $this->callAPISuccess('contact', 'get', array('birth_date_high' => date('Y-m-d', strtotime('-6 years'))));
1568 $this->assertEquals(1, $result['count']);
1569 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -20 years')), $result['values'][$contact3['id']]['birth_date']);
1570 $result = $this->callAPISuccess('contact', 'get', array(
1571 'birth_date_low' => date('Y-m-d', strtotime('-6 years')),
1572 'birth_date_high' => date('Y-m-d', strtotime('- 3 years')),
1573 ));
1574 $this->assertEquals(1, $result['count']);
1575 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -5 years')), $result['values'][$contact2['id']]['birth_date']);
1576 $result = $this->callAPISuccess('contact', 'get', array(
1577 'birth_date_low' => '-6 years',
1578 'birth_date_high' => '- 3 years',
1579 ));
1580 $this->assertEquals(1, $result['count']);
1581 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -5 years')), $result['values'][$contact2['id']]['birth_date']);
1582 }
1583
1584 /**
1585 * Test Address parameters
1586 *
1587 * This include state_province, state_province_name, country
1588 */
1589 public function testContactGetWithAddressFields() {
1590 $individuals = array(
1591 array(
1592 'first_name' => 'abc1',
1593 'contact_type' => 'Individual',
1594 'last_name' => 'xyz1',
1595 'api.address.create' => array(
1596 'country' => 'United States',
1597 'state_province_id' => 'Michigan',
1598 'location_type_id' => 1,
1599 ),
1600 ),
1601 array(
1602 'first_name' => 'abc2',
1603 'contact_type' => 'Individual',
1604 'last_name' => 'xyz2',
1605 'api.address.create' => array(
1606 'country' => 'United States',
1607 'state_province_id' => 'Alabama',
1608 'location_type_id' => 1,
1609 ),
1610 ),
1611 );
1612 foreach ($individuals as $params) {
1613 $contact = $this->callAPISuccess('contact', 'create', $params);
1614 }
1615
1616 // Check whether Contact get API return successfully with below Address params.
1617 $fieldsToTest = array(
1618 'state_province_name' => 'Michigan',
1619 'state_province' => 'Michigan',
1620 'country' => 'United States',
1621 'state_province_name' => array('IN' => array('Michigan', 'Alabama')),
1622 'state_province' => array('IN' => array('Michigan', 'Alabama')),
1623 );
1624 foreach ($fieldsToTest as $field => $value) {
1625 $getParams = array(
1626 'id' => $contact['id'],
1627 $field => $value,
1628 );
1629 $result = $this->callAPISuccess('Contact', 'get', $getParams);
1630 $this->assertEquals(1, $result['count']);
1631 }
1632 }
1633
1634 /**
1635 * Test Deceased date parameters.
1636 *
1637 * These include value, array & Deceased_date_high, Deceased date_low
1638 * && deceased.
1639 */
1640 public function testContactGetDeceasedDate() {
1641 $contact1 = $this->callAPISuccess('contact', 'create', array_merge($this->_params, array('deceased_date' => 'first day of next month - 2 years')));
1642 $contact2 = $this->callAPISuccess('contact', 'create', array_merge($this->_params, array('deceased_date' => 'first day of next month - 5 years')));
1643 $contact3 = $this->callAPISuccess('contact', 'create', array_merge($this->_params, array('deceased_date' => 'first day of next month -20 years')));
1644
1645 $result = $this->callAPISuccess('contact', 'get', array());
1646 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -2 years')), $result['values'][$contact1['id']]['deceased_date']);
1647 $result = $this->callAPISuccess('contact', 'get', array('deceased_date' => 'first day of next month -5 years'));
1648 $this->assertEquals(1, $result['count']);
1649 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -5 years')), $result['values'][$contact2['id']]['deceased_date']);
1650 $result = $this->callAPISuccess('contact', 'get', array('deceased_date_high' => date('Y-m-d', strtotime('-6 years'))));
1651 $this->assertEquals(1, $result['count']);
1652 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -20 years')), $result['values'][$contact3['id']]['deceased_date']);
1653 $result = $this->callAPISuccess('contact', 'get', array(
1654 'deceased_date_low' => '-6 years',
1655 'deceased_date_high' => date('Y-m-d', strtotime('- 3 years')),
1656 ));
1657 $this->assertEquals(1, $result['count']);
1658 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -5 years')), $result['values'][$contact2['id']]['deceased_date']);
1659 }
1660
1661 /**
1662 * Test for Contact.get id=@user:username.
1663 */
1664 public function testContactGetByUsername() {
1665 // Setup - create contact with a uf-match.
1666 $cid = $this->individualCreate(array(
1667 'contact_type' => 'Individual',
1668 'first_name' => 'testGetByUsername',
1669 'last_name' => 'testGetByUsername',
1670 ));
1671
1672 $ufMatchParams = array(
1673 'domain_id' => CRM_Core_Config::domainID(),
1674 'uf_id' => 99,
1675 'uf_name' => 'the-email-matching-key-is-not-really-the-username',
1676 'contact_id' => $cid,
1677 );
1678 $ufMatch = CRM_Core_BAO_UFMatch::create($ufMatchParams);
1679 $this->assertTrue(is_numeric($ufMatch->id));
1680
1681 // setup - mock the calls to CRM_Utils_System_*::getUfId
1682 $userSystem = $this->getMock('CRM_Utils_System_UnitTests', array('getUfId'));
1683 $userSystem->expects($this->once())
1684 ->method('getUfId')
1685 ->with($this->equalTo('exampleUser'))
1686 ->will($this->returnValue(99));
1687 CRM_Core_Config::singleton()->userSystem = $userSystem;
1688
1689 // perform a lookup
1690 $result = $this->callAPISuccess('Contact', 'get', array(
1691 'id' => '@user:exampleUser',
1692 ));
1693 $this->assertEquals('testGetByUsername', $result['values'][$cid]['first_name']);
1694 }
1695
1696 /**
1697 * Test to check return works OK.
1698 */
1699 public function testContactGetReturnValues() {
1700 $extraParams = array(
1701 'nick_name' => 'Bob',
1702 'phone' => '456',
1703 'email' => 'e@mail.com',
1704 );
1705 $contactID = $this->individualCreate($extraParams);
1706 //actually it turns out the above doesn't create a phone
1707 $this->callAPISuccess('phone', 'create', array('contact_id' => $contactID, 'phone' => '456'));
1708 $result = $this->callAPISuccess('contact', 'getsingle', array('id' => $contactID));
1709 foreach ($extraParams as $key => $value) {
1710 $this->assertEquals($result[$key], $value);
1711 }
1712 //now we check they are still returned with 'return' key
1713 $result = $this->callAPISuccess('contact', 'getsingle', array(
1714 'id' => $contactID,
1715 'return' => array_keys($extraParams),
1716 ));
1717 foreach ($extraParams as $key => $value) {
1718 $this->assertEquals($result[$key], $value);
1719 }
1720 }
1721
1722 /**
1723 * Test creating multiple phones using chaining.
1724 *
1725 * @throws \Exception
1726 */
1727 public function testCRM13252MultipleChainedPhones() {
1728 $contactID = $this->householdCreate();
1729 $this->callAPISuccessGetCount('phone', array('contact_id' => $contactID), 0);
1730 $params = array(
1731 'contact_id' => $contactID,
1732 'household_name' => 'Household 1',
1733 'contact_type' => 'Household',
1734 'api.phone.create' => array(
1735 0 => array(
1736 'phone' => '111-111-1111',
1737 'location_type_id' => 1,
1738 'phone_type_id' => 1,
1739 ),
1740 1 => array(
1741 'phone' => '222-222-2222',
1742 'location_type_id' => 1,
1743 'phone_type_id' => 2,
1744 ),
1745 ),
1746 );
1747 $this->callAPISuccess('contact', 'create', $params);
1748 $this->callAPISuccessGetCount('phone', array('contact_id' => $contactID), 2);
1749
1750 }
1751
1752 /**
1753 * Test for Contact.get id=@user:username (with an invalid username).
1754 */
1755 public function testContactGetByUnknownUsername() {
1756 // setup - mock the calls to CRM_Utils_System_*::getUfId
1757 $userSystem = $this->getMock('CRM_Utils_System_UnitTests', array('getUfId'));
1758 $userSystem->expects($this->once())
1759 ->method('getUfId')
1760 ->with($this->equalTo('exampleUser'))
1761 ->will($this->returnValue(NULL));
1762 CRM_Core_Config::singleton()->userSystem = $userSystem;
1763
1764 // perform a lookup
1765 $result = $this->callAPIFailure('Contact', 'get', array(
1766 'id' => '@user:exampleUser',
1767 ));
1768 $this->assertRegExp('/cannot be resolved to a contact ID/', $result['error_message']);
1769 }
1770
1771 /**
1772 * Verify attempt to create individual with chained arrays and sequential.
1773 */
1774 public function testGetIndividualWithChainedArraysAndSequential() {
1775 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__, __FILE__);
1776 $params['custom_' . $ids['custom_field_id']] = "custom string";
1777
1778 $moreIDs = $this->CustomGroupMultipleCreateWithFields();
1779 $params = array(
1780 'sequential' => 1,
1781 'first_name' => 'abc3',
1782 'last_name' => 'xyz3',
1783 'contact_type' => 'Individual',
1784 'email' => 'man3@yahoo.com',
1785 'api.website.create' => array(
1786 array(
1787 'url' => "http://civicrm.org",
1788 ),
1789 array(
1790 'url' => "https://civicrm.org",
1791 ),
1792 ),
1793 );
1794
1795 $result = $this->callAPISuccess('Contact', 'create', $params);
1796
1797 // delete the contact and custom groups
1798 $this->callAPISuccess('contact', 'delete', array('id' => $result['id']));
1799 $this->customGroupDelete($ids['custom_group_id']);
1800 $this->customGroupDelete($moreIDs['custom_group_id']);
1801
1802 $this->assertEquals($result['id'], $result['values'][0]['id']);
1803 $this->assertArrayKeyExists('api.website.create', $result['values'][0]);
1804 }
1805
1806 /**
1807 * Verify attempt to create individual with chained arrays.
1808 */
1809 public function testGetIndividualWithChainedArrays() {
1810 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__, __FILE__);
1811 $params['custom_' . $ids['custom_field_id']] = "custom string";
1812
1813 $moreIDs = $this->CustomGroupMultipleCreateWithFields();
1814 $description = "This demonstrates the usage of chained api functions.\nIn this case no notes or custom fields have been created.";
1815 $subfile = "APIChainedArray";
1816 $params = array(
1817 'first_name' => 'abc3',
1818 'last_name' => 'xyz3',
1819 'contact_type' => 'Individual',
1820 'email' => 'man3@yahoo.com',
1821 'api.contribution.create' => array(
1822 'receive_date' => '2010-01-01',
1823 'total_amount' => 100.00,
1824 'financial_type_id' => 1,
1825 'payment_instrument_id' => 1,
1826 'non_deductible_amount' => 10.00,
1827 'fee_amount' => 50.00,
1828 'net_amount' => 90.00,
1829 'trxn_id' => 12345,
1830 'invoice_id' => 67890,
1831 'source' => 'SSF',
1832 'contribution_status_id' => 1,
1833 ),
1834 'api.contribution.create.1' => array(
1835 'receive_date' => '2011-01-01',
1836 'total_amount' => 120.00,
1837 'financial_type_id' => $this->_financialTypeId = 1,
1838 'payment_instrument_id' => 1,
1839 'non_deductible_amount' => 10.00,
1840 'fee_amount' => 50.00,
1841 'net_amount' => 90.00,
1842 'trxn_id' => 12335,
1843 'invoice_id' => 67830,
1844 'source' => 'SSF',
1845 'contribution_status_id' => 1,
1846 ),
1847 'api.website.create' => array(
1848 array(
1849 'url' => "http://civicrm.org",
1850 ),
1851 ),
1852 );
1853
1854 $result = $this->callAPISuccess('Contact', 'create', $params);
1855 $params = array(
1856 'id' => $result['id'],
1857 'api.website.get' => array(),
1858 'api.Contribution.get' => array(
1859 'total_amount' => '120.00',
1860 ),
1861 'api.CustomValue.get' => 1,
1862 'api.Note.get' => 1,
1863 );
1864 $result = $this->callAPIAndDocument('Contact', 'Get', $params, __FUNCTION__, __FILE__, $description, $subfile);
1865 // delete the contact
1866 $this->callAPISuccess('contact', 'delete', $result);
1867 $this->customGroupDelete($ids['custom_group_id']);
1868 $this->customGroupDelete($moreIDs['custom_group_id']);
1869 $this->assertEquals(0, $result['values'][$result['id']]['api.website.get']['is_error']);
1870 $this->assertEquals("http://civicrm.org", $result['values'][$result['id']]['api.website.get']['values'][0]['url']);
1871 }
1872
1873 /**
1874 * Verify attempt to create individual with chained arrays and sequential.
1875 *
1876 * See https://issues.civicrm.org/jira/browse/CRM-15815
1877 */
1878 public function testCreateIndividualWithChainedArrayAndSequential() {
1879 $params = array(
1880 'sequential' => 1,
1881 'first_name' => 'abc5',
1882 'last_name' => 'xyz5',
1883 'contact_type' => 'Individual',
1884 'email' => 'woman5@yahoo.com',
1885 'api.phone.create' => array(
1886 array('phone' => '03-231 07 95'),
1887 array('phone' => '03-232 51 62'),
1888 ),
1889 'api.website.create' => array(
1890 'url' => 'http://civicrm.org',
1891 ),
1892 );
1893 $result = $this->callAPISuccess('Contact', 'create', $params);
1894
1895 // I could try to parse the result to see whether the two phone numbers
1896 // and the website are there, but I am not sure about the correct format.
1897 // So I will just fetch it again before checking.
1898 // See also http://forum.civicrm.org/index.php/topic,35393.0.html
1899 $params = array(
1900 'sequential' => 1,
1901 'id' => $result['id'],
1902 'api.website.get' => array(),
1903 'api.phone.get' => array(),
1904 );
1905 $result = $this->callAPISuccess('Contact', 'get', $params);
1906
1907 // delete the contact
1908 $this->callAPISuccess('contact', 'delete', $result);
1909
1910 $this->assertEquals(2, $result['values'][0]['api.phone.get']['count']);
1911 $this->assertEquals(1, $result['values'][0]['api.website.get']['count']);
1912 }
1913
1914 /**
1915 * Test retrieving an individual with chained array syntax.
1916 */
1917 public function testGetIndividualWithChainedArraysFormats() {
1918 $description = "This demonstrates the usage of chained api functions.\nIn this case no notes or custom fields have been created.";
1919 $subfile = "APIChainedArrayFormats";
1920 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__, __FILE__);
1921 $params['custom_' . $ids['custom_field_id']] = "custom string";
1922
1923 $moreIDs = $this->CustomGroupMultipleCreateWithFields();
1924 $params = array(
1925 'first_name' => 'abc3',
1926 'last_name' => 'xyz3',
1927 'contact_type' => 'Individual',
1928 'email' => 'man3@yahoo.com',
1929 'api.contribution.create' => array(
1930 'receive_date' => '2010-01-01',
1931 'total_amount' => 100.00,
1932 'financial_type_id' => $this->_financialTypeId,
1933 'payment_instrument_id' => 1,
1934 'non_deductible_amount' => 10.00,
1935 'fee_amount' => 50.00,
1936 'net_amount' => 90.00,
1937 'source' => 'SSF',
1938 'contribution_status_id' => 1,
1939 ),
1940 'api.contribution.create.1' => array(
1941 'receive_date' => '2011-01-01',
1942 'total_amount' => 120.00,
1943 'financial_type_id' => $this->_financialTypeId,
1944 'payment_instrument_id' => 1,
1945 'non_deductible_amount' => 10.00,
1946 'fee_amount' => 50.00,
1947 'net_amount' => 90.00,
1948 'source' => 'SSF',
1949 'contribution_status_id' => 1,
1950 ),
1951 'api.website.create' => array(
1952 array(
1953 'url' => "http://civicrm.org",
1954 ),
1955 ),
1956 );
1957
1958 $result = $this->callAPISuccess('Contact', 'create', $params);
1959 $params = array(
1960 'id' => $result['id'],
1961 'api.website.getValue' => array('return' => 'url'),
1962 'api.Contribution.getCount' => array(),
1963 'api.CustomValue.get' => 1,
1964 'api.Note.get' => 1,
1965 'api.Membership.getCount' => array(),
1966 );
1967 $result = $this->callAPIAndDocument('Contact', 'Get', $params, __FUNCTION__, __FILE__, $description, $subfile);
1968 $this->assertEquals(2, $result['values'][$result['id']]['api.Contribution.getCount']);
1969 $this->assertEquals(0, $result['values'][$result['id']]['api.Note.get']['is_error']);
1970 $this->assertEquals("http://civicrm.org", $result['values'][$result['id']]['api.website.getValue']);
1971
1972 $this->callAPISuccess('contact', 'delete', $result);
1973 $this->customGroupDelete($ids['custom_group_id']);
1974 $this->customGroupDelete($moreIDs['custom_group_id']);
1975 }
1976
1977 /**
1978 * Test complex chaining.
1979 */
1980 public function testGetIndividualWithChainedArraysAndMultipleCustom() {
1981 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__, __FILE__);
1982 $params['custom_' . $ids['custom_field_id']] = "custom string";
1983 $moreIDs = $this->CustomGroupMultipleCreateWithFields();
1984 $andMoreIDs = $this->CustomGroupMultipleCreateWithFields(array(
1985 'title' => "another group",
1986 'name' => 'another name',
1987 ));
1988 $description = "This demonstrates the usage of chained api functions with multiple custom fields.";
1989 $subfile = "APIChainedArrayMultipleCustom";
1990 $params = array(
1991 'first_name' => 'abc3',
1992 'last_name' => 'xyz3',
1993 'contact_type' => 'Individual',
1994 'email' => 'man3@yahoo.com',
1995 'api.contribution.create' => array(
1996 'receive_date' => '2010-01-01',
1997 'total_amount' => 100.00,
1998 'financial_type_id' => 1,
1999 'payment_instrument_id' => 1,
2000 'non_deductible_amount' => 10.00,
2001 'fee_amount' => 50.00,
2002 'net_amount' => 90.00,
2003 'trxn_id' => 12345,
2004 'invoice_id' => 67890,
2005 'source' => 'SSF',
2006 'contribution_status_id' => 1,
2007 ),
2008 'api.contribution.create.1' => array(
2009 'receive_date' => '2011-01-01',
2010 'total_amount' => 120.00,
2011 'financial_type_id' => 1,
2012 'payment_instrument_id' => 1,
2013 'non_deductible_amount' => 10.00,
2014 'fee_amount' => 50.00,
2015 'net_amount' => 90.00,
2016 'trxn_id' => 12335,
2017 'invoice_id' => 67830,
2018 'source' => 'SSF',
2019 'contribution_status_id' => 1,
2020 ),
2021 'api.website.create' => array(
2022 array(
2023 'url' => "http://civicrm.org",
2024 ),
2025 ),
2026 'custom_' . $ids['custom_field_id'] => "value 1",
2027 'custom_' . $moreIDs['custom_field_id'][0] => "value 2",
2028 'custom_' . $moreIDs['custom_field_id'][1] => "warm beer",
2029 'custom_' . $andMoreIDs['custom_field_id'][1] => "vegemite",
2030 );
2031
2032 $result = $this->callAPISuccess('Contact', 'create', $params);
2033 $result = $this->callAPISuccess('Contact', 'create', array(
2034 'contact_type' => 'Individual',
2035 'id' => $result['id'],
2036 'custom_' .
2037 $moreIDs['custom_field_id'][0] => "value 3",
2038 'custom_' .
2039 $ids['custom_field_id'] => "value 4",
2040 ));
2041
2042 $params = array(
2043 'id' => $result['id'],
2044 'api.website.getValue' => array('return' => 'url'),
2045 'api.Contribution.getCount' => array(),
2046 'api.CustomValue.get' => 1,
2047 );
2048 $result = $this->callAPIAndDocument('Contact', 'Get', $params, __FUNCTION__, __FILE__, $description, $subfile);
2049
2050 $this->customGroupDelete($ids['custom_group_id']);
2051 $this->customGroupDelete($moreIDs['custom_group_id']);
2052 $this->customGroupDelete($andMoreIDs['custom_group_id']);
2053 $this->assertEquals(0, $result['values'][$result['id']]['api.CustomValue.get']['is_error']);
2054 $this->assertEquals('http://civicrm.org', $result['values'][$result['id']]['api.website.getValue']);
2055 }
2056
2057 /**
2058 * Test checks usage of $values to pick & choose inputs.
2059 */
2060 public function testChainingValuesCreate() {
2061 $description = "This demonstrates the usage of chained api functions. Specifically it has one 'parent function' &
2062 2 child functions - one receives values from the parent (Contact) and the other child (Tag).";
2063 $subfile = "APIChainedArrayValuesFromSiblingFunction";
2064 $params = array(
2065 'display_name' => 'batman',
2066 'contact_type' => 'Individual',
2067 'api.tag.create' => array(
2068 'name' => '$value.id',
2069 'description' => '$value.display_name',
2070 'format.only_id' => 1,
2071 ),
2072 'api.entity_tag.create' => array('tag_id' => '$value.api.tag.create'),
2073 );
2074 $result = $this->callAPIAndDocument('Contact', 'Create', $params, __FUNCTION__, __FILE__, $description, $subfile);
2075 $this->assertEquals(0, $result['values'][$result['id']]['api.entity_tag.create']['is_error']);
2076
2077 $tablesToTruncate = array(
2078 'civicrm_contact',
2079 'civicrm_activity',
2080 'civicrm_entity_tag',
2081 'civicrm_tag',
2082 );
2083 $this->quickCleanup($tablesToTruncate, TRUE);
2084 }
2085
2086 /**
2087 * Test TrueFalse format - I couldn't come up with an easy way to get an error on Get.
2088 */
2089 public function testContactGetFormatIsSuccessTrue() {
2090 $this->createContactFromXML();
2091 $description = "This demonstrates use of the 'format.is_success' param.
2092 This param causes only the success or otherwise of the function to be returned as BOOLEAN";
2093 $subfile = "FormatIsSuccess_True";
2094 $params = array('id' => 17, 'format.is_success' => 1);
2095 $result = $this->callAPIAndDocument('Contact', 'Get', $params, __FUNCTION__, __FILE__, $description, $subfile);
2096 $this->assertEquals(1, $result);
2097 $this->callAPISuccess('Contact', 'Delete', $params);
2098 }
2099
2100 /**
2101 * Test TrueFalse format.
2102 */
2103 public function testContactCreateFormatIsSuccessFalse() {
2104
2105 $description = "This demonstrates use of the 'format.is_success' param.
2106 This param causes only the success or otherwise of the function to be returned as BOOLEAN";
2107 $subfile = "FormatIsSuccess_Fail";
2108 $params = array('id' => 500, 'format.is_success' => 1);
2109 $result = $this->callAPIAndDocument('Contact', 'Create', $params, __FUNCTION__, __FILE__, $description, $subfile);
2110 $this->assertEquals(0, $result);
2111 }
2112
2113 /**
2114 * Test Single Entity format.
2115 */
2116 public function testContactGetSingleEntityArray() {
2117 $this->createContactFromXML();
2118 $description = "This demonstrates use of the 'format.single_entity_array' param.
2119 This param causes the only contact to be returned as an array without the other levels.
2120 It will be ignored if there is not exactly 1 result";
2121 $subfile = "GetSingleContact";
2122 $params = array('id' => 17);
2123 $result = $this->callAPIAndDocument('Contact', 'GetSingle', $params, __FUNCTION__, __FILE__, $description, $subfile);
2124 $this->assertEquals('Test Contact', $result['display_name']);
2125 $this->callAPISuccess('Contact', 'Delete', $params);
2126 }
2127
2128 /**
2129 * Test Single Entity format.
2130 */
2131 public function testContactGetFormatCountOnly() {
2132 $this->createContactFromXML();
2133 $description = "This demonstrates use of the 'getCount' action.
2134 This param causes the count of the only function to be returned as an integer.";
2135 $params = array('id' => 17);
2136 $result = $this->callAPIAndDocument('Contact', 'GetCount', $params, __FUNCTION__, __FILE__, $description,
2137 'GetCountContact');
2138 $this->assertEquals('1', $result);
2139 $this->callAPISuccess('Contact', 'Delete', $params);
2140 }
2141
2142 /**
2143 * Test id only format.
2144 */
2145 public function testContactGetFormatIDOnly() {
2146 $this->createContactFromXML();
2147 $description = "This demonstrates use of the 'format.id_only' param.
2148 This param causes the id of the only entity to be returned as an integer.
2149 It will be ignored if there is not exactly 1 result";
2150 $subfile = "FormatOnlyID";
2151 $params = array('id' => 17, 'format.only_id' => 1);
2152 $result = $this->callAPIAndDocument('Contact', 'Get', $params, __FUNCTION__, __FILE__, $description, $subfile);
2153 $this->assertEquals('17', $result);
2154 $this->callAPISuccess('Contact', 'Delete', $params);
2155 }
2156
2157 /**
2158 * Test id only format.
2159 */
2160 public function testContactGetFormatSingleValue() {
2161 $this->createContactFromXML();
2162 $description = "This demonstrates use of the 'format.single_value' param.
2163 This param causes only a single value of the only entity to be returned as an string.
2164 It will be ignored if there is not exactly 1 result";
2165 $subFile = "FormatSingleValue";
2166 $params = array('id' => 17, 'return' => 'display_name');
2167 $result = $this->callAPIAndDocument('Contact', 'getvalue', $params, __FUNCTION__, __FILE__, $description, $subFile);
2168 $this->assertEquals('Test Contact', $result);
2169 $this->callAPISuccess('Contact', 'Delete', $params);
2170 }
2171
2172 /**
2173 * Test that permissions are respected when creating contacts.
2174 */
2175 public function testContactCreationPermissions() {
2176 $params = array(
2177 'contact_type' => 'Individual',
2178 'first_name' => 'Foo',
2179 'last_name' => 'Bear',
2180 'check_permissions' => TRUE,
2181 );
2182 $config = CRM_Core_Config::singleton();
2183 $config->userPermissionClass->permissions = array('access CiviCRM');
2184 $result = $this->callAPIFailure('contact', 'create', $params);
2185 $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');
2186
2187 $config->userPermissionClass->permissions = array('access CiviCRM', 'add contacts', 'import contacts');
2188 $this->callAPISuccess('contact', 'create', $params);
2189 }
2190
2191 /**
2192 * Test update with check permissions set.
2193 */
2194 public function testContactUpdatePermissions() {
2195 $params = array(
2196 'contact_type' => 'Individual',
2197 'first_name' => 'Foo',
2198 'last_name' => 'Bear',
2199 'check_permissions' => TRUE,
2200 );
2201 $result = $this->callAPISuccess('contact', 'create', $params);
2202 $config = CRM_Core_Config::singleton();
2203 $params = array(
2204 'id' => $result['id'],
2205 'contact_type' => 'Individual',
2206 'last_name' => 'Bar',
2207 'check_permissions' => TRUE,
2208 );
2209
2210 $config->userPermissionClass->permissions = array('access CiviCRM');
2211 $result = $this->callAPIFailure('contact', 'update', $params);
2212 $this->assertEquals('Permission denied to modify contact record', $result['error_message']);
2213
2214 $config->userPermissionClass->permissions = array(
2215 'access CiviCRM',
2216 'add contacts',
2217 'view all contacts',
2218 'edit all contacts',
2219 'import contacts',
2220 );
2221 $this->callAPISuccess('contact', 'update', $params);
2222 }
2223
2224 /**
2225 * Set up helper to create a contact.
2226 */
2227 public function createContactFromXML() {
2228 // Insert a row in civicrm_contact creating contact 17.
2229 $op = new PHPUnit_Extensions_Database_Operation_Insert();
2230 $op->execute($this->_dbconn,
2231 $this->createXMLDataSet(
2232 dirname(__FILE__) . '/dataset/contact_17.xml'
2233 )
2234 );
2235 }
2236
2237 /**
2238 * Test contact proximity api.
2239 */
2240 public function testContactProximity() {
2241 // first create a contact with a SF location with a specific
2242 // geocode
2243 $contactID = $this->organizationCreate();
2244
2245 // now create the address
2246 $params = array(
2247 'street_address' => '123 Main Street',
2248 'city' => 'San Francisco',
2249 'is_primary' => 1,
2250 'country_id' => 1228,
2251 'state_province_id' => 1004,
2252 'geo_code_1' => '37.79',
2253 'geo_code_2' => '-122.40',
2254 'location_type_id' => 1,
2255 'contact_id' => $contactID,
2256 );
2257
2258 $result = $this->callAPISuccess('address', 'create', $params);
2259 $this->assertEquals(1, $result['count']);
2260
2261 // now do a proximity search with a close enough geocode and hope to match
2262 // that specific contact only!
2263 $proxParams = array(
2264 'latitude' => 37.7,
2265 'longitude' => -122.3,
2266 'unit' => 'mile',
2267 'distance' => 10,
2268 );
2269 $result = $this->callAPISuccess('contact', 'proximity', $proxParams);
2270 $this->assertEquals(1, $result['count']);
2271 }
2272
2273 /**
2274 * Test that Ajax API permission is sufficient to access getquick api.
2275 *
2276 * (note that getquick api is required for autocomplete & has ACL permissions applied)
2277 */
2278 public function testGetquickPermissionCRM13744() {
2279 CRM_Core_Config::singleton()->userPermissionClass->permissions = array('access CiviEvent');
2280 $this->callAPIFailure('contact', 'getquick', array('name' => 'b', 'check_permissions' => TRUE));
2281 CRM_Core_Config::singleton()->userPermissionClass->permissions = array('access CiviCRM');
2282 $this->callAPISuccess('contact', 'getquick', array('name' => 'b', 'check_permissions' => TRUE));
2283 CRM_Core_Config::singleton()->userPermissionClass->permissions = array('access AJAX API');
2284 $this->callAPISuccess('contact', 'getquick', array('name' => 'b', 'check_permissions' => TRUE));
2285 }
2286
2287 /**
2288 * Test that getquick returns contacts with an exact first name match first.
2289 *
2290 * The search string 'b' & 'bob' both return ordered by sort_name if includeOrderByClause
2291 * is true (default) but if it is false then matches are returned in ID order.
2292 */
2293 public function testGetQuickExactFirst() {
2294 $this->getQuickSearchSampleData();
2295 $result = $this->callAPISuccess('contact', 'getquick', array('name' => 'b'));
2296 $this->assertEquals('A Bobby, Bobby', $result['values'][0]['sort_name']);
2297 $this->assertEquals('B Bobby, Bobby', $result['values'][1]['sort_name']);
2298 $result = $this->callAPISuccess('contact', 'getquick', array('name' => 'bob'));
2299 $this->assertEquals('A Bobby, Bobby', $result['values'][0]['sort_name']);
2300 $this->assertEquals('B Bobby, Bobby', $result['values'][1]['sort_name']);
2301 $this->callAPISuccess('Setting', 'create', array('includeOrderByClause' => FALSE));
2302 $result = $this->callAPISuccess('contact', 'getquick', array('name' => 'bob'));
2303 $this->assertEquals('Bob, Bob', $result['values'][0]['sort_name']);
2304 $this->assertEquals('A Bobby, Bobby', $result['values'][1]['sort_name']);
2305 }
2306
2307 /**
2308 * Test that getquick returns contacts with an exact first name match first.
2309 */
2310 public function testGetQuickEmail() {
2311 $this->getQuickSearchSampleData();
2312 $loggedInContactID = $this->createLoggedInUser();
2313 $result = $this->callAPISuccess('contact', 'getquick', array(
2314 'name' => 'c',
2315 ));
2316 $expectedData = array(
2317 'Bob, Bob :: bob@bob.com',
2318 'C Bobby, Bobby',
2319 'E Bobby, Bobby :: bob@bobby.com',
2320 'H Bobby, Bobby :: bob@h.com',
2321 'Second Domain',
2322 $this->callAPISuccessGetValue('Contact', array('id' => $loggedInContactID, 'return' => 'last_name')) . ', Logged In :: anthony_anderson@civicrm.org',
2323 );
2324 $this->assertEquals(6, $result['count']);
2325 foreach ($expectedData as $index => $value) {
2326 $this->assertEquals($value, $result['values'][$index]['data']);
2327 }
2328 $result = $this->callAPISuccess('contact', 'getquick', array(
2329 'name' => 'h.',
2330 ));
2331 $expectedData = array(
2332 'H Bobby, Bobby :: bob@h.com',
2333 );
2334 foreach ($expectedData as $index => $value) {
2335 $this->assertEquals($value, $result['values'][$index]['data']);
2336 }
2337 $this->callAPISuccess('Setting', 'create', array('includeWildCardInName' => FALSE));
2338 $result = $this->callAPISuccess('contact', 'getquick', array(
2339 'name' => 'h.',
2340 ));
2341 $this->callAPISuccess('Setting', 'create', array('includeWildCardInName' => TRUE));
2342 $this->assertEquals(0, $result['count']);
2343 }
2344
2345 /**
2346 * Test that getquick returns contacts with an exact first name match first.
2347 */
2348 public function testGetQuickEmailACL() {
2349 $this->getQuickSearchSampleData();
2350 $loggedInContactID = $this->createLoggedInUser();
2351 CRM_Core_Config::singleton()->userPermissionClass->permissions = array();
2352 $result = $this->callAPISuccess('contact', 'getquick', array(
2353 'name' => 'c',
2354 ));
2355 $this->assertEquals(0, $result['count']);
2356
2357 $this->hookClass->setHook('civicrm_aclWhereClause', array($this, 'aclWhereNoBobH'));
2358 CRM_Contact_BAO_Contact_Permission::cache($loggedInContactID, CRM_Core_Permission::VIEW, TRUE);
2359 $result = $this->callAPISuccess('contact', 'getquick', array(
2360 'name' => 'c',
2361 ));
2362
2363 // Without the acl it would be 6 like the previous email getquick test.
2364 $this->assertEquals(5, $result['count']);
2365 $expectedData = array(
2366 'Bob, Bob :: bob@bob.com',
2367 'C Bobby, Bobby',
2368 'E Bobby, Bobby :: bob@bobby.com',
2369 'Second Domain',
2370 $this->callAPISuccessGetValue('Contact', array('id' => $loggedInContactID, 'return' => 'last_name')) . ', Logged In :: anthony_anderson@civicrm.org',
2371 );
2372 foreach ($expectedData as $index => $value) {
2373 $this->assertEquals($value, $result['values'][$index]['data']);
2374 }
2375 }
2376
2377 /**
2378 * Test that getquick returns contacts with an exact first name match first.
2379 */
2380 public function testGetQuickExternalID() {
2381 $this->getQuickSearchSampleData();
2382 $result = $this->callAPISuccess('contact', 'getquick', array(
2383 'name' => 'b',
2384 'field_name' => 'external_identifier',
2385 'table_name' => 'cc',
2386 ));
2387 $this->assertEquals(0, $result['count']);
2388 $result = $this->callAPISuccess('contact', 'getquick', array(
2389 'name' => 'abc',
2390 'field_name' => 'external_identifier',
2391 'table_name' => 'cc',
2392 ));
2393 $this->assertEquals(1, $result['count']);
2394 $this->assertEquals('Bob, Bob', $result['values'][0]['sort_name']);
2395 }
2396
2397 /**
2398 * Test that getquick returns contacts with an exact first name match first.
2399 */
2400 public function testGetQuickID() {
2401 $max = CRM_Core_DAO::singleValueQuery("SELECT max(id) FROM civicrm_contact");
2402 $this->getQuickSearchSampleData();
2403 $result = $this->callAPISuccess('contact', 'getquick', array(
2404 'name' => $max + 2,
2405 'field_name' => 'id',
2406 'table_name' => 'cc',
2407 ));
2408 $this->assertEquals(1, $result['count']);
2409 $this->assertEquals('A Bobby, Bobby', $result['values'][0]['sort_name']);
2410 $result = $this->callAPISuccess('contact', 'getquick', array(
2411 'name' => $max + 2,
2412 'field_name' => 'contact_id',
2413 'table_name' => 'cc',
2414 ));
2415 $this->assertEquals(1, $result['count']);
2416 $this->assertEquals('A Bobby, Bobby', $result['values'][0]['sort_name']);
2417 }
2418
2419 /**
2420 * Test that getquick returns contacts with an exact first name match first.
2421 *
2422 * Depending on the setting the sort name sort might click in next or not - test!
2423 */
2424 public function testGetQuickFirstName() {
2425 $this->getQuickSearchSampleData();
2426 $this->callAPISuccess('Setting', 'create', array('includeOrderByClause' => TRUE));
2427 $result = $this->callAPISuccess('contact', 'getquick', array(
2428 'name' => 'Bob',
2429 'field_name' => 'first_name',
2430 'table_name' => 'cc',
2431 ));
2432 $expected = array(
2433 'Bob, Bob',
2434 'K Bobby, Bob',
2435 'A Bobby, Bobby',
2436 );
2437
2438 foreach ($expected as $index => $value) {
2439 $this->assertEquals($value, $result['values'][$index]['sort_name']);
2440 }
2441 $this->callAPISuccess('Setting', 'create', array('includeOrderByClause' => FALSE));
2442 $result = $this->callAPISuccess('contact', 'getquick', array('name' => 'bob'));
2443 $this->assertEquals('Bob, Bob', $result['values'][0]['sort_name']);
2444 $this->assertEquals('A Bobby, Bobby', $result['values'][1]['sort_name']);
2445 }
2446
2447 /**
2448 * Test that getquick applies ACLs.
2449 */
2450 public function testGetQuickFirstNameACLs() {
2451 $this->getQuickSearchSampleData();
2452 $userID = $this->createLoggedInUser();
2453 $this->callAPISuccess('Setting', 'create', array('includeOrderByClause' => TRUE));
2454 CRM_Core_Config::singleton()->userPermissionClass->permissions = array();
2455 $result = $this->callAPISuccess('contact', 'getquick', array(
2456 'name' => 'Bob',
2457 'field_name' => 'first_name',
2458 'table_name' => 'cc',
2459 ));
2460 $this->assertEquals(0, $result['count']);
2461
2462 $this->hookClass->setHook('civicrm_aclWhereClause', array($this, 'aclWhereNoBobH'));
2463 CRM_Contact_BAO_Contact_Permission::cache($userID, CRM_Core_Permission::VIEW, TRUE);
2464 $result = $this->callAPISuccess('contact', 'getquick', array(
2465 'name' => 'Bob',
2466 'field_name' => 'first_name',
2467 'table_name' => 'cc',
2468 ));
2469 $this->assertEquals('K Bobby, Bob', $result['values'][1]['sort_name']);
2470 // Without the ACL 9 would be bob@h.com.
2471 $this->assertEquals('I Bobby, Bobby', $result['values'][9]['sort_name']);
2472 }
2473
2474 /**
2475 * Full results returned.
2476 * @implements CRM_Utils_Hook::aclWhereClause
2477 *
2478 * @param string $type
2479 * @param array $tables
2480 * @param array $whereTables
2481 * @param int $contactID
2482 * @param string $where
2483 */
2484 public function aclWhereNoBobH($type, &$tables, &$whereTables, &$contactID, &$where) {
2485 $where = " (email <> 'bob@h.com' OR email IS NULL) ";
2486 $whereTables['civicrm_email'] = "LEFT JOIN civicrm_email e ON contact_a.id = e.contact_id";
2487 }
2488
2489 /**
2490 * Test that getquick returns contacts with an exact last name match first.
2491 */
2492 public function testGetQuickLastName() {
2493 $this->getQuickSearchSampleData();
2494 $this->callAPISuccess('Setting', 'create', array('includeOrderByClause' => TRUE));
2495 $result = $this->callAPISuccess('contact', 'getquick', array(
2496 'name' => 'Bob',
2497 'field_name' => 'last_name',
2498 'table_name' => 'cc',
2499 ));
2500 $expected = array(
2501 'Bob, Bob',
2502 'A Bobby, Bobby',
2503 'B Bobby, Bobby',
2504 );
2505
2506 foreach ($expected as $index => $value) {
2507 $this->assertEquals($value, $result['values'][$index]['sort_name']);
2508 }
2509 $this->callAPISuccess('Setting', 'create', array('includeOrderByClause' => FALSE));
2510 $result = $this->callAPISuccess('contact', 'getquick', array('name' => 'bob'));
2511 $this->assertEquals('Bob, Bob :: bob@bob.com', $result['values'][0]['data']);
2512 }
2513
2514 /**
2515 * Test that getquick returns contacts by city.
2516 */
2517 public function testGetQuickCity() {
2518 $this->getQuickSearchSampleData();
2519 $result = $this->callAPISuccess('contact', 'getquick', array(
2520 'name' => 'o',
2521 'field_name' => 'city',
2522 'table_name' => 'sts',
2523 ));
2524 $this->assertEquals('B Bobby, Bobby :: Toronto', $result['values'][0]['data']);
2525 $result = $this->callAPISuccess('contact', 'getquick', array(
2526 'name' => 'n',
2527 'field_name' => 'city',
2528 'table_name' => 'sts',
2529 ));
2530 $this->assertEquals('B Bobby, Bobby :: Toronto', $result['values'][0]['data']);
2531 $this->assertEquals('C Bobby, Bobby :: Whanganui', $result['values'][1]['data']);
2532 }
2533
2534 /**
2535 * Set up some sample data for testing quicksearch.
2536 */
2537 public function getQuickSearchSampleData() {
2538 $contacts = array(
2539 array('first_name' => 'Bob', 'last_name' => 'Bob', 'external_identifier' => 'abc', 'email' => 'bob@bob.com'),
2540 array('first_name' => 'Bobby', 'last_name' => 'A Bobby', 'external_identifier' => 'abcd'),
2541 array(
2542 'first_name' => 'Bobby',
2543 'last_name' => 'B Bobby',
2544 'external_identifier' => 'bcd',
2545 'api.address.create' => array(
2546 'street_address' => 'Sesame Street',
2547 'city' => 'Toronto',
2548 'location_type_id' => 1,
2549 ),
2550 ),
2551 array(
2552 'first_name' => 'Bobby',
2553 'last_name' => 'C Bobby',
2554 'external_identifier' => 'bcde',
2555 'api.address.create' => array(
2556 'street_address' => 'Te huarahi',
2557 'city' => 'Whanganui',
2558 'location_type_id' => 1,
2559 ),
2560 ),
2561 array('first_name' => 'Bobby', 'last_name' => 'D Bobby', 'external_identifier' => 'efg'),
2562 array('first_name' => 'Bobby', 'last_name' => 'E Bobby', 'external_identifier' => 'hij', 'email' => 'bob@bobby.com'),
2563 array('first_name' => 'Bobby', 'last_name' => 'F Bobby', 'external_identifier' => 'klm'),
2564 array('first_name' => 'Bobby', 'last_name' => 'G Bobby', 'external_identifier' => 'nop'),
2565 array('first_name' => 'Bobby', 'last_name' => 'H Bobby', 'external_identifier' => 'qrs', 'email' => 'bob@h.com'),
2566 array('first_name' => 'Bobby', 'last_name' => 'I Bobby'),
2567 array('first_name' => 'Bobby', 'last_name' => 'J Bobby'),
2568 array('first_name' => 'Bob', 'last_name' => 'K Bobby', 'external_identifier' => 'bcdef'),
2569 );
2570 foreach ($contacts as $type => $contact) {
2571 $contact['contact_type'] = 'Individual';
2572 $this->callAPISuccess('Contact', 'create', $contact);
2573 }
2574 }
2575
2576 /**
2577 * Test get ref api - gets a list of references to an entity.
2578 */
2579 public function testGetReferenceCounts() {
2580 $result = $this->callAPISuccess('Contact', 'create', array(
2581 'first_name' => 'Testily',
2582 'last_name' => 'McHaste',
2583 'contact_type' => 'Individual',
2584 'api.Address.replace' => array(
2585 'values' => array(),
2586 ),
2587 'api.Email.replace' => array(
2588 'values' => array(
2589 array(
2590 'email' => 'spam@dev.null',
2591 'is_primary' => 0,
2592 'location_type_id' => 1,
2593 ),
2594 ),
2595 ),
2596 'api.Phone.replace' => array(
2597 'values' => array(
2598 array(
2599 'phone' => '234-567-0001',
2600 'is_primary' => 1,
2601 'location_type_id' => 1,
2602 ),
2603 array(
2604 'phone' => '234-567-0002',
2605 'is_primary' => 0,
2606 'location_type_id' => 1,
2607 ),
2608 ),
2609 ),
2610 ));
2611
2612 //$dao = new CRM_Contact_BAO_Contact();
2613 //$dao->id = $result['id'];
2614 //$this->assertTrue((bool) $dao->find(TRUE));
2615 //
2616 //$refCounts = $dao->getReferenceCounts();
2617 //$this->assertTrue(is_array($refCounts));
2618 //$refCountsIdx = CRM_Utils_Array::index(array('name'), $refCounts);
2619
2620 $refCounts = $this->callAPISuccess('Contact', 'getrefcount', array(
2621 'id' => $result['id'],
2622 ));
2623 $refCountsIdx = CRM_Utils_Array::index(array('name'), $refCounts['values']);
2624
2625 $this->assertEquals(1, $refCountsIdx['sql:civicrm_email:contact_id']['count']);
2626 $this->assertEquals('civicrm_email', $refCountsIdx['sql:civicrm_email:contact_id']['table']);
2627 $this->assertEquals(2, $refCountsIdx['sql:civicrm_phone:contact_id']['count']);
2628 $this->assertEquals('civicrm_phone', $refCountsIdx['sql:civicrm_phone:contact_id']['table']);
2629 $this->assertTrue(!isset($refCountsIdx['sql:civicrm_address:contact_id']));
2630 }
2631
2632 /**
2633 * Test the use of sql operators.
2634 */
2635 public function testSQLOperatorsOnContactAPI() {
2636 $this->individualCreate();
2637 $this->organizationCreate();
2638 $this->householdCreate();
2639 $contacts = $this->callAPISuccess('contact', 'get', array('legal_name' => array('IS NOT NULL' => TRUE)));
2640 $this->assertEquals($contacts['count'], CRM_Core_DAO::singleValueQuery('select count(*) FROM civicrm_contact WHERE legal_name IS NOT NULL'));
2641 $contacts = $this->callAPISuccess('contact', 'get', array('legal_name' => array('IS NULL' => TRUE)));
2642 $this->assertEquals($contacts['count'], CRM_Core_DAO::singleValueQuery('select count(*) FROM civicrm_contact WHERE legal_name IS NULL'));
2643 }
2644
2645 /**
2646 * CRM-14743 - test api respects search operators.
2647 */
2648 public function testGetModifiedDateByOperators() {
2649 $preExistingContactCount = CRM_Core_DAO::singleValueQuery('select count(*) FROM civicrm_contact');
2650 $contact1 = $this->individualCreate();
2651 $sql = "UPDATE civicrm_contact SET created_date = '2012-01-01', modified_date = '2013-01-01' WHERE id = " . $contact1;
2652 CRM_Core_DAO::executeQuery($sql);
2653 $contact2 = $this->individualCreate();
2654 $sql = "UPDATE civicrm_contact SET created_date = '2012-02-01', modified_date = '2013-02-01' WHERE id = " . $contact2;
2655 CRM_Core_DAO::executeQuery($sql);
2656 $contact3 = $this->householdCreate();
2657 $sql = "UPDATE civicrm_contact SET created_date = '2012-03-01', modified_date = '2013-03-01' WHERE id = " . $contact3;
2658 CRM_Core_DAO::executeQuery($sql);
2659 $contacts = $this->callAPISuccess('contact', 'get', array('modified_date' => array('<' => '2014-01-01')));
2660 $this->assertEquals($contacts['count'], 3);
2661 $contacts = $this->callAPISuccess('contact', 'get', array('modified_date' => array('>' => '2014-01-01')));
2662 $this->assertEquals($contacts['count'], $preExistingContactCount);
2663 }
2664
2665 /**
2666 * CRM-14743 - test api respects search operators.
2667 */
2668 public function testGetCreatedDateByOperators() {
2669 $preExistingContactCount = CRM_Core_DAO::singleValueQuery('select count(*) FROM civicrm_contact');
2670 $contact1 = $this->individualCreate();
2671 $sql = "UPDATE civicrm_contact SET created_date = '2012-01-01' WHERE id = " . $contact1;
2672 CRM_Core_DAO::executeQuery($sql);
2673 $contact2 = $this->individualCreate();
2674 $sql = "UPDATE civicrm_contact SET created_date = '2012-02-01' WHERE id = " . $contact2;
2675 CRM_Core_DAO::executeQuery($sql);
2676 $contact3 = $this->householdCreate();
2677 $sql = "UPDATE civicrm_contact SET created_date = '2012-03-01' WHERE id = " . $contact3;
2678 CRM_Core_DAO::executeQuery($sql);
2679 $contacts = $this->callAPISuccess('contact', 'get', array('created_date' => array('<' => '2014-01-01')));
2680 $this->assertEquals($contacts['count'], 3);
2681 $contacts = $this->callAPISuccess('contact', 'get', array('created_date' => array('>' => '2014-01-01')));
2682 $this->assertEquals($contacts['count'], $preExistingContactCount);
2683 }
2684
2685 /**
2686 * CRM-14263 check that API is not affected by search profile related bug.
2687 */
2688 public function testReturnCityProfile() {
2689 $contactID = $this->individualCreate();
2690 CRM_Core_Config::singleton()->defaultSearchProfileID = 1;
2691 $this->callAPISuccess('address', 'create', array(
2692 'contact_id' => $contactID,
2693 'city' => 'Cool City',
2694 'location_type_id' => 1,
2695 ));
2696 $result = $this->callAPISuccess('contact', 'get', array('city' => 'Cool City', 'return' => 'contact_type'));
2697 $this->assertEquals(1, $result['count']);
2698 }
2699
2700 /**
2701 * CRM-15443 - ensure getlist api does not return deleted contacts.
2702 */
2703 public function testGetlistExcludeConditions() {
2704 $name = md5(time());
2705 $contact = $this->individualCreate(array('last_name' => $name));
2706 $this->individualCreate(array('last_name' => $name, 'is_deceased' => 1));
2707 $this->individualCreate(array('last_name' => $name, 'is_deleted' => 1));
2708 // We should get all but the deleted contact.
2709 $result = $this->callAPISuccess('contact', 'getlist', array('input' => $name));
2710 $this->assertEquals(2, $result['count']);
2711 // Force-exclude the deceased contact.
2712 $result = $this->callAPISuccess('contact', 'getlist', array(
2713 'input' => $name,
2714 'params' => array('is_deceased' => 0),
2715 ));
2716 $this->assertEquals(1, $result['count']);
2717 $this->assertEquals($contact, $result['values'][0]['id']);
2718 }
2719
2720 /**
2721 * Test contact getactions.
2722 */
2723 public function testGetActions() {
2724 $description = "Getting the available actions for an entity.";
2725 $result = $this->callAPIAndDocument($this->_entity, 'getactions', array(), __FUNCTION__, __FILE__, $description);
2726 $expected = array(
2727 'create',
2728 'delete',
2729 'get',
2730 'getactions',
2731 'getcount',
2732 'getfields',
2733 'getlist',
2734 'getoptions',
2735 'getquick',
2736 'getrefcount',
2737 'getsingle',
2738 'getvalue',
2739 'merge',
2740 'proximity',
2741 'replace',
2742 'setvalue',
2743 'update',
2744 );
2745 $deprecated = array(
2746 'update',
2747 'getquick',
2748 );
2749 foreach ($expected as $action) {
2750 $this->assertTrue(in_array($action, $result['values']), "Expected action $action");
2751 }
2752 foreach ($deprecated as $action) {
2753 $this->assertArrayKeyExists($action, $result['deprecated']);
2754 }
2755 }
2756
2757 /**
2758 * Test the duplicate check function.
2759 */
2760 public function testDuplicateCheck() {
2761 $this->callAPISuccess('Contact', 'create', array(
2762 'first_name' => 'Harry',
2763 'last_name' => 'Potter',
2764 'email' => 'harry@hogwarts.edu',
2765 'contact_type' => 'Individual',
2766 ));
2767 $result = $this->callAPISuccess('Contact', 'duplicatecheck', array(
2768 'match' => array(
2769 'first_name' => 'Harry',
2770 'last_name' => 'Potter',
2771 'email' => 'harry@hogwarts.edu',
2772 'contact_type' => 'Individual',
2773 ),
2774 ));
2775
2776 $this->assertEquals(1, $result['count']);
2777 $result = $this->callAPISuccess('Contact', 'duplicatecheck', array(
2778 'match' => array(
2779 'first_name' => 'Harry',
2780 'last_name' => 'Potter',
2781 'email' => 'no5@privet.drive',
2782 'contact_type' => 'Individual',
2783 ),
2784 ));
2785 $this->assertEquals(0, $result['count']);
2786 }
2787
2788 public function testGetByContactType() {
2789 $individual = $this->callAPISuccess('Contact', 'create', array(
2790 'email' => 'individual@test.com',
2791 'contact_type' => 'Individual',
2792 ));
2793 $household = $this->callAPISuccess('Contact', 'create', array(
2794 'household_name' => 'household@test.com',
2795 'contact_type' => 'Household',
2796 ));
2797 $organization = $this->callAPISuccess('Contact', 'create', array(
2798 'organization_name' => 'organization@test.com',
2799 'contact_type' => 'Organization',
2800 ));
2801 // Test with id - getsingle will throw an exception if not found
2802 $this->callAPISuccess('Contact', 'getsingle', array(
2803 'id' => $individual['id'],
2804 'contact_type' => 'Individual',
2805 ));
2806 $this->callAPISuccess('Contact', 'getsingle', array(
2807 'id' => $individual['id'],
2808 'contact_type' => array('IN' => array('Individual')),
2809 'return' => 'id',
2810 ));
2811 $this->callAPISuccess('Contact', 'getsingle', array(
2812 'id' => $organization['id'],
2813 'contact_type' => array('IN' => array('Individual', 'Organization')),
2814 ));
2815 // Test as array
2816 $result = $this->callAPISuccess('Contact', 'get', array(
2817 'contact_type' => array('IN' => array('Individual', 'Organization')),
2818 'options' => array('limit' => 0),
2819 'return' => 'id',
2820 ));
2821 $this->assertContains($organization['id'], array_keys($result['values']));
2822 $this->assertContains($individual['id'], array_keys($result['values']));
2823 $this->assertNotContains($household['id'], array_keys($result['values']));
2824 // Test as string
2825 $result = $this->callAPISuccess('Contact', 'get', array(
2826 'contact_type' => 'Household',
2827 'options' => array('limit' => 0),
2828 'return' => 'id',
2829 ));
2830 $this->assertNotContains($organization['id'], array_keys($result['values']));
2831 $this->assertNotContains($individual['id'], array_keys($result['values']));
2832 $this->assertContains($household['id'], array_keys($result['values']));
2833 }
2834
2835 /**
2836 * Test merging 2 contacts.
2837 *
2838 * Someone kindly bequethed us the legacy of mixed up use of main_id & other_id
2839 * in the params for contact.merge api.
2840 *
2841 * This test protects that legacy.
2842 */
2843 public function testMergeBizzareOldParams() {
2844 $this->createLoggedInUser();
2845 $otherContact = $this->callAPISuccess('contact', 'create', $this->_params);
2846 $mainContact = $this->callAPISuccess('contact', 'create', $this->_params);
2847 $this->callAPISuccess('contact', 'merge', array(
2848 'main_id' => $mainContact['id'],
2849 'other_id' => $otherContact['id'],
2850 ));
2851 $contacts = $this->callAPISuccess('contact', 'get', $this->_params);
2852 $this->assertEquals($otherContact['id'], $contacts['id']);
2853 }
2854
2855 /**
2856 * Test merging 2 contacts.
2857 */
2858 public function testMerge() {
2859 $this->createLoggedInUser();
2860 $otherContact = $this->callAPISuccess('contact', 'create', $this->_params);
2861 $retainedContact = $this->callAPISuccess('contact', 'create', $this->_params);
2862 $this->callAPISuccess('contact', 'merge', array(
2863 'to_keep_id' => $retainedContact['id'],
2864 'to_remove_id' => $otherContact['id'],
2865 'auto_flip' => FALSE,
2866 ));
2867
2868 $contacts = $this->callAPISuccess('contact', 'get', $this->_params);
2869 $this->assertEquals($retainedContact['id'], $contacts['id']);
2870 $activity = $this->callAPISuccess('Activity', 'getsingle', array(
2871 'target_contact_id' => $retainedContact['id'],
2872 'activity_type_id' => 'Contact Merged',
2873 ));
2874 $this->assertEquals(date('Y-m-d'), date('Y-m-d', strtotime($activity['activity_date_time'])));
2875
2876 }
2877
2878 }