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