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