Merge pull request #11597 from seamuslee001/CRM-20996
[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 ),
1189 'api.website.create' => array(
1190 'url' => "http://civicrm.org",
1191 ),
1192 'api.website.create.2' => array(
1193 'url' => "http://chained.org",
1194 ),
1195 );
1196
1197 $result = $this->callAPIAndDocument('Contact', 'create', $params, __FUNCTION__, __FILE__, $description, $subFile);
1198
1199 // checking child function result not covered in callAPIAndDocument
1200 $this->assertAPISuccess($result['values'][$result['id']]['api.website.create']);
1201 $this->assertEquals("http://chained.org", $result['values'][$result['id']]['api.website.create.2']['values'][0]['url']);
1202 $this->assertEquals("http://civicrm.org", $result['values'][$result['id']]['api.website.create']['values'][0]['url']);
1203
1204 // delete the contact
1205 $this->callAPISuccess('contact', 'delete', $result);
1206 }
1207
1208 /**
1209 * Verify that attempt to create individual contact with chained contribution and website succeeds.
1210 */
1211 public function testCreateIndividualWithContributionChainedArrays() {
1212 $params = array(
1213 'first_name' => 'abc3',
1214 'last_name' => 'xyz3',
1215 'contact_type' => 'Individual',
1216 'email' => 'man3@yahoo.com',
1217 'api.contribution.create' => array(
1218 'receive_date' => '2010-01-01',
1219 'total_amount' => 100.00,
1220 'financial_type_id' => $this->_financialTypeId,
1221 'payment_instrument_id' => 1,
1222 'non_deductible_amount' => 10.00,
1223 'fee_amount' => 50.00,
1224 'net_amount' => 90.00,
1225 'trxn_id' => 12345,
1226 'invoice_id' => 67890,
1227 'source' => 'SSF',
1228 'contribution_status_id' => 1,
1229 ),
1230 'api.website.create' => array(
1231 array(
1232 'url' => "http://civicrm.org",
1233 ),
1234 array(
1235 'url' => "http://chained.org",
1236 'website_type_id' => 2,
1237 ),
1238 ),
1239 );
1240
1241 $description = "Demonstrates creating two websites as an array.";
1242 $subfile = "ChainTwoWebsitesSyntax2";
1243 $result = $this->callAPIAndDocument('Contact', 'create', $params, __FUNCTION__, __FILE__, $description, $subfile);
1244
1245 // the callAndDocument doesn't check the chained call
1246 $this->assertEquals(0, $result['values'][$result['id']]['api.website.create'][0]['is_error']);
1247 $this->assertEquals("http://chained.org", $result['values'][$result['id']]['api.website.create'][1]['values'][0]['url']);
1248 $this->assertEquals("http://civicrm.org", $result['values'][$result['id']]['api.website.create'][0]['values'][0]['url']);
1249
1250 $this->callAPISuccess('contact', 'delete', $result);
1251 }
1252
1253 /**
1254 * Test for direction when chaining relationships.
1255 *
1256 * https://issues.civicrm.org/jira/browse/CRM-16084
1257 */
1258 public function testDirectionChainingRelationshipsCRM16084() {
1259 // Some contact, called Jules.
1260 $create_result_1 = $this->callAPISuccess('contact', 'create', array(
1261 'first_name' => 'Jules',
1262 'last_name' => 'Smos',
1263 'contact_type' => 'Individual',
1264 ));
1265
1266 // Another contact: Jos, child of Jules.
1267 $create_params = array(
1268 'first_name' => 'Jos',
1269 'last_name' => 'Smos',
1270 'contact_type' => 'Individual',
1271 'api.relationship.create' => array(
1272 array(
1273 'contact_id_a' => '$value.id',
1274 'contact_id_b' => $create_result_1['id'],
1275 // child of
1276 'relationship_type_id' => 1,
1277 ),
1278 ),
1279 );
1280 $create_result_2 = $this->callAPISuccess('contact', 'create', $create_params);
1281
1282 // Mia is the child of Jos.
1283 $create_params = array(
1284 'first_name' => 'Mia',
1285 'last_name' => 'Smos',
1286 'contact_type' => 'Individual',
1287 'api.relationship.create' => array(
1288 array(
1289 'contact_id_a' => '$value.id',
1290 'contact_id_b' => $create_result_2['id'],
1291 // child of
1292 'relationship_type_id' => 1,
1293 ),
1294 ),
1295 );
1296 $create_result_3 = $this->callAPISuccess('contact', 'create', $create_params);
1297
1298 // Get Jos and his children.
1299 $get_params = array(
1300 'sequential' => 1,
1301 'id' => $create_result_2['id'],
1302 'api.relationship.get' => array(
1303 'contact_id_b' => '$value.id',
1304 'relationship_type_id' => 1,
1305 ),
1306 );
1307 $get_result = $this->callAPISuccess('contact', 'getsingle', $get_params);
1308
1309 // Clean up first.
1310 $this->callAPISuccess('contact', 'delete', array(
1311 'id' => $create_result_1['id'],
1312 ));
1313 $this->callAPISuccess('contact', 'delete', array(
1314 'id' => $create_result_2['id'],
1315 ));
1316 $this->callAPISuccess('contact', 'delete', array(
1317 'id' => $create_result_2['id'],
1318 ));
1319
1320 // Assert.
1321 $this->assertEquals(1, $get_result['api.relationship.get']['count']);
1322 $this->assertEquals($create_result_3['id'], $get_result['api.relationship.get']['values'][0]['contact_id_a']);
1323 }
1324
1325 /**
1326 * Verify that attempt to create individual contact with first, and last names and email succeeds.
1327 */
1328 public function testCreateIndividualWithNameEmail() {
1329 $params = array(
1330 'first_name' => 'abc3',
1331 'last_name' => 'xyz3',
1332 'contact_type' => 'Individual',
1333 'email' => 'man3@yahoo.com',
1334 );
1335
1336 $contact = $this->callAPISuccess('contact', 'create', $params);
1337
1338 $this->callAPISuccess('contact', 'delete', $contact);
1339 }
1340
1341 /**
1342 * Verify that attempt to create individual contact with no data fails.
1343 */
1344 public function testCreateIndividualWithOutNameEmail() {
1345 $params = array(
1346 'contact_type' => 'Individual',
1347 );
1348 $this->callAPIFailure('contact', 'create', $params);
1349 }
1350
1351 /**
1352 * Test create individual contact with first &last names, email and location type succeeds.
1353 */
1354 public function testCreateIndividualWithNameEmailLocationType() {
1355 $params = array(
1356 'first_name' => 'abc4',
1357 'last_name' => 'xyz4',
1358 'email' => 'man4@yahoo.com',
1359 'contact_type' => 'Individual',
1360 'location_type_id' => 1,
1361 );
1362 $result = $this->callAPISuccess('contact', 'create', $params);
1363
1364 $this->callAPISuccess('contact', 'delete', array('id' => $result['id']));
1365 }
1366
1367 /**
1368 * Verify that when changing employers the old employer relationship becomes inactive.
1369 */
1370 public function testCreateIndividualWithEmployer() {
1371 $employer = $this->organizationCreate();
1372 $employer2 = $this->organizationCreate();
1373
1374 $params = array(
1375 'email' => 'man4@yahoo.com',
1376 'contact_type' => 'Individual',
1377 'employer_id' => $employer,
1378 );
1379
1380 $result = $this->callAPISuccess('contact', 'create', $params);
1381 $relationships = $this->callAPISuccess('relationship', 'get', array(
1382 'contact_id_a' => $result['id'],
1383 'sequential' => 1,
1384 ));
1385
1386 $this->assertEquals($employer, $relationships['values'][0]['contact_id_b']);
1387
1388 // Add more random relationships to make the test more realistic
1389 foreach (array('Employee of', 'Volunteer for') as $relationshipType) {
1390 $relTypeId = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_RelationshipType', $relationshipType, 'id', 'name_a_b');
1391 $this->callAPISuccess('relationship', 'create', array(
1392 'contact_id_a' => $result['id'],
1393 'contact_id_b' => $this->organizationCreate(),
1394 'is_active' => 1,
1395 'relationship_type_id' => $relTypeId,
1396 ));
1397 }
1398
1399 // Add second employer
1400 $params['employer_id'] = $employer2;
1401 $params['id'] = $result['id'];
1402 $result = $this->callAPISuccess('contact', 'create', $params);
1403
1404 $relationships = $this->callAPISuccess('relationship', 'get', array(
1405 'contact_id_a' => $result['id'],
1406 'sequential' => 1,
1407 'is_active' => 0,
1408 ));
1409
1410 $this->assertEquals($employer, $relationships['values'][0]['contact_id_b']);
1411 }
1412
1413 /**
1414 * Verify that attempt to create household contact with details succeeds.
1415 */
1416 public function testCreateHouseholdDetails() {
1417 $params = array(
1418 'household_name' => 'abc8\'s House',
1419 'nick_name' => 'x House',
1420 'email' => 'man8@yahoo.com',
1421 'contact_type' => 'Household',
1422 );
1423
1424 $contact = $this->callAPISuccess('contact', 'create', $params);
1425
1426 $this->callAPISuccess('contact', 'delete', $contact);
1427 }
1428
1429 /**
1430 * Verify that attempt to create household contact with inadequate details fails.
1431 */
1432 public function testCreateHouseholdInadequateDetails() {
1433 $params = array(
1434 'nick_name' => 'x House',
1435 'email' => 'man8@yahoo.com',
1436 'contact_type' => 'Household',
1437 );
1438 $this->callAPIFailure('contact', 'create', $params);
1439 }
1440
1441 /**
1442 * Verify successful update of individual contact.
1443 */
1444 public function testUpdateIndividualWithAll() {
1445 // Insert a row in civicrm_contact creating individual contact.
1446 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1447 $op->execute($this->_dbconn,
1448 $this->createXMLDataSet(
1449 dirname(__FILE__) . '/dataset/contact_ind.xml'
1450 )
1451 );
1452
1453 $params = array(
1454 'id' => 23,
1455 'first_name' => 'abcd',
1456 'contact_type' => 'Individual',
1457 'nick_name' => 'This is nickname first',
1458 'do_not_email' => '1',
1459 'do_not_phone' => '1',
1460 'do_not_mail' => '1',
1461 'do_not_trade' => '1',
1462 'legal_identifier' => 'ABC23853ZZ2235',
1463 'external_identifier' => '1928837465',
1464 'image_URL' => 'http://some.url.com/image.jpg',
1465 'home_url' => 'http://www.example.org',
1466
1467 );
1468
1469 $this->callAPISuccess('Contact', 'Update', $params);
1470 $getResult = $this->callAPISuccess('Contact', 'Get', $params);
1471 unset($params['contact_id']);
1472 //Todo - neither API v2 or V3 are testing for home_url - not sure if it is being set.
1473 //reducing this test partially back to api v2 level to get it through
1474 unset($params['home_url']);
1475 foreach ($params as $key => $value) {
1476 $this->assertEquals($value, $getResult['values'][23][$key]);
1477 }
1478 // Check updated civicrm_contact against expected.
1479 $expected = $this->createXMLDataSet(
1480 dirname(__FILE__) . '/dataset/contact_ind_upd.xml'
1481 );
1482 $actual = new PHPUnit_Extensions_Database_DataSet_QueryDataSet(
1483 $this->_dbconn
1484 );
1485 $actual->addTable('civicrm_contact');
1486 $expected->matches($actual);
1487 }
1488
1489 /**
1490 * Verify successful update of organization contact.
1491 */
1492 public function testUpdateOrganizationWithAll() {
1493 // Insert a row in civicrm_contact creating organization contact
1494 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1495 $op->execute($this->_dbconn,
1496 $this->createXMLDataSet(
1497 dirname(__FILE__) . '/dataset/contact_org.xml'
1498 )
1499 );
1500
1501 $params = array(
1502 'id' => 24,
1503 'organization_name' => 'WebAccess India Pvt Ltd',
1504 'legal_name' => 'WebAccess',
1505 'sic_code' => 'ABC12DEF',
1506 'contact_type' => 'Organization',
1507 );
1508
1509 $this->callAPISuccess('Contact', 'Update', $params);
1510
1511 // Check updated civicrm_contact against expected.
1512 $expected = $this->createXMLDataSet(
1513 dirname(__FILE__) . '/dataset/contact_org_upd.xml'
1514 );
1515 $actual = new PHPUnit_Extensions_Database_DataSet_QueryDataSet(
1516 $this->_dbconn
1517 );
1518 $actual->addTable('civicrm_contact');
1519 $expected->matches($actual);
1520 }
1521
1522 /**
1523 * Verify successful update of household contact.
1524 */
1525 public function testUpdateHouseholdWithAll() {
1526 // Insert a row in civicrm_contact creating household contact
1527 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1528 $op->execute($this->_dbconn,
1529 $this->createXMLDataSet(
1530 dirname(__FILE__) . '/dataset/contact_hld.xml'
1531 )
1532 );
1533
1534 $params = array(
1535 'id' => 25,
1536 'household_name' => 'ABC household',
1537 'nick_name' => 'ABC House',
1538 'contact_type' => 'Household',
1539 );
1540
1541 $result = $this->callAPISuccess('Contact', 'Update', $params);
1542
1543 $expected = array(
1544 'contact_type' => 'Household',
1545 'is_opt_out' => 0,
1546 'sort_name' => 'ABC household',
1547 'display_name' => 'ABC household',
1548 'nick_name' => 'ABC House',
1549 );
1550 $this->getAndCheck($expected, $result['id'], 'contact');
1551 }
1552
1553 /**
1554 * Test civicrm_update() without contact type.
1555 *
1556 * Deliberately exclude contact_type as it should still cope using civicrm_api.
1557 *
1558 * CRM-7645.
1559 */
1560 public function testUpdateCreateWithID() {
1561 // Insert a row in civicrm_contact creating individual contact.
1562 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1563 $op->execute($this->_dbconn,
1564 $this->createXMLDataSet(
1565 dirname(__FILE__) . '/dataset/contact_ind.xml'
1566 )
1567 );
1568
1569 $params = array(
1570 'id' => 23,
1571 'first_name' => 'abcd',
1572 'last_name' => 'wxyz',
1573 );
1574 $this->callAPISuccess('Contact', 'Update', $params);
1575 }
1576
1577 /**
1578 * Test civicrm_contact_delete() with no contact ID.
1579 */
1580 public function testContactDeleteNoID() {
1581 $params = array(
1582 'foo' => 'bar',
1583 );
1584 $this->callAPIFailure('contact', 'delete', $params);
1585 }
1586
1587 /**
1588 * Test civicrm_contact_delete() with error.
1589 */
1590 public function testContactDeleteError() {
1591 $params = array('contact_id' => 999);
1592 $this->callAPIFailure('contact', 'delete', $params);
1593 }
1594
1595 /**
1596 * Test civicrm_contact_delete().
1597 */
1598 public function testContactDelete() {
1599 $contactID = $this->individualCreate();
1600 $params = array(
1601 'id' => $contactID,
1602 );
1603 $this->callAPIAndDocument('contact', 'delete', $params, __FUNCTION__, __FILE__);
1604 }
1605
1606 /**
1607 * Test civicrm_contact_get() return only first name.
1608 */
1609 public function testContactGetRetFirst() {
1610 $contact = $this->callAPISuccess('contact', 'create', $this->_params);
1611 $params = array(
1612 'contact_id' => $contact['id'],
1613 'return_first_name' => TRUE,
1614 'sort' => 'first_name',
1615 );
1616 $result = $this->callAPISuccess('contact', 'get', $params);
1617 $this->assertEquals(1, $result['count']);
1618 $this->assertEquals($contact['id'], $result['id']);
1619 $this->assertEquals('abc1', $result['values'][$contact['id']]['first_name']);
1620 }
1621
1622 /**
1623 * Test civicrm_contact_get() return only first name & last name.
1624 *
1625 * Use comma separated string return with a space.
1626 */
1627 public function testContactGetReturnFirstLast() {
1628 $contact = $this->callAPISuccess('contact', 'create', $this->_params);
1629 $params = array(
1630 'contact_id' => $contact['id'],
1631 'return' => 'first_name, last_name',
1632 );
1633 $result = $this->callAPISuccess('contact', 'getsingle', $params);
1634 $this->assertEquals('abc1', $result['first_name']);
1635 $this->assertEquals('xyz1', $result['last_name']);
1636 //check that other defaults not returns
1637 $this->assertArrayNotHasKey('sort_name', $result);
1638 $params = array(
1639 'contact_id' => $contact['id'],
1640 'return' => 'first_name,last_name',
1641 );
1642 $result = $this->callAPISuccess('contact', 'getsingle', $params);
1643 $this->assertEquals('abc1', $result['first_name']);
1644 $this->assertEquals('xyz1', $result['last_name']);
1645 //check that other defaults not returns
1646 $this->assertArrayNotHasKey('sort_name', $result);
1647 }
1648
1649 /**
1650 * Test civicrm_contact_get() return only first name & last name.
1651 *
1652 * Use comma separated string return without a space
1653 */
1654 public function testContactGetReturnFirstLastNoComma() {
1655 $contact = $this->callAPISuccess('contact', 'create', $this->_params);
1656 $params = array(
1657 'contact_id' => $contact['id'],
1658 'return' => 'first_name,last_name',
1659 );
1660 $result = $this->callAPISuccess('contact', 'getsingle', $params);
1661 $this->assertEquals('abc1', $result['first_name']);
1662 $this->assertEquals('xyz1', $result['last_name']);
1663 //check that other defaults not returns
1664 $this->assertArrayNotHasKey('sort_name', $result);
1665 }
1666
1667 /**
1668 * Test civicrm_contact_get() with default return properties.
1669 */
1670 public function testContactGetRetDefault() {
1671 $contactID = $this->individualCreate();
1672 $params = array(
1673 'contact_id' => $contactID,
1674 'sort' => 'first_name',
1675 );
1676 $result = $this->callAPISuccess('contact', 'get', $params);
1677 $this->assertEquals($contactID, $result['values'][$contactID]['contact_id']);
1678 $this->assertEquals('Anthony', $result['values'][$contactID]['first_name']);
1679 }
1680
1681 /**
1682 * Test civicrm_contact_getquick() with empty name param.
1683 */
1684 public function testContactGetQuick() {
1685 // Insert a row in civicrm_contact creating individual contact.
1686 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1687 $op->execute($this->_dbconn,
1688 $this->createXMLDataSet(
1689 dirname(__FILE__) . '/dataset/contact_17.xml'
1690 )
1691 );
1692 $op->execute($this->_dbconn,
1693 $this->createXMLDataSet(
1694 dirname(__FILE__) . '/dataset/email_contact_17.xml'
1695 )
1696 );
1697 $params = array(
1698 'name' => "T",
1699 );
1700
1701 $result = $this->callAPISuccess('contact', 'getquick', $params);
1702 $this->assertEquals(17, $result['values'][0]['id']);
1703 }
1704
1705 /**
1706 * Test civicrm_contact_get) with empty params.
1707 */
1708 public function testContactGetEmptyParams() {
1709 $this->callAPISuccess('contact', 'get', array());
1710 }
1711
1712 /**
1713 * Test civicrm_contact_get(,true) with no matches.
1714 */
1715 public function testContactGetOldParamsNoMatches() {
1716 // Insert a row in civicrm_contact creating contact 17.
1717 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1718 $op->execute($this->_dbconn,
1719 $this->createXMLDataSet(
1720 dirname(__FILE__) . '/dataset/contact_17.xml'
1721 )
1722 );
1723
1724 $params = array(
1725 'first_name' => 'Fred',
1726 );
1727 $result = $this->callAPISuccess('contact', 'get', $params);
1728 $this->assertEquals(0, $result['count']);
1729 }
1730
1731 /**
1732 * Test civicrm_contact_get(,true) with one match.
1733 */
1734 public function testContactGetOldParamsOneMatch() {
1735 // Insert a row in civicrm_contact creating contact 17
1736 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1737 $op->execute($this->_dbconn,
1738 $this->createXMLDataSet(dirname(__FILE__) . '/dataset/contact_17.xml'
1739 )
1740 );
1741
1742 $params = array(
1743 'first_name' => 'Test',
1744 );
1745 $result = $this->callAPISuccess('contact', 'get', $params);
1746 $this->assertEquals(17, $result['values'][17]['contact_id']);
1747 $this->assertEquals(17, $result['id']);
1748 }
1749
1750 /**
1751 * Test civicrm_contact_search_count().
1752 */
1753 public function testContactGetEmail() {
1754 $params = array(
1755 'email' => 'man2@yahoo.com',
1756 'contact_type' => 'Individual',
1757 'location_type_id' => 1,
1758 );
1759
1760 $contact = $this->callAPISuccess('contact', 'create', $params);
1761
1762 $params = array(
1763 'email' => 'man2@yahoo.com',
1764 );
1765 $result = $this->callAPIAndDocument('contact', 'get', $params, __FUNCTION__, __FILE__);
1766 $this->assertEquals('man2@yahoo.com', $result['values'][$result['id']]['email']);
1767
1768 $this->callAPISuccess('contact', 'delete', $contact);
1769 }
1770
1771 /**
1772 * Ensure consistent return format for option group fields.
1773 */
1774 public function testSetPreferredCommunicationNull() {
1775 $contact = $this->callAPISuccess('contact', 'create', array_merge($this->_params, array(
1776 'preferred_communication_method' => array('Phone', 'SMS'),
1777 )));
1778 $preferredCommunicationMethod = $this->callAPISuccessGetValue('Contact', array(
1779 'id' => $contact['id'],
1780 'return' => 'preferred_communication_method',
1781 ));
1782 $this->assertNotEmpty($preferredCommunicationMethod);
1783 $contact = $this->callAPISuccess('contact', 'create', array_merge($this->_params, array(
1784 'preferred_communication_method' => 'null',
1785 'id' => $contact['id'],
1786 )));
1787 $preferredCommunicationMethod = $this->callAPISuccessGetValue('Contact', array(
1788 'id' => $contact['id'],
1789 'return' => 'preferred_communication_method',
1790 ));
1791 $this->assertEmpty($preferredCommunicationMethod);
1792 }
1793
1794 /**
1795 * Ensure consistent return format for option group fields.
1796 */
1797 public function testPseudoFields() {
1798 $params = array(
1799 'preferred_communication_method' => array('Phone', 'SMS'),
1800 'preferred_language' => 'en_US',
1801 'gender_id' => 'Female',
1802 'prefix_id' => 'Mrs.',
1803 'suffix_id' => 'II',
1804 'communication_style_id' => 'Formal',
1805 );
1806
1807 $contact = $this->callAPISuccess('contact', 'create', array_merge($this->_params, $params));
1808
1809 $result = $this->callAPISuccess('contact', 'getsingle', array('id' => $contact['id']));
1810 $this->assertEquals('Both', $result['preferred_mail_format']);
1811
1812 $this->assertEquals('en_US', $result['preferred_language']);
1813 $this->assertEquals(1, $result['communication_style_id']);
1814 $this->assertEquals(1, $result['gender_id']);
1815 $this->assertEquals('Female', $result['gender']);
1816 $this->assertEquals('Mrs.', $result['individual_prefix']);
1817 $this->assertEquals(1, $result['prefix_id']);
1818 $this->assertEquals('II', $result['individual_suffix']);
1819 $this->assertEquals(CRM_Core_PseudoConstant::getKey("CRM_Contact_BAO_Contact", 'suffix_id', 'II'), $result['suffix_id']);
1820 $this->callAPISuccess('contact', 'delete', $contact);
1821 $this->assertEquals(array(
1822 CRM_Core_PseudoConstant::getKey("CRM_Contact_BAO_Contact", 'preferred_communication_method', 'Phone'),
1823 CRM_Core_PseudoConstant::getKey("CRM_Contact_BAO_Contact", 'preferred_communication_method', 'SMS'),
1824 ), $result['preferred_communication_method']);
1825 }
1826
1827
1828 /**
1829 * Test birth date parameters.
1830 *
1831 * These include value, array & birth_date_high, birth_date_low
1832 * && deceased.
1833 */
1834 public function testContactGetBirthDate() {
1835 $contact1 = $this->callAPISuccess('contact', 'create', array_merge($this->_params, array('birth_date' => 'first day of next month - 2 years')));
1836 $contact2 = $this->callAPISuccess('contact', 'create', array_merge($this->_params, array('birth_date' => 'first day of next month - 5 years')));
1837 $contact3 = $this->callAPISuccess('contact', 'create', array_merge($this->_params, array('birth_date' => 'first day of next month -20 years')));
1838
1839 $result = $this->callAPISuccess('contact', 'get', array());
1840 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -2 years')), $result['values'][$contact1['id']]['birth_date']);
1841 $result = $this->callAPISuccess('contact', 'get', array('birth_date' => 'first day of next month -5 years'));
1842 $this->assertEquals(1, $result['count']);
1843 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -5 years')), $result['values'][$contact2['id']]['birth_date']);
1844 $result = $this->callAPISuccess('contact', 'get', array('birth_date_high' => date('Y-m-d', strtotime('-6 years'))));
1845 $this->assertEquals(1, $result['count']);
1846 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -20 years')), $result['values'][$contact3['id']]['birth_date']);
1847 $result = $this->callAPISuccess('contact', 'get', array(
1848 'birth_date_low' => date('Y-m-d', strtotime('-6 years')),
1849 'birth_date_high' => date('Y-m-d', strtotime('- 3 years')),
1850 ));
1851 $this->assertEquals(1, $result['count']);
1852 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -5 years')), $result['values'][$contact2['id']]['birth_date']);
1853 $result = $this->callAPISuccess('contact', 'get', array(
1854 'birth_date_low' => '-6 years',
1855 'birth_date_high' => '- 3 years',
1856 ));
1857 $this->assertEquals(1, $result['count']);
1858 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -5 years')), $result['values'][$contact2['id']]['birth_date']);
1859 }
1860
1861 /**
1862 * Test Address parameters
1863 *
1864 * This include state_province, state_province_name, country
1865 */
1866 public function testContactGetWithAddressFields() {
1867 $individuals = array(
1868 array(
1869 'first_name' => 'abc1',
1870 'contact_type' => 'Individual',
1871 'last_name' => 'xyz1',
1872 'api.address.create' => array(
1873 'country' => 'United States',
1874 'state_province_id' => 'Michigan',
1875 'location_type_id' => 1,
1876 ),
1877 ),
1878 array(
1879 'first_name' => 'abc2',
1880 'contact_type' => 'Individual',
1881 'last_name' => 'xyz2',
1882 'api.address.create' => array(
1883 'country' => 'United States',
1884 'state_province_id' => 'Alabama',
1885 'location_type_id' => 1,
1886 ),
1887 ),
1888 );
1889 foreach ($individuals as $params) {
1890 $contact = $this->callAPISuccess('contact', 'create', $params);
1891 }
1892
1893 // Check whether Contact get API return successfully with below Address params.
1894 $fieldsToTest = array(
1895 'state_province_name' => 'Michigan',
1896 'state_province' => 'Michigan',
1897 'country' => 'United States',
1898 'state_province_name' => array('IN' => array('Michigan', 'Alabama')),
1899 'state_province' => array('IN' => array('Michigan', 'Alabama')),
1900 );
1901 foreach ($fieldsToTest as $field => $value) {
1902 $getParams = array(
1903 'id' => $contact['id'],
1904 $field => $value,
1905 );
1906 $result = $this->callAPISuccess('Contact', 'get', $getParams);
1907 $this->assertEquals(1, $result['count']);
1908 }
1909 }
1910
1911 /**
1912 * Test Deceased date parameters.
1913 *
1914 * These include value, array & Deceased_date_high, Deceased date_low
1915 * && deceased.
1916 */
1917 public function testContactGetDeceasedDate() {
1918 $contact1 = $this->callAPISuccess('contact', 'create', array_merge($this->_params, array('deceased_date' => 'first day of next month - 2 years')));
1919 $contact2 = $this->callAPISuccess('contact', 'create', array_merge($this->_params, array('deceased_date' => 'first day of next month - 5 years')));
1920 $contact3 = $this->callAPISuccess('contact', 'create', array_merge($this->_params, array('deceased_date' => 'first day of next month -20 years')));
1921
1922 $result = $this->callAPISuccess('contact', 'get', array());
1923 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -2 years')), $result['values'][$contact1['id']]['deceased_date']);
1924 $result = $this->callAPISuccess('contact', 'get', array('deceased_date' => 'first day of next month -5 years'));
1925 $this->assertEquals(1, $result['count']);
1926 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -5 years')), $result['values'][$contact2['id']]['deceased_date']);
1927 $result = $this->callAPISuccess('contact', 'get', array('deceased_date_high' => date('Y-m-d', strtotime('-6 years'))));
1928 $this->assertEquals(1, $result['count']);
1929 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -20 years')), $result['values'][$contact3['id']]['deceased_date']);
1930 $result = $this->callAPISuccess('contact', 'get', array(
1931 'deceased_date_low' => '-6 years',
1932 'deceased_date_high' => date('Y-m-d', strtotime('- 3 years')),
1933 ));
1934 $this->assertEquals(1, $result['count']);
1935 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -5 years')), $result['values'][$contact2['id']]['deceased_date']);
1936 }
1937
1938 /**
1939 * Test for Contact.get id=@user:username.
1940 */
1941 public function testContactGetByUsername() {
1942 // Setup - create contact with a uf-match.
1943 $cid = $this->individualCreate(array(
1944 'contact_type' => 'Individual',
1945 'first_name' => 'testGetByUsername',
1946 'last_name' => 'testGetByUsername',
1947 ));
1948
1949 $ufMatchParams = array(
1950 'domain_id' => CRM_Core_Config::domainID(),
1951 'uf_id' => 99,
1952 'uf_name' => 'the-email-matching-key-is-not-really-the-username',
1953 'contact_id' => $cid,
1954 );
1955 $ufMatch = CRM_Core_BAO_UFMatch::create($ufMatchParams);
1956 $this->assertTrue(is_numeric($ufMatch->id));
1957
1958 // setup - mock the calls to CRM_Utils_System_*::getUfId
1959 $userSystem = $this->getMock('CRM_Utils_System_UnitTests', array('getUfId'));
1960 $userSystem->expects($this->once())
1961 ->method('getUfId')
1962 ->with($this->equalTo('exampleUser'))
1963 ->will($this->returnValue(99));
1964 CRM_Core_Config::singleton()->userSystem = $userSystem;
1965
1966 // perform a lookup
1967 $result = $this->callAPISuccess('Contact', 'get', array(
1968 'id' => '@user:exampleUser',
1969 ));
1970 $this->assertEquals('testGetByUsername', $result['values'][$cid]['first_name']);
1971 }
1972
1973 /**
1974 * Test to check return works OK.
1975 */
1976 public function testContactGetReturnValues() {
1977 $extraParams = array(
1978 'nick_name' => 'Bob',
1979 'phone' => '456',
1980 'email' => 'e@mail.com',
1981 );
1982 $contactID = $this->individualCreate($extraParams);
1983 //actually it turns out the above doesn't create a phone
1984 $this->callAPISuccess('phone', 'create', array('contact_id' => $contactID, 'phone' => '456'));
1985 $result = $this->callAPISuccess('contact', 'getsingle', array('id' => $contactID));
1986 foreach ($extraParams as $key => $value) {
1987 $this->assertEquals($result[$key], $value);
1988 }
1989 //now we check they are still returned with 'return' key
1990 $result = $this->callAPISuccess('contact', 'getsingle', array(
1991 'id' => $contactID,
1992 'return' => array_keys($extraParams),
1993 ));
1994 foreach ($extraParams as $key => $value) {
1995 $this->assertEquals($result[$key], $value);
1996 }
1997 }
1998
1999 /**
2000 * Test creating multiple phones using chaining.
2001 *
2002 * @throws \Exception
2003 */
2004 public function testCRM13252MultipleChainedPhones() {
2005 $contactID = $this->householdCreate();
2006 $this->callAPISuccessGetCount('phone', array('contact_id' => $contactID), 0);
2007 $params = array(
2008 'contact_id' => $contactID,
2009 'household_name' => 'Household 1',
2010 'contact_type' => 'Household',
2011 'api.phone.create' => array(
2012 0 => array(
2013 'phone' => '111-111-1111',
2014 'location_type_id' => 1,
2015 'phone_type_id' => 1,
2016 ),
2017 1 => array(
2018 'phone' => '222-222-2222',
2019 'location_type_id' => 1,
2020 'phone_type_id' => 2,
2021 ),
2022 ),
2023 );
2024 $this->callAPISuccess('contact', 'create', $params);
2025 $this->callAPISuccessGetCount('phone', array('contact_id' => $contactID), 2);
2026
2027 }
2028
2029 /**
2030 * Test for Contact.get id=@user:username (with an invalid username).
2031 */
2032 public function testContactGetByUnknownUsername() {
2033 // setup - mock the calls to CRM_Utils_System_*::getUfId
2034 $userSystem = $this->getMock('CRM_Utils_System_UnitTests', array('getUfId'));
2035 $userSystem->expects($this->once())
2036 ->method('getUfId')
2037 ->with($this->equalTo('exampleUser'))
2038 ->will($this->returnValue(NULL));
2039 CRM_Core_Config::singleton()->userSystem = $userSystem;
2040
2041 // perform a lookup
2042 $result = $this->callAPIFailure('Contact', 'get', array(
2043 'id' => '@user:exampleUser',
2044 ));
2045 $this->assertRegExp('/cannot be resolved to a contact ID/', $result['error_message']);
2046 }
2047
2048 /**
2049 * Verify attempt to create individual with chained arrays and sequential.
2050 */
2051 public function testGetIndividualWithChainedArraysAndSequential() {
2052 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__, __FILE__);
2053 $params['custom_' . $ids['custom_field_id']] = "custom string";
2054
2055 $moreIDs = $this->CustomGroupMultipleCreateWithFields();
2056 $params = array(
2057 'sequential' => 1,
2058 'first_name' => 'abc3',
2059 'last_name' => 'xyz3',
2060 'contact_type' => 'Individual',
2061 'email' => 'man3@yahoo.com',
2062 'api.website.create' => array(
2063 array(
2064 'url' => "http://civicrm.org",
2065 ),
2066 array(
2067 'url' => "https://civicrm.org",
2068 ),
2069 ),
2070 );
2071
2072 $result = $this->callAPISuccess('Contact', 'create', $params);
2073
2074 // delete the contact and custom groups
2075 $this->callAPISuccess('contact', 'delete', array('id' => $result['id']));
2076 $this->customGroupDelete($ids['custom_group_id']);
2077 $this->customGroupDelete($moreIDs['custom_group_id']);
2078
2079 $this->assertEquals($result['id'], $result['values'][0]['id']);
2080 $this->assertArrayKeyExists('api.website.create', $result['values'][0]);
2081 }
2082
2083 /**
2084 * Verify attempt to create individual with chained arrays.
2085 */
2086 public function testGetIndividualWithChainedArrays() {
2087 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__, __FILE__);
2088 $params['custom_' . $ids['custom_field_id']] = "custom string";
2089
2090 $moreIDs = $this->CustomGroupMultipleCreateWithFields();
2091 $description = "This demonstrates the usage of chained api functions.\nIn this case no notes or custom fields have been created.";
2092 $subfile = "APIChainedArray";
2093 $params = array(
2094 'first_name' => 'abc3',
2095 'last_name' => 'xyz3',
2096 'contact_type' => 'Individual',
2097 'email' => 'man3@yahoo.com',
2098 'api.contribution.create' => array(
2099 'receive_date' => '2010-01-01',
2100 'total_amount' => 100.00,
2101 'financial_type_id' => 1,
2102 'payment_instrument_id' => 1,
2103 'non_deductible_amount' => 10.00,
2104 'fee_amount' => 50.00,
2105 'net_amount' => 90.00,
2106 'trxn_id' => 12345,
2107 'invoice_id' => 67890,
2108 'source' => 'SSF',
2109 'contribution_status_id' => 1,
2110 ),
2111 'api.contribution.create.1' => array(
2112 'receive_date' => '2011-01-01',
2113 'total_amount' => 120.00,
2114 'financial_type_id' => $this->_financialTypeId = 1,
2115 'payment_instrument_id' => 1,
2116 'non_deductible_amount' => 10.00,
2117 'fee_amount' => 50.00,
2118 'net_amount' => 90.00,
2119 'trxn_id' => 12335,
2120 'invoice_id' => 67830,
2121 'source' => 'SSF',
2122 'contribution_status_id' => 1,
2123 ),
2124 'api.website.create' => array(
2125 array(
2126 'url' => "http://civicrm.org",
2127 ),
2128 ),
2129 );
2130
2131 $result = $this->callAPISuccess('Contact', 'create', $params);
2132 $params = array(
2133 'id' => $result['id'],
2134 'api.website.get' => array(),
2135 'api.Contribution.get' => array(
2136 'total_amount' => '120.00',
2137 ),
2138 'api.CustomValue.get' => 1,
2139 'api.Note.get' => 1,
2140 );
2141 $result = $this->callAPIAndDocument('Contact', 'Get', $params, __FUNCTION__, __FILE__, $description, $subfile);
2142 // delete the contact
2143 $this->callAPISuccess('contact', 'delete', $result);
2144 $this->customGroupDelete($ids['custom_group_id']);
2145 $this->customGroupDelete($moreIDs['custom_group_id']);
2146 $this->assertEquals(0, $result['values'][$result['id']]['api.website.get']['is_error']);
2147 $this->assertEquals("http://civicrm.org", $result['values'][$result['id']]['api.website.get']['values'][0]['url']);
2148 }
2149
2150 /**
2151 * Verify attempt to create individual with chained arrays and sequential.
2152 *
2153 * See https://issues.civicrm.org/jira/browse/CRM-15815
2154 */
2155 public function testCreateIndividualWithChainedArrayAndSequential() {
2156 $params = array(
2157 'sequential' => 1,
2158 'first_name' => 'abc5',
2159 'last_name' => 'xyz5',
2160 'contact_type' => 'Individual',
2161 'email' => 'woman5@yahoo.com',
2162 'api.phone.create' => array(
2163 array('phone' => '03-231 07 95'),
2164 array('phone' => '03-232 51 62'),
2165 ),
2166 'api.website.create' => array(
2167 'url' => 'http://civicrm.org',
2168 ),
2169 );
2170 $result = $this->callAPISuccess('Contact', 'create', $params);
2171
2172 // I could try to parse the result to see whether the two phone numbers
2173 // and the website are there, but I am not sure about the correct format.
2174 // So I will just fetch it again before checking.
2175 // See also http://forum.civicrm.org/index.php/topic,35393.0.html
2176 $params = array(
2177 'sequential' => 1,
2178 'id' => $result['id'],
2179 'api.website.get' => array(),
2180 'api.phone.get' => array(),
2181 );
2182 $result = $this->callAPISuccess('Contact', 'get', $params);
2183
2184 // delete the contact
2185 $this->callAPISuccess('contact', 'delete', $result);
2186
2187 $this->assertEquals(2, $result['values'][0]['api.phone.get']['count']);
2188 $this->assertEquals(1, $result['values'][0]['api.website.get']['count']);
2189 }
2190
2191 /**
2192 * Test retrieving an individual with chained array syntax.
2193 */
2194 public function testGetIndividualWithChainedArraysFormats() {
2195 $description = "This demonstrates the usage of chained api functions.\nIn this case no notes or custom fields have been created.";
2196 $subfile = "APIChainedArrayFormats";
2197 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__, __FILE__);
2198 $params['custom_' . $ids['custom_field_id']] = "custom string";
2199
2200 $moreIDs = $this->CustomGroupMultipleCreateWithFields();
2201 $params = array(
2202 'first_name' => 'abc3',
2203 'last_name' => 'xyz3',
2204 'contact_type' => 'Individual',
2205 'email' => 'man3@yahoo.com',
2206 'api.contribution.create' => array(
2207 'receive_date' => '2010-01-01',
2208 'total_amount' => 100.00,
2209 'financial_type_id' => $this->_financialTypeId,
2210 'payment_instrument_id' => 1,
2211 'non_deductible_amount' => 10.00,
2212 'fee_amount' => 50.00,
2213 'net_amount' => 90.00,
2214 'source' => 'SSF',
2215 'contribution_status_id' => 1,
2216 ),
2217 'api.contribution.create.1' => array(
2218 'receive_date' => '2011-01-01',
2219 'total_amount' => 120.00,
2220 'financial_type_id' => $this->_financialTypeId,
2221 'payment_instrument_id' => 1,
2222 'non_deductible_amount' => 10.00,
2223 'fee_amount' => 50.00,
2224 'net_amount' => 90.00,
2225 'source' => 'SSF',
2226 'contribution_status_id' => 1,
2227 ),
2228 'api.website.create' => array(
2229 array(
2230 'url' => "http://civicrm.org",
2231 ),
2232 ),
2233 );
2234
2235 $result = $this->callAPISuccess('Contact', 'create', $params);
2236 $params = array(
2237 'id' => $result['id'],
2238 'api.website.getValue' => array('return' => 'url'),
2239 'api.Contribution.getCount' => array(),
2240 'api.CustomValue.get' => 1,
2241 'api.Note.get' => 1,
2242 'api.Membership.getCount' => array(),
2243 );
2244 $result = $this->callAPIAndDocument('Contact', 'Get', $params, __FUNCTION__, __FILE__, $description, $subfile);
2245 $this->assertEquals(2, $result['values'][$result['id']]['api.Contribution.getCount']);
2246 $this->assertEquals(0, $result['values'][$result['id']]['api.Note.get']['is_error']);
2247 $this->assertEquals("http://civicrm.org", $result['values'][$result['id']]['api.website.getValue']);
2248
2249 $this->callAPISuccess('contact', 'delete', $result);
2250 $this->customGroupDelete($ids['custom_group_id']);
2251 $this->customGroupDelete($moreIDs['custom_group_id']);
2252 }
2253
2254 /**
2255 * Test complex chaining.
2256 */
2257 public function testGetIndividualWithChainedArraysAndMultipleCustom() {
2258 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__, __FILE__);
2259 $params['custom_' . $ids['custom_field_id']] = "custom string";
2260 $moreIDs = $this->CustomGroupMultipleCreateWithFields();
2261 $andMoreIDs = $this->CustomGroupMultipleCreateWithFields(array(
2262 'title' => "another group",
2263 'name' => 'another name',
2264 ));
2265 $description = "This demonstrates the usage of chained api functions with multiple custom fields.";
2266 $subfile = "APIChainedArrayMultipleCustom";
2267 $params = array(
2268 'first_name' => 'abc3',
2269 'last_name' => 'xyz3',
2270 'contact_type' => 'Individual',
2271 'email' => 'man3@yahoo.com',
2272 'api.contribution.create' => array(
2273 'receive_date' => '2010-01-01',
2274 'total_amount' => 100.00,
2275 'financial_type_id' => 1,
2276 'payment_instrument_id' => 1,
2277 'non_deductible_amount' => 10.00,
2278 'fee_amount' => 50.00,
2279 'net_amount' => 90.00,
2280 'trxn_id' => 12345,
2281 'invoice_id' => 67890,
2282 'source' => 'SSF',
2283 'contribution_status_id' => 1,
2284 ),
2285 'api.contribution.create.1' => array(
2286 'receive_date' => '2011-01-01',
2287 'total_amount' => 120.00,
2288 'financial_type_id' => 1,
2289 'payment_instrument_id' => 1,
2290 'non_deductible_amount' => 10.00,
2291 'fee_amount' => 50.00,
2292 'net_amount' => 90.00,
2293 'trxn_id' => 12335,
2294 'invoice_id' => 67830,
2295 'source' => 'SSF',
2296 'contribution_status_id' => 1,
2297 ),
2298 'api.website.create' => array(
2299 array(
2300 'url' => "http://civicrm.org",
2301 ),
2302 ),
2303 'custom_' . $ids['custom_field_id'] => "value 1",
2304 'custom_' . $moreIDs['custom_field_id'][0] => "value 2",
2305 'custom_' . $moreIDs['custom_field_id'][1] => "warm beer",
2306 'custom_' . $andMoreIDs['custom_field_id'][1] => "vegemite",
2307 );
2308
2309 $result = $this->callAPISuccess('Contact', 'create', $params);
2310 $result = $this->callAPISuccess('Contact', 'create', array(
2311 'contact_type' => 'Individual',
2312 'id' => $result['id'],
2313 'custom_' .
2314 $moreIDs['custom_field_id'][0] => "value 3",
2315 'custom_' .
2316 $ids['custom_field_id'] => "value 4",
2317 ));
2318
2319 $params = array(
2320 'id' => $result['id'],
2321 'api.website.getValue' => array('return' => 'url'),
2322 'api.Contribution.getCount' => array(),
2323 'api.CustomValue.get' => 1,
2324 );
2325 $result = $this->callAPIAndDocument('Contact', 'Get', $params, __FUNCTION__, __FILE__, $description, $subfile);
2326
2327 $this->customGroupDelete($ids['custom_group_id']);
2328 $this->customGroupDelete($moreIDs['custom_group_id']);
2329 $this->customGroupDelete($andMoreIDs['custom_group_id']);
2330 $this->assertEquals(0, $result['values'][$result['id']]['api.CustomValue.get']['is_error']);
2331 $this->assertEquals('http://civicrm.org', $result['values'][$result['id']]['api.website.getValue']);
2332 }
2333
2334 /**
2335 * Test checks usage of $values to pick & choose inputs.
2336 */
2337 public function testChainingValuesCreate() {
2338 $description = "This demonstrates the usage of chained api functions. Specifically it has one 'parent function' &
2339 2 child functions - one receives values from the parent (Contact) and the other child (Tag).";
2340 $subfile = "APIChainedArrayValuesFromSiblingFunction";
2341 $params = array(
2342 'display_name' => 'batman',
2343 'contact_type' => 'Individual',
2344 'api.tag.create' => array(
2345 'name' => '$value.id',
2346 'description' => '$value.display_name',
2347 'format.only_id' => 1,
2348 ),
2349 'api.entity_tag.create' => array('tag_id' => '$value.api.tag.create'),
2350 );
2351 $result = $this->callAPIAndDocument('Contact', 'Create', $params, __FUNCTION__, __FILE__, $description, $subfile);
2352 $this->assertEquals(0, $result['values'][$result['id']]['api.entity_tag.create']['is_error']);
2353
2354 $tablesToTruncate = array(
2355 'civicrm_contact',
2356 'civicrm_activity',
2357 'civicrm_entity_tag',
2358 'civicrm_tag',
2359 );
2360 $this->quickCleanup($tablesToTruncate, TRUE);
2361 }
2362
2363 /**
2364 * Test TrueFalse format - I couldn't come up with an easy way to get an error on Get.
2365 */
2366 public function testContactGetFormatIsSuccessTrue() {
2367 $this->createContactFromXML();
2368 $description = "This demonstrates use of the 'format.is_success' param.
2369 This param causes only the success or otherwise of the function to be returned as BOOLEAN";
2370 $subfile = "FormatIsSuccess_True";
2371 $params = array('id' => 17, 'format.is_success' => 1);
2372 $result = $this->callAPIAndDocument('Contact', 'Get', $params, __FUNCTION__, __FILE__, $description, $subfile);
2373 $this->assertEquals(1, $result);
2374 $this->callAPISuccess('Contact', 'Delete', $params);
2375 }
2376
2377 /**
2378 * Test TrueFalse format.
2379 */
2380 public function testContactCreateFormatIsSuccessFalse() {
2381
2382 $description = "This demonstrates use of the 'format.is_success' param.
2383 This param causes only the success or otherwise of the function to be returned as BOOLEAN";
2384 $subfile = "FormatIsSuccess_Fail";
2385 $params = array('id' => 500, 'format.is_success' => 1);
2386 $result = $this->callAPIAndDocument('Contact', 'Create', $params, __FUNCTION__, __FILE__, $description, $subfile);
2387 $this->assertEquals(0, $result);
2388 }
2389
2390 /**
2391 * Test long display names.
2392 *
2393 * CRM-21258
2394 */
2395 public function testContactCreateLongDisplayName() {
2396 $result = $this->callAPISuccess('Contact', 'Create', array(
2397 'first_name' => str_pad('a', 64, 'a'),
2398 'last_name' => str_pad('a', 64, 'a'),
2399 'contact_type' => 'Individual',
2400 ));
2401 $this->assertEquals('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', $result['values'][$result['id']]['display_name']);
2402 $this->assertEquals('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', $result['values'][$result['id']]['sort_name']);
2403 }
2404
2405 /**
2406 * Test Single Entity format.
2407 */
2408 public function testContactGetSingleEntityArray() {
2409 $this->createContactFromXML();
2410 $description = "This demonstrates use of the 'format.single_entity_array' param.
2411 This param causes the only contact to be returned as an array without the other levels.
2412 It will be ignored if there is not exactly 1 result";
2413 $subfile = "GetSingleContact";
2414 $params = array('id' => 17);
2415 $result = $this->callAPIAndDocument('Contact', 'GetSingle', $params, __FUNCTION__, __FILE__, $description, $subfile);
2416 $this->assertEquals('Test Contact', $result['display_name']);
2417 $this->callAPISuccess('Contact', 'Delete', $params);
2418 }
2419
2420 /**
2421 * Test Single Entity format.
2422 */
2423 public function testContactGetFormatCountOnly() {
2424 $this->createContactFromXML();
2425 $description = "This demonstrates use of the 'getCount' action.
2426 This param causes the count of the only function to be returned as an integer.";
2427 $params = array('id' => 17);
2428 $result = $this->callAPIAndDocument('Contact', 'GetCount', $params, __FUNCTION__, __FILE__, $description,
2429 'GetCountContact');
2430 $this->assertEquals('1', $result);
2431 $this->callAPISuccess('Contact', 'Delete', $params);
2432 }
2433
2434 /**
2435 * Test id only format.
2436 */
2437 public function testContactGetFormatIDOnly() {
2438 $this->createContactFromXML();
2439 $description = "This demonstrates use of the 'format.id_only' param.
2440 This param causes the id of the only entity to be returned as an integer.
2441 It will be ignored if there is not exactly 1 result";
2442 $subfile = "FormatOnlyID";
2443 $params = array('id' => 17, 'format.only_id' => 1);
2444 $result = $this->callAPIAndDocument('Contact', 'Get', $params, __FUNCTION__, __FILE__, $description, $subfile);
2445 $this->assertEquals('17', $result);
2446 $this->callAPISuccess('Contact', 'Delete', $params);
2447 }
2448
2449 /**
2450 * Test id only format.
2451 */
2452 public function testContactGetFormatSingleValue() {
2453 $this->createContactFromXML();
2454 $description = "This demonstrates use of the 'format.single_value' param.
2455 This param causes only a single value of the only entity to be returned as an string.
2456 It will be ignored if there is not exactly 1 result";
2457 $subFile = "FormatSingleValue";
2458 $params = array('id' => 17, 'return' => 'display_name');
2459 $result = $this->callAPIAndDocument('Contact', 'getvalue', $params, __FUNCTION__, __FILE__, $description, $subFile);
2460 $this->assertEquals('Test Contact', $result);
2461 $this->callAPISuccess('Contact', 'Delete', $params);
2462 }
2463
2464 /**
2465 * Test that permissions are respected when creating contacts.
2466 */
2467 public function testContactCreationPermissions() {
2468 $params = array(
2469 'contact_type' => 'Individual',
2470 'first_name' => 'Foo',
2471 'last_name' => 'Bear',
2472 'check_permissions' => TRUE,
2473 );
2474 $config = CRM_Core_Config::singleton();
2475 $config->userPermissionClass->permissions = array('access CiviCRM');
2476 $result = $this->callAPIFailure('contact', 'create', $params);
2477 $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');
2478
2479 $config->userPermissionClass->permissions = array('access CiviCRM', 'add contacts', 'import contacts');
2480 $this->callAPISuccess('contact', 'create', $params);
2481 }
2482
2483 /**
2484 * Test that delete with skip undelete respects permissions.
2485 */
2486 public function testContactDeletePermissions() {
2487 $contactID = $this->individualCreate();
2488 CRM_Core_Config::singleton()->userPermissionClass->permissions = array('access CiviCRM');
2489 $this->callAPIFailure('Contact', 'delete', array(
2490 'id' => $contactID,
2491 'check_permissions' => 1,
2492 'skip_undelete' => 1,
2493 ));
2494 $this->callAPISuccess('Contact', 'delete', array(
2495 'id' => $contactID,
2496 'check_permissions' => 0,
2497 'skip_undelete' => 1,
2498 ));
2499 }
2500
2501 /**
2502 * Test update with check permissions set.
2503 */
2504 public function testContactUpdatePermissions() {
2505 $params = array(
2506 'contact_type' => 'Individual',
2507 'first_name' => 'Foo',
2508 'last_name' => 'Bear',
2509 'check_permissions' => TRUE,
2510 );
2511 $result = $this->callAPISuccess('contact', 'create', $params);
2512 $config = CRM_Core_Config::singleton();
2513 $params = array(
2514 'id' => $result['id'],
2515 'contact_type' => 'Individual',
2516 'last_name' => 'Bar',
2517 'check_permissions' => TRUE,
2518 );
2519
2520 $config->userPermissionClass->permissions = array('access CiviCRM');
2521 $result = $this->callAPIFailure('contact', 'update', $params);
2522 $this->assertEquals('Permission denied to modify contact record', $result['error_message']);
2523
2524 $config->userPermissionClass->permissions = array(
2525 'access CiviCRM',
2526 'add contacts',
2527 'view all contacts',
2528 'edit all contacts',
2529 'import contacts',
2530 );
2531 $this->callAPISuccess('contact', 'update', $params);
2532 }
2533
2534 /**
2535 * Set up helper to create a contact.
2536 */
2537 public function createContactFromXML() {
2538 // Insert a row in civicrm_contact creating contact 17.
2539 $op = new PHPUnit_Extensions_Database_Operation_Insert();
2540 $op->execute($this->_dbconn,
2541 $this->createXMLDataSet(
2542 dirname(__FILE__) . '/dataset/contact_17.xml'
2543 )
2544 );
2545 }
2546
2547 /**
2548 * Test contact proximity api.
2549 */
2550 public function testContactProximity() {
2551 // first create a contact with a SF location with a specific
2552 // geocode
2553 $contactID = $this->organizationCreate();
2554
2555 // now create the address
2556 $params = array(
2557 'street_address' => '123 Main Street',
2558 'city' => 'San Francisco',
2559 'is_primary' => 1,
2560 'country_id' => 1228,
2561 'state_province_id' => 1004,
2562 'geo_code_1' => '37.79',
2563 'geo_code_2' => '-122.40',
2564 'location_type_id' => 1,
2565 'contact_id' => $contactID,
2566 );
2567
2568 $result = $this->callAPISuccess('address', 'create', $params);
2569 $this->assertEquals(1, $result['count']);
2570
2571 // now do a proximity search with a close enough geocode and hope to match
2572 // that specific contact only!
2573 $proxParams = array(
2574 'latitude' => 37.7,
2575 'longitude' => -122.3,
2576 'unit' => 'mile',
2577 'distance' => 10,
2578 );
2579 $result = $this->callAPISuccess('contact', 'proximity', $proxParams);
2580 $this->assertEquals(1, $result['count']);
2581 }
2582
2583 /**
2584 * Test that Ajax API permission is sufficient to access getquick api.
2585 *
2586 * (note that getquick api is required for autocomplete & has ACL permissions applied)
2587 */
2588 public function testGetquickPermissionCRM13744() {
2589 CRM_Core_Config::singleton()->userPermissionClass->permissions = array('access CiviEvent');
2590 $this->callAPIFailure('contact', 'getquick', array('name' => 'b', 'check_permissions' => TRUE));
2591 CRM_Core_Config::singleton()->userPermissionClass->permissions = array('access CiviCRM');
2592 $this->callAPISuccess('contact', 'getquick', array('name' => 'b', 'check_permissions' => TRUE));
2593 CRM_Core_Config::singleton()->userPermissionClass->permissions = array('access AJAX API');
2594 $this->callAPISuccess('contact', 'getquick', array('name' => 'b', 'check_permissions' => TRUE));
2595 }
2596
2597 /**
2598 * Test that getquick returns contacts with an exact first name match first.
2599 *
2600 * The search string 'b' & 'bob' both return ordered by sort_name if includeOrderByClause
2601 * is true (default) but if it is false then matches are returned in ID order.
2602 *
2603 * @dataProvider getSearchSortOptions
2604 */
2605 public function testGetQuickExactFirst($searchParameters, $settings, $firstContact, $secondContact = NULL) {
2606 $this->getQuickSearchSampleData();
2607 $this->callAPISuccess('Setting', 'create', $settings);
2608 $result = $this->callAPISuccess('contact', 'getquick', $searchParameters);
2609 $this->assertEquals($firstContact, $result['values'][0]['sort_name']);
2610 $this->assertEquals($secondContact, $result['values'][1]['sort_name']);
2611 $this->callAPISuccess('Setting', 'create', array('includeWildCardInName' => TRUE, 'includeOrderByClause' => TRUE));
2612 }
2613
2614 public function getSearchSortOptions() {
2615 $firstAlphabeticalContactBySortName = 'A Bobby, Bobby';
2616 $secondAlphabeticalContactBySortName = 'Aadvark, Bob';
2617 $secondAlphabeticalContactWithEmailBySortName = 'Bob, Bob';
2618 $firstAlphabeticalContactFirstNameBob = 'Aadvark, Bob';
2619 $secondAlphabeticalContactFirstNameBob = 'Bob, Bob';
2620 $firstByIDContactFirstNameBob = 'Bob, Bob';
2621 $secondByIDContactFirstNameBob = 'K Bobby, Bob';
2622 $firstContactByID = 'Bob, Bob';
2623 $secondContactByID = 'E Bobby, Bobby';
2624 $bobLikeEmail = 'A Bobby, Bobby';
2625
2626 return array(
2627 'empty_search_basic' => array(
2628 'search_parameters' => array('name' => '%'),
2629 'settings' => array('includeWildCardInName' => TRUE, 'includeOrderByClause' => TRUE),
2630 'first_contact' => $firstAlphabeticalContactBySortName,
2631 'second_contact' => $secondAlphabeticalContactBySortName,
2632 ),
2633 'empty_search_basic_no_wildcard' => array(
2634 'search_parameters' => array('name' => '%'),
2635 'settings' => array('includeWildCardInName' => FALSE, 'includeOrderByClause' => TRUE),
2636 'first_contact' => $firstAlphabeticalContactBySortName,
2637 'second_contact' => $secondAlphabeticalContactBySortName,
2638 ),
2639 'single_letter_search_basic' => array(
2640 'search_parameters' => array('name' => 'b'),
2641 'settings' => array('includeWildCardInName' => TRUE, 'includeOrderByClause' => TRUE),
2642 'first_contact' => $firstAlphabeticalContactBySortName,
2643 'second_contact' => $secondAlphabeticalContactBySortName,
2644 ),
2645 'bob_search_basic' => array(
2646 'search_parameters' => array('name' => 'bob'),
2647 'settings' => array('includeWildCardInName' => TRUE, 'includeOrderByClause' => TRUE),
2648 'first_contact' => $firstAlphabeticalContactBySortName,
2649 'second_contact' => $secondAlphabeticalContactBySortName,
2650 ),
2651 'bob_search_no_orderby' => array(
2652 'search_parameters' => array('name' => 'bob'),
2653 'settings' => array('includeWildCardInName' => TRUE, 'includeOrderByClause' => FALSE),
2654 'first_contact' => $firstContactByID,
2655 'second_contact' => $secondContactByID,
2656 ),
2657 'bob_search_no_wildcard' => array(
2658 'search_parameters' => array('name' => 'bob'),
2659 'settings' => array('includeWildCardInName' => FALSE, 'includeOrderByClause' => TRUE),
2660 'second_contact' => $bobLikeEmail,
2661 'first_contact' => $secondAlphabeticalContactFirstNameBob,
2662 ),
2663 // This should be the same as just no wildcard as if we had an exactMatch while searching by
2664 // sort name it would rise to the top CRM-19547
2665 'bob_search_no_wildcard_no_orderby' => array(
2666 'search_parameters' => array('name' => 'bob'),
2667 'settings' => array('includeWildCardInName' => FALSE, 'includeOrderByClause' => TRUE),
2668 'second_contact' => $bobLikeEmail,
2669 'first_contact' => $secondAlphabeticalContactFirstNameBob,
2670 ),
2671 'first_name_search_basic' => array(
2672 'search_parameters' => array('name' => 'bob', 'field_name' => 'first_name'),
2673 'settings' => array('includeWildCardInName' => TRUE, 'includeOrderByClause' => TRUE),
2674 'first_contact' => $firstAlphabeticalContactFirstNameBob,
2675 'second_contact' => $secondAlphabeticalContactFirstNameBob,
2676 ),
2677 'first_name_search_no_wildcard' => array(
2678 'search_parameters' => array('name' => 'bob', 'field_name' => 'first_name'),
2679 'settings' => array('includeWildCardInName' => FALSE, 'includeOrderByClause' => TRUE),
2680 'first_contact' => $firstAlphabeticalContactFirstNameBob,
2681 'second_contact' => $secondAlphabeticalContactFirstNameBob,
2682 ),
2683 'first_name_search_no_orderby' => array(
2684 'search_parameters' => array('name' => 'bob', 'field_name' => 'first_name'),
2685 'settings' => array('includeWildCardInName' => TRUE, 'includeOrderByClause' => FALSE),
2686 'first_contact' => $firstByIDContactFirstNameBob,
2687 'second_contact' => $secondByIDContactFirstNameBob,
2688 ),
2689 'email_search_basic' => array(
2690 'search_parameters' => array('name' => 'bob', 'field_name' => 'email', 'table_name' => 'eml'),
2691 'settings' => array('includeWildCardInName' => FALSE, 'includeOrderByClause' => TRUE),
2692 'first_contact' => $firstAlphabeticalContactBySortName,
2693 'second_contact' => $secondAlphabeticalContactWithEmailBySortName,
2694 ),
2695 );
2696 }
2697
2698 /**
2699 * Test that getquick returns contacts with an exact first name match first.
2700 */
2701 public function testGetQuickEmail() {
2702 $this->getQuickSearchSampleData();
2703 $loggedInContactID = $this->createLoggedInUser();
2704 $result = $this->callAPISuccess('contact', 'getquick', array(
2705 'name' => 'c',
2706 ));
2707 $expectedData = array(
2708 'A Bobby, Bobby :: bob@bobby.com',
2709 'Bob, Bob :: bob@bob.com',
2710 'C Bobby, Bobby',
2711 'H Bobby, Bobby :: bob@h.com',
2712 'Second Domain',
2713 $this->callAPISuccessGetValue('Contact', array('id' => $loggedInContactID, 'return' => 'last_name')) . ', Logged In :: anthony_anderson@civicrm.org',
2714 );
2715 $this->assertEquals(6, $result['count']);
2716 foreach ($expectedData as $index => $value) {
2717 $this->assertEquals($value, $result['values'][$index]['data']);
2718 }
2719 $result = $this->callAPISuccess('contact', 'getquick', array(
2720 'name' => 'h.',
2721 ));
2722 $expectedData = array(
2723 'H Bobby, Bobby :: bob@h.com',
2724 );
2725 foreach ($expectedData as $index => $value) {
2726 $this->assertEquals($value, $result['values'][$index]['data']);
2727 }
2728 $this->callAPISuccess('Setting', 'create', array('includeWildCardInName' => FALSE));
2729 $result = $this->callAPISuccess('contact', 'getquick', array(
2730 'name' => 'h.',
2731 ));
2732 $this->callAPISuccess('Setting', 'create', array('includeWildCardInName' => TRUE));
2733 $this->assertEquals(0, $result['count']);
2734 }
2735
2736 /**
2737 * Test that getquick returns contacts with an exact first name match first.
2738 */
2739 public function testGetQuickEmailACL() {
2740 $this->getQuickSearchSampleData();
2741 $loggedInContactID = $this->createLoggedInUser();
2742 CRM_Core_Config::singleton()->userPermissionClass->permissions = array();
2743 $result = $this->callAPISuccess('contact', 'getquick', array(
2744 'name' => 'c',
2745 ));
2746 $this->assertEquals(0, $result['count']);
2747
2748 $this->hookClass->setHook('civicrm_aclWhereClause', array($this, 'aclWhereNoBobH'));
2749 CRM_Contact_BAO_Contact_Permission::cache($loggedInContactID, CRM_Core_Permission::VIEW, TRUE);
2750 $result = $this->callAPISuccess('contact', 'getquick', array(
2751 'name' => 'c',
2752 ));
2753
2754 // Without the acl it would be 6 like the previous email getquick test.
2755 $this->assertEquals(5, $result['count']);
2756 $expectedData = array(
2757 'A Bobby, Bobby :: bob@bobby.com',
2758 'Bob, Bob :: bob@bob.com',
2759 'C Bobby, Bobby',
2760 'Second Domain',
2761 $this->callAPISuccessGetValue('Contact', array('id' => $loggedInContactID, 'return' => 'last_name')) . ', Logged In :: anthony_anderson@civicrm.org',
2762 );
2763 foreach ($expectedData as $index => $value) {
2764 $this->assertEquals($value, $result['values'][$index]['data']);
2765 }
2766 }
2767
2768 /**
2769 * Test that getquick returns contacts with an exact first name match first.
2770 */
2771 public function testGetQuickExternalID() {
2772 $this->getQuickSearchSampleData();
2773 $result = $this->callAPISuccess('contact', 'getquick', array(
2774 'name' => 'b',
2775 'field_name' => 'external_identifier',
2776 'table_name' => 'cc',
2777 ));
2778 $this->assertEquals(0, $result['count']);
2779 $result = $this->callAPISuccess('contact', 'getquick', array(
2780 'name' => 'abc',
2781 'field_name' => 'external_identifier',
2782 'table_name' => 'cc',
2783 ));
2784 $this->assertEquals(1, $result['count']);
2785 $this->assertEquals('Bob, Bob', $result['values'][0]['sort_name']);
2786 }
2787
2788 /**
2789 * Test that getquick returns contacts with an exact first name match first.
2790 */
2791 public function testGetQuickID() {
2792 $max = CRM_Core_DAO::singleValueQuery("SELECT max(id) FROM civicrm_contact");
2793 $this->getQuickSearchSampleData();
2794 $result = $this->callAPISuccess('contact', 'getquick', array(
2795 'name' => $max + 2,
2796 'field_name' => 'id',
2797 'table_name' => 'cc',
2798 ));
2799 $this->assertEquals(1, $result['count']);
2800 $this->assertEquals('E Bobby, Bobby', $result['values'][0]['sort_name']);
2801 $result = $this->callAPISuccess('contact', 'getquick', array(
2802 'name' => $max + 2,
2803 'field_name' => 'contact_id',
2804 'table_name' => 'cc',
2805 ));
2806 $this->assertEquals(1, $result['count']);
2807 $this->assertEquals('E Bobby, Bobby', $result['values'][0]['sort_name']);
2808 }
2809
2810 /**
2811 * Test that getquick returns contacts with an exact first name match first.
2812 *
2813 * Depending on the setting the sort name sort might click in next or not - test!
2814 */
2815 public function testGetQuickFirstName() {
2816 $this->getQuickSearchSampleData();
2817 $this->callAPISuccess('Setting', 'create', array('includeOrderByClause' => TRUE));
2818 $result = $this->callAPISuccess('contact', 'getquick', array(
2819 'name' => 'Bob',
2820 'field_name' => 'first_name',
2821 'table_name' => 'cc',
2822 ));
2823 $expected = array(
2824 'Aadvark, Bob',
2825 'Bob, Bob',
2826 'K Bobby, Bob',
2827 'A Bobby, Bobby',
2828 );
2829
2830 foreach ($expected as $index => $value) {
2831 $this->assertEquals($value, $result['values'][$index]['sort_name']);
2832 }
2833 $this->callAPISuccess('Setting', 'create', array('includeOrderByClause' => FALSE));
2834 $result = $this->callAPISuccess('contact', 'getquick', array('name' => 'bob'));
2835 $this->assertEquals('Bob, Bob', $result['values'][0]['sort_name']);
2836 $this->assertEquals('E Bobby, Bobby', $result['values'][1]['sort_name']);
2837 }
2838
2839 /**
2840 * Test that getquick applies ACLs.
2841 */
2842 public function testGetQuickFirstNameACLs() {
2843 $this->getQuickSearchSampleData();
2844 $userID = $this->createLoggedInUser();
2845 $this->callAPISuccess('Setting', 'create', array('includeOrderByClause' => TRUE, 'search_autocomplete_count' => 15));
2846 CRM_Core_Config::singleton()->userPermissionClass->permissions = array();
2847 $result = $this->callAPISuccess('contact', 'getquick', array(
2848 'name' => 'Bob',
2849 'field_name' => 'first_name',
2850 'table_name' => 'cc',
2851 ));
2852 $this->assertEquals(0, $result['count']);
2853
2854 $this->hookClass->setHook('civicrm_aclWhereClause', array($this, 'aclWhereNoBobH'));
2855 CRM_Contact_BAO_Contact_Permission::cache($userID, CRM_Core_Permission::VIEW, TRUE);
2856 $result = $this->callAPISuccess('contact', 'getquick', array(
2857 'name' => 'Bob',
2858 'field_name' => 'first_name',
2859 'table_name' => 'cc',
2860 ));
2861 $this->assertEquals('K Bobby, Bob', $result['values'][2]['sort_name']);
2862 // Without the ACL 9 would be bob@h.com.
2863 $this->assertEquals('I Bobby, Bobby', $result['values'][10]['sort_name']);
2864 }
2865
2866 /**
2867 * Full results returned.
2868 * @implements CRM_Utils_Hook::aclWhereClause
2869 *
2870 * @param string $type
2871 * @param array $tables
2872 * @param array $whereTables
2873 * @param int $contactID
2874 * @param string $where
2875 */
2876 public function aclWhereNoBobH($type, &$tables, &$whereTables, &$contactID, &$where) {
2877 $where = " (email <> 'bob@h.com' OR email IS NULL) ";
2878 $whereTables['civicrm_email'] = "LEFT JOIN civicrm_email e ON contact_a.id = e.contact_id";
2879 }
2880
2881 /**
2882 * Test that getquick returns contacts with an exact last name match first.
2883 */
2884 public function testGetQuickLastName() {
2885 $this->getQuickSearchSampleData();
2886 $this->callAPISuccess('Setting', 'create', array('includeOrderByClause' => TRUE));
2887 $result = $this->callAPISuccess('contact', 'getquick', array(
2888 'name' => 'Bob',
2889 'field_name' => 'last_name',
2890 'table_name' => 'cc',
2891 ));
2892 $expected = array(
2893 'Bob, Bob',
2894 'A Bobby, Bobby',
2895 'B Bobby, Bobby',
2896 );
2897
2898 foreach ($expected as $index => $value) {
2899 $this->assertEquals($value, $result['values'][$index]['sort_name']);
2900 }
2901 $this->callAPISuccess('Setting', 'create', array('includeOrderByClause' => FALSE));
2902 $result = $this->callAPISuccess('contact', 'getquick', array('name' => 'bob'));
2903 $this->assertEquals('Bob, Bob :: bob@bob.com', $result['values'][0]['data']);
2904 }
2905
2906 /**
2907 * Test that getquick returns contacts by city.
2908 */
2909 public function testGetQuickCity() {
2910 $this->getQuickSearchSampleData();
2911 $result = $this->callAPISuccess('contact', 'getquick', array(
2912 'name' => 'o',
2913 'field_name' => 'city',
2914 'table_name' => 'sts',
2915 ));
2916 $this->assertEquals('B Bobby, Bobby :: Toronto', $result['values'][0]['data']);
2917 $result = $this->callAPISuccess('contact', 'getquick', array(
2918 'name' => 'n',
2919 'field_name' => 'city',
2920 'table_name' => 'sts',
2921 ));
2922 $this->assertEquals('B Bobby, Bobby :: Toronto', $result['values'][0]['data']);
2923 $this->assertEquals('C Bobby, Bobby :: Whanganui', $result['values'][1]['data']);
2924 }
2925
2926 /**
2927 * Set up some sample data for testing quicksearch.
2928 */
2929 public function getQuickSearchSampleData() {
2930 $contacts = array(
2931 array('first_name' => 'Bob', 'last_name' => 'Bob', 'external_identifier' => 'abc', 'email' => 'bob@bob.com'),
2932 array('first_name' => 'Bobby', 'last_name' => 'E Bobby', 'external_identifier' => 'abcd'),
2933 array(
2934 'first_name' => 'Bobby',
2935 'last_name' => 'B Bobby',
2936 'external_identifier' => 'bcd',
2937 'api.address.create' => array(
2938 'street_address' => 'Sesame Street',
2939 'city' => 'Toronto',
2940 'location_type_id' => 1,
2941 ),
2942 ),
2943 array(
2944 'first_name' => 'Bobby',
2945 'last_name' => 'C Bobby',
2946 'external_identifier' => 'bcde',
2947 'api.address.create' => array(
2948 'street_address' => 'Te huarahi',
2949 'city' => 'Whanganui',
2950 'location_type_id' => 1,
2951 ),
2952 ),
2953 array('first_name' => 'Bobby', 'last_name' => 'D Bobby', 'external_identifier' => 'efg'),
2954 array('first_name' => 'Bobby', 'last_name' => 'A Bobby', 'external_identifier' => 'hij', 'email' => 'bob@bobby.com'),
2955 array('first_name' => 'Bobby', 'last_name' => 'F Bobby', 'external_identifier' => 'klm'),
2956 array('first_name' => 'Bobby', 'last_name' => 'G Bobby', 'external_identifier' => 'nop'),
2957 array('first_name' => 'Bobby', 'last_name' => 'H Bobby', 'external_identifier' => 'qrs', 'email' => 'bob@h.com'),
2958 array('first_name' => 'Bobby', 'last_name' => 'I Bobby'),
2959 array('first_name' => 'Bobby', 'last_name' => 'J Bobby'),
2960 array('first_name' => 'Bob', 'last_name' => 'K Bobby', 'external_identifier' => 'bcdef'),
2961 array('first_name' => 'Bob', 'last_name' => 'Aadvark'),
2962 );
2963 foreach ($contacts as $type => $contact) {
2964 $contact['contact_type'] = 'Individual';
2965 $this->callAPISuccess('Contact', 'create', $contact);
2966 }
2967 }
2968
2969 /**
2970 * Test get ref api - gets a list of references to an entity.
2971 */
2972 public function testGetReferenceCounts() {
2973 $result = $this->callAPISuccess('Contact', 'create', array(
2974 'first_name' => 'Testily',
2975 'last_name' => 'McHaste',
2976 'contact_type' => 'Individual',
2977 'api.Address.replace' => array(
2978 'values' => array(),
2979 ),
2980 'api.Email.replace' => array(
2981 'values' => array(
2982 array(
2983 'email' => 'spam@dev.null',
2984 'is_primary' => 0,
2985 'location_type_id' => 1,
2986 ),
2987 ),
2988 ),
2989 'api.Phone.replace' => array(
2990 'values' => array(
2991 array(
2992 'phone' => '234-567-0001',
2993 'is_primary' => 1,
2994 'location_type_id' => 1,
2995 ),
2996 array(
2997 'phone' => '234-567-0002',
2998 'is_primary' => 0,
2999 'location_type_id' => 1,
3000 ),
3001 ),
3002 ),
3003 ));
3004
3005 //$dao = new CRM_Contact_BAO_Contact();
3006 //$dao->id = $result['id'];
3007 //$this->assertTrue((bool) $dao->find(TRUE));
3008 //
3009 //$refCounts = $dao->getReferenceCounts();
3010 //$this->assertTrue(is_array($refCounts));
3011 //$refCountsIdx = CRM_Utils_Array::index(array('name'), $refCounts);
3012
3013 $refCounts = $this->callAPISuccess('Contact', 'getrefcount', array(
3014 'id' => $result['id'],
3015 ));
3016 $refCountsIdx = CRM_Utils_Array::index(array('name'), $refCounts['values']);
3017
3018 $this->assertEquals(1, $refCountsIdx['sql:civicrm_email:contact_id']['count']);
3019 $this->assertEquals('civicrm_email', $refCountsIdx['sql:civicrm_email:contact_id']['table']);
3020 $this->assertEquals(2, $refCountsIdx['sql:civicrm_phone:contact_id']['count']);
3021 $this->assertEquals('civicrm_phone', $refCountsIdx['sql:civicrm_phone:contact_id']['table']);
3022 $this->assertTrue(!isset($refCountsIdx['sql:civicrm_address:contact_id']));
3023 }
3024
3025 /**
3026 * Test the use of sql operators.
3027 */
3028 public function testSQLOperatorsOnContactAPI() {
3029 $this->individualCreate();
3030 $this->organizationCreate();
3031 $this->householdCreate();
3032 $contacts = $this->callAPISuccess('contact', 'get', array('legal_name' => array('IS NOT NULL' => TRUE)));
3033 $this->assertEquals($contacts['count'], CRM_Core_DAO::singleValueQuery('select count(*) FROM civicrm_contact WHERE legal_name IS NOT NULL'));
3034 $contacts = $this->callAPISuccess('contact', 'get', array('legal_name' => array('IS NULL' => TRUE)));
3035 $this->assertEquals($contacts['count'], CRM_Core_DAO::singleValueQuery('select count(*) FROM civicrm_contact WHERE legal_name IS NULL'));
3036 }
3037
3038 /**
3039 * CRM-14743 - test api respects search operators.
3040 */
3041 public function testGetModifiedDateByOperators() {
3042 $preExistingContactCount = CRM_Core_DAO::singleValueQuery('select count(*) FROM civicrm_contact');
3043 $contact1 = $this->individualCreate();
3044 $sql = "UPDATE civicrm_contact SET created_date = '2012-01-01', modified_date = '2013-01-01' WHERE id = " . $contact1;
3045 CRM_Core_DAO::executeQuery($sql);
3046 $contact2 = $this->individualCreate();
3047 $sql = "UPDATE civicrm_contact SET created_date = '2012-02-01', modified_date = '2013-02-01' WHERE id = " . $contact2;
3048 CRM_Core_DAO::executeQuery($sql);
3049 $contact3 = $this->householdCreate();
3050 $sql = "UPDATE civicrm_contact SET created_date = '2012-03-01', modified_date = '2013-03-01' WHERE id = " . $contact3;
3051 CRM_Core_DAO::executeQuery($sql);
3052 $contacts = $this->callAPISuccess('contact', 'get', array('modified_date' => array('<' => '2014-01-01')));
3053 $this->assertEquals($contacts['count'], 3);
3054 $contacts = $this->callAPISuccess('contact', 'get', array('modified_date' => array('>' => '2014-01-01')));
3055 $this->assertEquals($contacts['count'], $preExistingContactCount);
3056 }
3057
3058 /**
3059 * CRM-14743 - test api respects search operators.
3060 */
3061 public function testGetCreatedDateByOperators() {
3062 $preExistingContactCount = CRM_Core_DAO::singleValueQuery('select count(*) FROM civicrm_contact');
3063 $contact1 = $this->individualCreate();
3064 $sql = "UPDATE civicrm_contact SET created_date = '2012-01-01' WHERE id = " . $contact1;
3065 CRM_Core_DAO::executeQuery($sql);
3066 $contact2 = $this->individualCreate();
3067 $sql = "UPDATE civicrm_contact SET created_date = '2012-02-01' WHERE id = " . $contact2;
3068 CRM_Core_DAO::executeQuery($sql);
3069 $contact3 = $this->householdCreate();
3070 $sql = "UPDATE civicrm_contact SET created_date = '2012-03-01' WHERE id = " . $contact3;
3071 CRM_Core_DAO::executeQuery($sql);
3072 $contacts = $this->callAPISuccess('contact', 'get', array('created_date' => array('<' => '2014-01-01')));
3073 $this->assertEquals($contacts['count'], 3);
3074 $contacts = $this->callAPISuccess('contact', 'get', array('created_date' => array('>' => '2014-01-01')));
3075 $this->assertEquals($contacts['count'], $preExistingContactCount);
3076 }
3077
3078 /**
3079 * CRM-14263 check that API is not affected by search profile related bug.
3080 */
3081 public function testReturnCityProfile() {
3082 $contactID = $this->individualCreate();
3083 CRM_Core_Config::singleton()->defaultSearchProfileID = 1;
3084 $this->callAPISuccess('address', 'create', array(
3085 'contact_id' => $contactID,
3086 'city' => 'Cool City',
3087 'location_type_id' => 1,
3088 ));
3089 $result = $this->callAPISuccess('contact', 'get', array('city' => 'Cool City', 'return' => 'contact_type'));
3090 $this->assertEquals(1, $result['count']);
3091 }
3092
3093 /**
3094 * CRM-15443 - ensure getlist api does not return deleted contacts.
3095 */
3096 public function testGetlistExcludeConditions() {
3097 $name = md5(time());
3098 $contact = $this->individualCreate(array('last_name' => $name));
3099 $this->individualCreate(array('last_name' => $name, 'is_deceased' => 1));
3100 $this->individualCreate(array('last_name' => $name, 'is_deleted' => 1));
3101 // We should get all but the deleted contact.
3102 $result = $this->callAPISuccess('contact', 'getlist', array('input' => $name));
3103 $this->assertEquals(2, $result['count']);
3104 // Force-exclude the deceased contact.
3105 $result = $this->callAPISuccess('contact', 'getlist', array(
3106 'input' => $name,
3107 'params' => array('is_deceased' => 0),
3108 ));
3109 $this->assertEquals(1, $result['count']);
3110 $this->assertEquals($contact, $result['values'][0]['id']);
3111 }
3112
3113 /**
3114 * Test contact getactions.
3115 */
3116 public function testGetActions() {
3117 $description = "Getting the available actions for an entity.";
3118 $result = $this->callAPIAndDocument($this->_entity, 'getactions', array(), __FUNCTION__, __FILE__, $description);
3119 $expected = array(
3120 'create',
3121 'delete',
3122 'get',
3123 'getactions',
3124 'getcount',
3125 'getfields',
3126 'getlist',
3127 'getoptions',
3128 'getquick',
3129 'getrefcount',
3130 'getsingle',
3131 'getvalue',
3132 'merge',
3133 'proximity',
3134 'replace',
3135 'setvalue',
3136 'update',
3137 );
3138 $deprecated = array(
3139 'update',
3140 'getquick',
3141 );
3142 foreach ($expected as $action) {
3143 $this->assertTrue(in_array($action, $result['values']), "Expected action $action");
3144 }
3145 foreach ($deprecated as $action) {
3146 $this->assertArrayKeyExists($action, $result['deprecated']);
3147 }
3148 }
3149
3150 /**
3151 * Test the duplicate check function.
3152 */
3153 public function testDuplicateCheck() {
3154 $harry = array(
3155 'first_name' => 'Harry',
3156 'last_name' => 'Potter',
3157 'email' => 'harry@hogwarts.edu',
3158 'contact_type' => 'Individual',
3159 );
3160 $this->callAPISuccess('Contact', 'create', $harry);
3161 $result = $this->callAPISuccess('Contact', 'duplicatecheck', array(
3162 'match' => $harry,
3163 ));
3164
3165 $this->assertEquals(1, $result['count']);
3166 $result = $this->callAPISuccess('Contact', 'duplicatecheck', array(
3167 'match' => array(
3168 'first_name' => 'Harry',
3169 'last_name' => 'Potter',
3170 'email' => 'no5@privet.drive',
3171 'contact_type' => 'Individual',
3172 ),
3173 ));
3174 $this->assertEquals(0, $result['count']);
3175 $this->callAPIFailure('Contact', 'create', array_merge($harry, array('dupe_check' => 1)));
3176 }
3177
3178 /**
3179 * Test the duplicate check function.
3180 */
3181 public function testDuplicateCheckRuleNotReserved() {
3182 $harry = array(
3183 'first_name' => 'Harry',
3184 'last_name' => 'Potter',
3185 'email' => 'harry@hogwarts.edu',
3186 'contact_type' => 'Individual',
3187 );
3188 $defaultRule = $this->callAPISuccess('RuleGroup', 'getsingle', array('used' => 'Unsupervised', 'is_reserved' => 1));
3189 $this->callAPISuccess('RuleGroup', 'create', array('id' => $defaultRule['id'], 'is_reserved' => 0));
3190 $this->callAPISuccess('Contact', 'create', $harry);
3191 $result = $this->callAPISuccess('Contact', 'duplicatecheck', array(
3192 'match' => $harry,
3193 ));
3194
3195 $this->assertEquals(1, $result['count']);
3196 $this->callAPISuccess('RuleGroup', 'create', array('id' => $defaultRule['id'], 'is_reserved' => 1));
3197 }
3198
3199 /**
3200 * Test variants on retrieving contact by type.
3201 */
3202 public function testGetByContactType() {
3203 $individual = $this->callAPISuccess('Contact', 'create', array(
3204 'email' => 'individual@test.com',
3205 'contact_type' => 'Individual',
3206 ));
3207 $household = $this->callAPISuccess('Contact', 'create', array(
3208 'household_name' => 'household@test.com',
3209 'contact_type' => 'Household',
3210 ));
3211 $organization = $this->callAPISuccess('Contact', 'create', array(
3212 'organization_name' => 'organization@test.com',
3213 'contact_type' => 'Organization',
3214 ));
3215 // Test with id - getsingle will throw an exception if not found
3216 $this->callAPISuccess('Contact', 'getsingle', array(
3217 'id' => $individual['id'],
3218 'contact_type' => 'Individual',
3219 ));
3220 $this->callAPISuccess('Contact', 'getsingle', array(
3221 'id' => $individual['id'],
3222 'contact_type' => array('IN' => array('Individual')),
3223 'return' => 'id',
3224 ));
3225 $this->callAPISuccess('Contact', 'getsingle', array(
3226 'id' => $organization['id'],
3227 'contact_type' => array('IN' => array('Individual', 'Organization')),
3228 ));
3229 // Test as array
3230 $result = $this->callAPISuccess('Contact', 'get', array(
3231 'contact_type' => array('IN' => array('Individual', 'Organization')),
3232 'options' => array('limit' => 0),
3233 'return' => 'id',
3234 ));
3235 $this->assertContains($organization['id'], array_keys($result['values']));
3236 $this->assertContains($individual['id'], array_keys($result['values']));
3237 $this->assertNotContains($household['id'], array_keys($result['values']));
3238 // Test as string
3239 $result = $this->callAPISuccess('Contact', 'get', array(
3240 'contact_type' => 'Household',
3241 'options' => array('limit' => 0),
3242 'return' => 'id',
3243 ));
3244 $this->assertNotContains($organization['id'], array_keys($result['values']));
3245 $this->assertNotContains($individual['id'], array_keys($result['values']));
3246 $this->assertContains($household['id'], array_keys($result['values']));
3247 }
3248
3249 /**
3250 * Test merging 2 contacts.
3251 *
3252 * Someone kindly bequethed us the legacy of mixed up use of main_id & other_id
3253 * in the params for contact.merge api.
3254 *
3255 * This test protects that legacy.
3256 */
3257 public function testMergeBizzareOldParams() {
3258 $this->createLoggedInUser();
3259 $otherContact = $this->callAPISuccess('contact', 'create', $this->_params);
3260 $mainContact = $this->callAPISuccess('contact', 'create', $this->_params);
3261 $this->callAPISuccess('contact', 'merge', array(
3262 'main_id' => $mainContact['id'],
3263 'other_id' => $otherContact['id'],
3264 ));
3265 $contacts = $this->callAPISuccess('contact', 'get', $this->_params);
3266 $this->assertEquals($otherContact['id'], $contacts['id']);
3267 }
3268
3269 /**
3270 * Test merging 2 contacts.
3271 */
3272 public function testMerge() {
3273 $this->createLoggedInUser();
3274 $otherContact = $this->callAPISuccess('contact', 'create', $this->_params);
3275 $retainedContact = $this->callAPISuccess('contact', 'create', $this->_params);
3276 $this->callAPISuccess('contact', 'merge', array(
3277 'to_keep_id' => $retainedContact['id'],
3278 'to_remove_id' => $otherContact['id'],
3279 'auto_flip' => FALSE,
3280 ));
3281
3282 $contacts = $this->callAPISuccess('contact', 'get', $this->_params);
3283 $this->assertEquals($retainedContact['id'], $contacts['id']);
3284 $activity = $this->callAPISuccess('Activity', 'getsingle', array(
3285 'target_contact_id' => $retainedContact['id'],
3286 'activity_type_id' => 'Contact Merged',
3287 ));
3288 $this->assertEquals(date('Y-m-d'), date('Y-m-d', strtotime($activity['activity_date_time'])));
3289 $activity2 = $this->callAPISuccess('Activity', 'getsingle', array(
3290 'target_contact_id' => $otherContact['id'],
3291 'activity_type_id' => 'Contact Deleted by Merge',
3292 ));
3293 $this->assertEquals($activity['id'], $activity2['parent_id']);
3294 $this->assertEquals('Normal', civicrm_api3('option_value', 'getvalue', array(
3295 'value' => $activity['priority_id'],
3296 'return' => 'label',
3297 'option_group_id' => 'priority',
3298 )));
3299
3300 }
3301
3302 /**
3303 * Test merging 2 contacts with delete to trash off.
3304 *
3305 * We are checking that there is no error due to attempting to add an activity for the
3306 * deleted contact.
3307 *
3308 * CRM-18307
3309 */
3310 public function testMergeNoTrash() {
3311 $this->createLoggedInUser();
3312 $this->callAPISuccess('Setting', 'create', array('contact_undelete' => FALSE));
3313 $otherContact = $this->callAPISuccess('contact', 'create', $this->_params);
3314 $retainedContact = $this->callAPISuccess('contact', 'create', $this->_params);
3315 $this->callAPISuccess('contact', 'merge', array(
3316 'to_keep_id' => $retainedContact['id'],
3317 'to_remove_id' => $otherContact['id'],
3318 'auto_flip' => FALSE,
3319 ));
3320 $this->callAPISuccess('Setting', 'create', array('contact_undelete' => TRUE));
3321 }
3322
3323 /**
3324 * Ensure format with return=group shows comma-separated group IDs.
3325 *
3326 * CRM-19426
3327 */
3328 public function testContactGetReturnGroup() {
3329 // Set up a contact, asser that they were created.
3330 $contact_params = array(
3331 'contact_type' => 'Individual',
3332 'first_name' => 'Test',
3333 'last_name' => 'Groupmember',
3334 'email' => 'test@example.org',
3335 );
3336 $create_contact = $this->callApiSuccess('Contact', 'create', $contact_params);
3337 $this->assertEquals(0, $create_contact['is_error']);
3338 $this->assertInternalType('int', $create_contact['id']);
3339
3340 $created_contact_id = $create_contact['id'];
3341
3342 // Set up multiple groups, add the contact to the groups.
3343 $test_groups = array('Test group A', 'Test group B');
3344 foreach ($test_groups as $title) {
3345 // Use this contact as group owner, since we know they exist.
3346 $group_params = array(
3347 'title' => $title,
3348 'created_id' => $created_contact_id,
3349 );
3350 $create_group = $this->callApiSuccess('Group', 'create', $group_params);
3351 $this->assertEquals(0, $create_group['is_error']);
3352 $this->assertInternalType('int', $create_group['id']);
3353
3354 $created_group_ids[] = $create_group['id'];
3355
3356 // Add contact to the new group.
3357 $group_contact_params = array(
3358 'contact_id' => $created_contact_id,
3359 'group_id' => $create_group['id'],
3360 );
3361 $create_group_contact = $this->callApiSuccess('GroupContact', 'create', $group_contact_params);
3362 $this->assertEquals(0, $create_group_contact['is_error']);
3363 $this->assertInternalType('int', $create_group_contact['added']);
3364 }
3365
3366 // Use the Contact,get API to retrieve the contact
3367 $contact_get_params = array(
3368 'id' => $created_contact_id,
3369 'return' => 'group',
3370 );
3371 $contact_get = $this->callApiSuccess('Contact', 'get', $contact_get_params);
3372 $this->assertInternalType('array', $contact_get['values'][$created_contact_id]);
3373 $this->assertInternalType('string', $contact_get['values'][$created_contact_id]['groups']);
3374
3375 // Ensure they are shown as being in each created group.
3376 $contact_group_ids = explode(',', $contact_get['values'][$created_contact_id]['groups']);
3377 foreach ($created_group_ids as $created_group_id) {
3378 $this->assertContains($created_group_id, $contact_group_ids);
3379 }
3380 }
3381
3382 /**
3383 * CRM-20144 Verify that passing title of group works as well as id
3384 * Tests the following formats
3385 * contact.get group='title1'
3386 * contact.get group=id1
3387 */
3388 public function testContactGetWithGroupTitle() {
3389 // Set up a contact, asser that they were created.
3390 $contact_params = array(
3391 'contact_type' => 'Individual',
3392 'first_name' => 'Test2',
3393 'last_name' => 'Groupmember',
3394 'email' => 'test@example.org',
3395 );
3396 $create_contact = $this->callApiSuccess('Contact', 'create', $contact_params);
3397 $created_contact_id = $create_contact['id'];
3398 // Set up multiple groups, add the contact to the groups.
3399 $test_groups = array('Test group C', 'Test group D');
3400 foreach ($test_groups as $title) {
3401 $group_params = array(
3402 'title' => $title,
3403 'created_id' => $created_contact_id,
3404 );
3405 $create_group = $this->callApiSuccess('Group', 'create', $group_params);
3406 $created_group_id = $create_group['id'];
3407
3408 // Add contact to the new group.
3409 $group_contact_params = array(
3410 'contact_id' => $created_contact_id,
3411 'group_id' => $create_group['id'],
3412 );
3413 $this->callApiSuccess('GroupContact', 'create', $group_contact_params);
3414 $contact_get = $this->callAPISuccess('contact', 'get', array('group' => $title, 'return' => 'group'));
3415 $this->assertEquals(1, $contact_get['count']);
3416 $this->assertEquals($created_contact_id, $contact_get['id']);
3417 $contact_groups = explode(',', $contact_get['values'][$created_contact_id]['groups']);
3418 $this->assertContains((string) $create_group['id'], $contact_groups);
3419 $contact_get2 = $this->callAPISuccess('contact', 'get', array('group' => $created_group_id, 'return' => 'group'));
3420 $this->assertEquals($created_contact_id, $contact_get2['id']);
3421 $contact_groups2 = explode(',', $contact_get2['values'][$created_contact_id]['groups']);
3422 $this->assertContains((string) $create_group['id'], $contact_groups2);
3423 $this->callAPISuccess('group', 'delete', array('id' => $created_group_id));
3424 }
3425 $this->callAPISuccess('contact', 'delete', array('id' => $created_contact_id, 'skip_undelete' => TRUE));
3426 }
3427
3428 /**
3429 * CRM-20144 Verify that passing title of group works as well as id
3430 * Tests the following formats
3431 * contact.get group=array('title1', title1)
3432 * contact.get group=array('IN' => array('title1', 'title2)
3433 */
3434 public function testContactGetWithGroupTitleMultipleGroups() {
3435 $description = "Get all from group and display contacts.";
3436 $subFile = "GroupFilterUsingContactAPI";
3437 // Set up a contact, asser that they were created.
3438 $contact_params = array(
3439 'contact_type' => 'Individual',
3440 'first_name' => 'Test2',
3441 'last_name' => 'Groupmember',
3442 'email' => 'test@example.org',
3443 );
3444 $create_contact = $this->callApiSuccess('Contact', 'create', $contact_params);
3445 $created_contact_id = $create_contact['id'];
3446 $createdGroupsTitles = $createdGroupsIds = array();
3447 // Set up multiple groups, add the contact to the groups.
3448 $test_groups = array('Test group C', 'Test group D');
3449 foreach ($test_groups as $title) {
3450 $group_params = array(
3451 'title' => $title,
3452 'created_id' => $created_contact_id,
3453 );
3454 $create_group = $this->callApiSuccess('Group', 'create', $group_params);
3455 $created_group_id = $create_group['id'];
3456 $createdGroupsIds[] = $create_group['id'];
3457 $createdGroupTitles[] = $title;
3458 // Add contact to the new group.
3459 $group_contact_params = array(
3460 'contact_id' => $created_contact_id,
3461 'group_id' => $create_group['id'],
3462 );
3463 $create_group_contact = $this->callApiSuccess('GroupContact', 'create', $group_contact_params);
3464 }
3465 $contact_get = $this->callAPISuccess('contact', 'get', array('group' => $createdGroupTitles, 'return' => 'group'));
3466 $this->assertEquals(1, $contact_get['count']);
3467 $this->assertEquals($created_contact_id, $contact_get['id']);
3468 $contact_groups = explode(',', $contact_get['values'][$created_contact_id]['groups']);
3469 foreach ($createdGroupsIds as $id) {
3470 $this->assertContains((string) $id, $contact_groups);
3471 }
3472 $contact_get2 = $this->callAPIAndDocument('contact', 'get', array('group' => array('IN' => $createdGroupTitles)), __FUNCTION__, __FILE__, $description, $subFile);
3473 $contact_get2 = $this->callAPISuccess('contact', 'get', array('group' => array('IN' => $createdGroupTitles), 'return' => 'group'));
3474 $this->assertEquals($created_contact_id, $contact_get2['id']);
3475 $contact_groups2 = explode(',', $contact_get2['values'][$created_contact_id]['groups']);
3476 foreach ($createdGroupsIds as $id) {
3477 $this->assertContains((string) $id, $contact_groups2);
3478 }
3479 foreach ($createdGroupsIds as $id) {
3480 $this->callAPISuccess('group', 'delete', array('id' => $id));
3481 }
3482 $this->callAPISuccess('contact', 'delete', array('id' => $created_contact_id, 'skip_undelete' => TRUE));
3483 }
3484
3485 /**
3486 * CRM-20144 Verify that passing title of group works as well as id
3487 * Tests the following formats
3488 * contact.get group=array('title1' => 1)
3489 * contact.get group=array('titke1' => 1, 'title2' => 1)
3490 * contact.get group=array('id1' => 1)
3491 * contact.get group=array('id1' => 1, id2 => 1)
3492 */
3493 public function testContactGetWithGroupTitleMultipleGroupsLegacyFormat() {
3494 // Set up a contact, asser that they were created.
3495 $contact_params = array(
3496 'contact_type' => 'Individual',
3497 'first_name' => 'Test2',
3498 'last_name' => 'Groupmember',
3499 'email' => 'test@example.org',
3500 );
3501 $create_contact = $this->callApiSuccess('Contact', 'create', $contact_params);
3502 $created_contact_id = $create_contact['id'];
3503 $createdGroupsTitles = $createdGroupsIds = array();
3504 // Set up multiple groups, add the contact to the groups.
3505 $test_groups = array('Test group C', 'Test group D');
3506 foreach ($test_groups as $title) {
3507 $group_params = array(
3508 'title' => $title,
3509 'created_id' => $created_contact_id,
3510 );
3511 $create_group = $this->callApiSuccess('Group', 'create', $group_params);
3512 $created_group_id = $create_group['id'];
3513 $createdGroupsIds[] = $create_group['id'];
3514 $createdGroupTitles[] = $title;
3515 // Add contact to the new group.
3516 $group_contact_params = array(
3517 'contact_id' => $created_contact_id,
3518 'group_id' => $create_group['id'],
3519 );
3520 $create_group_contact = $this->callApiSuccess('GroupContact', 'create', $group_contact_params);
3521 }
3522 $contact_get = $this->callAPISuccess('contact', 'get', array('group' => array($createdGroupTitles[0] => 1), 'return' => 'group'));
3523 $this->assertEquals(1, $contact_get['count']);
3524 $this->assertEquals($created_contact_id, $contact_get['id']);
3525 $contact_groups = explode(',', $contact_get['values'][$created_contact_id]['groups']);
3526 foreach ($createdGroupsIds as $id) {
3527 $this->assertContains((string) $id, $contact_groups);
3528 }
3529 $contact_get2 = $this->callAPISuccess('contact', 'get', array('group' => array($createdGroupTitles[0] => 1, $createdGroupTitles[1] => 1), 'return' => 'group'));
3530 $this->assertEquals(1, $contact_get2['count']);
3531 $this->assertEquals($created_contact_id, $contact_get2['id']);
3532 $contact_groups2 = explode(',', $contact_get2['values'][$created_contact_id]['groups']);
3533 foreach ($createdGroupsIds as $id) {
3534 $this->assertContains((string) $id, $contact_groups2);
3535 }
3536 $contact_get3 = $this->callAPISuccess('contact', 'get', array('group' => array($createdGroupsIds[0] => 1), 'return' => 'group'));
3537 $this->assertEquals($created_contact_id, $contact_get3['id']);
3538 $contact_groups3 = explode(',', $contact_get3['values'][$created_contact_id]['groups']);
3539 foreach ($createdGroupsIds as $id) {
3540 $this->assertContains((string) $id, $contact_groups3);
3541 }
3542 $contact_get4 = $this->callAPISuccess('contact', 'get', array('group' => array($createdGroupsIds[0] => 1, $createdGroupsIds[1] => 1), 'return' => 'group'));
3543 $this->assertEquals($created_contact_id, $contact_get4['id']);
3544 $contact_groups4 = explode(',', $contact_get4['values'][$created_contact_id]['groups']);
3545 foreach ($createdGroupsIds as $id) {
3546 $this->assertContains((string) $id, $contact_groups4);
3547 }
3548 foreach ($createdGroupsIds as $id) {
3549 $this->callAPISuccess('group', 'delete', array('id' => $id));
3550 }
3551 $this->callAPISuccess('contact', 'delete', array('id' => $created_contact_id, 'skip_undelete' => TRUE));
3552 }
3553
3554 /**
3555 * Test the prox_distance functionality works.
3556 *
3557 * This is primarily testing functionality in the BAO_Query object that 'happens to be'
3558 * accessible via the api.
3559 */
3560 public function testContactGetProximity() {
3561 CRM_Core_Config::singleton()->geocodeMethod = 'CRM_Utils_MockGeocoder';
3562 $this->individualCreate();
3563 $contactID = $this->individualCreate();
3564 $this->callAPISuccess('Address', 'create', [
3565 'contact_id' => $contactID,
3566 'is_primary' => 1,
3567 'city' => 'Whangarei',
3568 'street_address' => 'Dent St',
3569 'geo_code_1' => '-35.8743325',
3570 'geo_code_2' => '174.4567136',
3571 'location_type_id' => 'Home',
3572 ]);
3573 $contact = $this->callAPISuccess('Contact', 'get', [
3574 'prox_distance' => 100,
3575 'prox_geo_code_1' => '-35.72192',
3576 'prox_geo_code_2' => '174.32034',
3577 ]);
3578 $this->assertEquals(1, $contact['count']);
3579 $this->assertEquals($contactID, $contact['id']);
3580 }
3581
3582 public function testLoggedInUserAPISupportToken() {
3583 $description = "Get contact id of the current logged in user";
3584 $subFile = "ContactIDOfLoggedInUserContactAPI";
3585 $cid = $this->createLoggedInUser();
3586 $contact = $this->callAPIAndDocument('contact', 'get', array('id' => 'user_contact_id'), __FUNCTION__, __FILE__, $description, $subFile);
3587 $this->assertEquals($cid, $contact['id']);
3588 }
3589
3590 /**
3591 * @param $groupID
3592 * @param $contact
3593 */
3594 protected function putGroupContactCacheInClearableState($groupID, $contact) {
3595 // We need to force the situation where there is invalid data in the cache and it
3596 // is due to be cleared.
3597 CRM_Core_DAO::executeQuery("
3598 INSERT INTO civicrm_group_contact_cache (group_id, contact_id)
3599 VALUES ({$groupID}, {$contact['id']})
3600 ");
3601 CRM_Core_DAO::executeQuery("UPDATE civicrm_group SET cache_date = '2017-01-01'");
3602 // Reset so it does not skip.
3603 Civi::$statics['CRM_Contact_BAO_GroupContactCache']['is_refresh_init'] = FALSE;
3604 }
3605
3606 /**
3607 * CRM-21041 Test if 'communication style' is set to site default if not passed.
3608 */
3609 public function testCreateCommunicationStyleUnset() {
3610 $this->callAPISuccess('Contact', 'create', array(
3611 'first_name' => 'John',
3612 'last_name' => 'Doe',
3613 'contact_type' => 'Individual')
3614 );
3615 $result = $this->callAPISuccessGetSingle('Contact', array('last_name' => 'Doe'));
3616 $this->assertEquals(1, $result['communication_style_id']);
3617 }
3618
3619 /**
3620 * CRM-21041 Test if 'communication style' is set if value is passed.
3621 */
3622 public function testCreateCommunicationStylePassed() {
3623 $this->callAPISuccess('Contact', 'create', array(
3624 'first_name' => 'John',
3625 'last_name' => 'Doe',
3626 'contact_type' => 'Individual',
3627 'communication_style_id' => 'Familiar',
3628 ));
3629 $result = $this->callAPISuccessGetSingle('Contact', array('last_name' => 'Doe'));
3630 $params = array(
3631 'option_group_id' => 'communication_style',
3632 'label' => 'Familiar',
3633 'return' => 'value',
3634 );
3635 $optionResult = civicrm_api3('OptionValue', 'get', $params);
3636 $communicationStyle = reset($optionResult['values']);
3637 $this->assertEquals($communicationStyle['value'], $result['communication_style_id']);
3638 }
3639
3640 /**
3641 * Test that creating a contact with various contact greetings works.
3642 */
3643 public function testContactGreetingsCreate() {
3644 $contact = $this->callAPISuccess('Contact', 'create', array('first_name' => 'Alan', 'last_name' => 'MouseMouse', 'contact_type' => 'Individual'));
3645 $contact = $this->callAPISuccessGetSingle('Contact', array('id' => $contact['id'], 'return' => 'postal_greeting'));
3646 $this->assertEquals('Dear Alan', $contact['postal_greeting_display']);
3647
3648 $contact = $this->callAPISuccess('Contact', 'create', array('id' => $contact['id'], 'postal_greeting_id' => 2));
3649 $contact = $this->callAPISuccessGetSingle('Contact', array('id' => $contact['id'], 'return' => 'postal_greeting'));
3650 $this->assertEquals('Dear Alan MouseMouse', $contact['postal_greeting_display']);
3651
3652 $contact = $this->callAPISuccess('Contact', 'create', array('organization_name' => 'Alan\'s Show', 'contact_type' => 'Organization'));
3653 $contact = $this->callAPISuccessGetSingle('Contact', array('id' => $contact['id'], 'return' => 'postal_greeting, addressee, email_greeting'));
3654 $this->assertEquals('', $contact['postal_greeting_display']);
3655 $this->assertEquals('', $contact['email_greeting_display']);
3656 $this->assertEquals('Alan\'s Show', $contact['addressee_display']);
3657 }
3658
3659 /**
3660 * Test that creating a contact with various contact greetings works.
3661 */
3662 public function testContactGreetingsCreateWithCustomField() {
3663 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__, __FILE__);
3664 $contact = $this->callAPISuccess('Contact', 'create', array('first_name' => 'Alan', 'contact_type' => 'Individual', 'custom_' . $ids['custom_field_id'] => 'Mice'));
3665
3666 // Change postal greeting to involve a custom field.
3667 $postalOption = $this->callAPISuccessGetSingle('OptionValue', array('option_group_id' => 'postal_greeting', 'filter' => 1, 'is_default' => 1));
3668 $this->callAPISuccess('OptionValue', 'create', array(
3669 'id' => $postalOption['id'],
3670 'name' => 'Dear {contact.first_name} {contact.custom_' . $ids['custom_field_id'] . '}',
3671 'label' => 'Dear {contact.first_name} {contact.custom_' . $ids['custom_field_id'] . '}',
3672 ));
3673
3674 // Update contact & see if postal greeting now reflects the new string.
3675 $this->callAPISuccess('Contact', 'create', array('id' => $contact['id'], 'last_name' => 'MouseyMousey'));
3676 $contact = $this->callAPISuccessGetSingle('Contact', array('id' => $contact['id'], 'return' => 'postal_greeting'));
3677 $this->assertEquals('Dear Alan Mice', $contact['postal_greeting_display']);
3678
3679 // Set contact to have no postal greeting & check it is correct.
3680 $this->callAPISuccess('Contact', 'create', array('id' => $contact['id'], 'postal_greeting_id' => 'null'));
3681 $contact = $this->callAPISuccessGetSingle('Contact', array('id' => $contact['id'], 'return' => 'postal_greeting'));
3682 $this->assertEquals('', $contact['postal_greeting_display']);
3683
3684 //Cleanup
3685 $this->callAPISuccess('OptionValue', 'create', array('id' => $postalOption['id'], 'name' => 'Dear {contact.first_name}'));
3686 $this->customFieldDelete($ids['custom_field_id']);
3687 $this->customGroupDelete($ids['custom_group_id']);
3688 }
3689
3690 }