Merge pull request #11036 from elisseck/CRM-20460-4.7
[civicrm-core.git] / tests / phpunit / api / v3 / ContactTest.php
CommitLineData
6a488035
TO
1<?php
2/**
381fa321 3 * @file
4 * File for the TestContact class.
6a488035
TO
5 *
6 * (PHP 5)
7 *
6c6e6187
TO
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
6a488035 11 * GNU Affero General Public License version 3
6c6e6187
TO
12 * @version $Id: ContactTest.php 31254 2010-12-15 10:09:29Z eileen $
13 * @package CiviCRM
6a488035
TO
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
6a488035
TO
32/**
33 * Test APIv3 civicrm_contact* functions
34 *
6c6e6187
TO
35 * @package CiviCRM_APIv3
36 * @subpackage API_Contact
acb109b7 37 * @group headless
6a488035 38 */
6a488035
TO
39class api_v3_ContactTest extends CiviUnitTestCase {
40 public $DBResetRequired = FALSE;
41 protected $_apiversion;
42 protected $_entity;
43 protected $_params;
b7c9bc4c 44
f6722559 45 protected $_contactID;
6c6e6187 46 protected $_financialTypeId = 1;
6a488035 47
6a488035 48 /**
381fa321 49 * Test setup for every test.
6a488035 50 *
d177a2a6
EM
51 * Connect to the database, truncate the tables that will be used
52 * and redirect stdin to a temporary file
6a488035
TO
53 */
54 public function setUp() {
381fa321 55 // Connect to the database.
6a488035
TO
56 parent::setUp();
57 $this->_apiversion = 3;
f6722559 58 $this->_entity = 'contact';
59 $this->_params = array(
6a488035
TO
60 'first_name' => 'abc1',
61 'contact_type' => 'Individual',
62 'last_name' => 'xyz1',
6a488035 63 );
6a488035
TO
64 }
65
701a69da 66 /**
67 * Restore the DB for the next test.
68 *
69 * @throws \Exception
70 */
00be9182 71 public function tearDown() {
1ca22999 72 $this->callAPISuccess('Setting', 'create', array('includeOrderByClause' => TRUE));
6a488035
TO
73 // truncate a few tables
74 $tablesToTruncate = array(
6a488035
TO
75 'civicrm_email',
76 'civicrm_contribution',
77 'civicrm_line_item',
78 'civicrm_website',
e635f9d4
TO
79 'civicrm_relationship',
80 'civicrm_uf_match',
405f289b 81 'civicrm_phone',
e9e27a80 82 'civicrm_address',
1ca22999 83 'civicrm_acl_contact_cache',
5ea06a7b 84 'civicrm_activity_contact',
85 'civicrm_activity',
0626851e 86 'civicrm_group',
87 'civicrm_group_contact',
88 'civicrm_saved_search',
89 'civicrm_group_contact_cache',
6a488035
TO
90 );
91
f6722559 92 $this->quickCleanup($tablesToTruncate, TRUE);
1ca22999 93 parent::tearDown();
6a488035
TO
94 }
95
96 /**
381fa321 97 * Test civicrm_contact_create.
6a488035 98 *
381fa321 99 * Verify that attempt to create individual contact with only
100 * first and last names succeeds
6a488035 101 */
00be9182 102 public function testAddCreateIndividual() {
6a488035
TO
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',
6a488035
TO
108 );
109
f6722559 110 $contact = $this->callAPISuccess('contact', 'create', $params);
fe482240
EM
111 $this->assertTrue(is_numeric($contact['id']));
112 $this->assertTrue($contact['id'] > 0);
6a488035 113 $newCount = CRM_Core_DAO::singleValueQuery('select count(*) from civicrm_contact');
6c6e6187 114 $this->assertEquals($oldCount + 1, $newCount);
6a488035 115
6a488035
TO
116 $this->assertDBState('CRM_Contact_DAO_Contact',
117 $contact['id'],
118 $params
119 );
120 }
121
ec52a65a 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);
0626851e 139 CRM_Core_Config::setPermitCacheFlushMode(FALSE);
140 $this->callAPISuccess('contact', 'create', array('id' => $contact['id']));
ec52a65a 141 $this->assertEquals(1, CRM_Core_DAO::singleValueQuery("SELECT count(*) FROM civicrm_group_contact_cache"));
0626851e 142 CRM_Core_Config::setPermitCacheFlushMode(TRUE);
ec52a65a 143 }
144
3a15378c 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
b99f9616 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
6a488035 202 /**
381fa321 203 * Test civicrm_contact_create with sub-types.
6a488035 204 *
381fa321 205 * Verify that sub-types are created successfully and not deleted by subsequent updates.
6a488035 206 */
00be9182 207 public function testIndividualSubType() {
6a488035
TO
208 $params = array(
209 'first_name' => 'test abc',
210 'contact_type' => 'Individual',
211 'last_name' => 'test xyz',
212 'contact_sub_type' => array('Student', 'Staff'),
5896d037 213 );
f6722559 214 $contact = $this->callAPISuccess('contact', 'create', $params);
6a488035
TO
215 $cid = $contact['id'];
216
217 $params = array(
218 'id' => $cid,
219 'middle_name' => 'foo',
6a488035 220 );
f6722559 221 $this->callAPISuccess('contact', 'create', $params);
6a488035
TO
222 unset($params['middle_name']);
223
f6722559 224 $contact = $this->callAPISuccess('contact', 'get', $params);
6a488035 225
fe482240 226 $this->assertEquals(array('Student', 'Staff'), $contact['values'][$cid]['contact_sub_type']);
6a488035
TO
227 }
228
35fbf8a2
MM
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
6a488035 267 /**
381fa321 268 * Verify that attempt to create contact with empty params fails.
6a488035 269 */
00be9182 270 public function testCreateEmptyContact() {
f6722559 271 $this->callAPIFailure('contact', 'create', array());
6a488035
TO
272 }
273
274 /**
381fa321 275 * Verify that attempt to create contact with bad contact type fails.
6a488035 276 */
00be9182 277 public function testCreateBadTypeContact() {
6a488035
TO
278 $params = array(
279 'email' => 'man1@yahoo.com',
280 'contact_type' => 'Does not Exist',
6a488035 281 );
6c6e6187 282 $this->callAPIFailure('contact', 'create', $params, "'Does not Exist' is not a valid option for field contact_type");
6a488035
TO
283 }
284
285 /**
381fa321 286 * Verify that attempt to create individual contact without required fields fails.
6a488035 287 */
00be9182 288 public function testCreateBadRequiredFieldsIndividual() {
6a488035
TO
289 $params = array(
290 'middle_name' => 'This field is not required',
291 'contact_type' => 'Individual',
292 );
4b58ed3b 293 $this->callAPIFailure('contact', 'create', $params);
6a488035
TO
294 }
295
296 /**
381fa321 297 * Verify that attempt to create household contact without required fields fails.
6a488035 298 */
00be9182 299 public function testCreateBadRequiredFieldsHousehold() {
6a488035
TO
300 $params = array(
301 'middle_name' => 'This field is not required',
302 'contact_type' => 'Household',
303 );
4b58ed3b 304 $this->callAPIFailure('contact', 'create', $params);
6a488035
TO
305 }
306
307 /**
381fa321 308 * Test required field check.
309 *
310 * Verify that attempt to create organization contact without required fields fails.
6a488035 311 */
00be9182 312 public function testCreateBadRequiredFieldsOrganization() {
6a488035
TO
313 $params = array(
314 'middle_name' => 'This field is not required',
315 'contact_type' => 'Organization',
316 );
317
4b58ed3b 318 $this->callAPIFailure('contact', 'create', $params);
6a488035
TO
319 }
320
321 /**
381fa321 322 * Verify that attempt to create individual contact with only an email succeeds.
6a488035 323 */
00be9182 324 public function testCreateEmailIndividual() {
57f8e7f0 325 $primaryEmail = 'man3@yahoo.com';
326 $notPrimaryEmail = 'man4@yahoo.com';
6a488035 327 $params = array(
57f8e7f0 328 'email' => $primaryEmail,
6a488035
TO
329 'contact_type' => 'Individual',
330 'location_type_id' => 1,
6a488035
TO
331 );
332
57f8e7f0 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']);
f6722559 351
57f8e7f0 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']);
6a488035 356
57f8e7f0 357 $this->callAPISuccess('contact', 'delete', $contact1);
6a488035
TO
358 }
359
360 /**
381fa321 361 * Test creating individual by name.
362 *
363 * Verify create individual contact with only first and last names succeeds.
6a488035 364 */
00be9182 365 public function testCreateNameIndividual() {
6a488035
TO
366 $params = array(
367 'first_name' => 'abc1',
368 'contact_type' => 'Individual',
369 'last_name' => 'xyz1',
6a488035 370 );
6a488035 371
c8747697 372 $this->callAPISuccess('contact', 'create', $params);
6a488035
TO
373 }
374
c10e7177 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
6a488035 391 /**
381fa321 392 * Test old keys still work.
393 *
394 * Verify that attempt to create individual contact with
d177a2a6 395 * first and last names and old key values works
6a488035 396 */
00be9182 397 public function testCreateNameIndividualOldKeys() {
6a488035
TO
398 $params = array(
399 'individual_prefix' => 'Dr.',
400 'first_name' => 'abc1',
401 'contact_type' => 'Individual',
402 'last_name' => 'xyz1',
403 'individual_suffix' => 'Jr.',
6a488035
TO
404 );
405
f6722559 406 $contact = $this->callAPISuccess('contact', 'create', $params);
6ecbca5b 407 $result = $this->callAPISuccess('contact', 'getsingle', array('id' => $contact['id']));
fd651abc 408
a1255c80
CW
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']);
6a488035
TO
414 }
415
416 /**
381fa321 417 * Test preferred keys work.
418 *
419 * Verify that attempt to create individual contact with
d177a2a6 420 * first and last names and old key values works
6a488035 421 */
381fa321 422 public function testCreateNameIndividualRecommendedKeys2() {
6a488035
TO
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',
6a488035
TO
430 );
431
f6722559 432 $contact = $this->callAPISuccess('contact', 'create', $params);
6ecbca5b 433 $result = $this->callAPISuccess('contact', 'getsingle', array('id' => $contact['id']));
fd651abc 434
a1255c80
CW
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']);
6a488035
TO
440 }
441
442 /**
381fa321 443 * Test household name is sufficient for create.
444 *
445 * Verify that attempt to create household contact with only
d177a2a6 446 * household name succeeds
6a488035 447 */
00be9182 448 public function testCreateNameHousehold() {
6a488035
TO
449 $params = array(
450 'household_name' => 'The abc Household',
451 'contact_type' => 'Household',
6a488035 452 );
c8747697 453 $this->callAPISuccess('contact', 'create', $params);
6a488035
TO
454 }
455
456 /**
381fa321 457 * Test organization name is sufficient for create.
458 *
459 * Verify that attempt to create organization contact with only
d177a2a6 460 * organization name succeeds.
6a488035 461 */
00be9182 462 public function testCreateNameOrganization() {
6a488035
TO
463 $params = array(
464 'organization_name' => 'The abc Organization',
465 'contact_type' => 'Organization',
6a488035 466 );
c8747697 467 $this->callAPISuccess('contact', 'create', $params);
6a488035 468 }
5896d037 469
6a488035 470 /**
381fa321 471 * Verify that attempt to create organization contact without organization name fails.
6a488035 472 */
00be9182 473 public function testCreateNoNameOrganization() {
6a488035
TO
474 $params = array(
475 'first_name' => 'The abc Organization',
476 'contact_type' => 'Organization',
6a488035 477 );
4b58ed3b 478 $this->callAPIFailure('contact', 'create', $params);
6a488035 479 }
5896d037 480
ea33395c
TO
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
6a488035 550 /**
381fa321 551 * Check with complete array + custom field.
552 *
6a488035
TO
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 */
00be9182 557 public function testCreateWithCustom() {
6a488035
TO
558 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__, __FILE__);
559
560 $params = $this->_params;
561 $params['custom_' . $ids['custom_field_id']] = "custom string";
5c49fee0 562 $description = "This demonstrates setting a custom field through the API.";
fb32de45 563 $result = $this->callAPIAndDocument($this->_entity, 'create', $params, __FUNCTION__, __FILE__, $description);
6a488035 564
5896d037 565 $check = $this->callAPISuccess($this->_entity, 'get', array(
92915c55
TO
566 'return.custom_' . $ids['custom_field_id'] => 1,
567 'id' => $result['id'],
568 ));
4b58ed3b 569 $this->assertEquals("custom string", $check['values'][$check['id']]['custom_' . $ids['custom_field_id']]);
6a488035
TO
570
571 $this->customFieldDelete($ids['custom_field_id']);
572 $this->customGroupDelete($ids['custom_group_id']);
573 }
574
fe6daa04 575 /**
381fa321 576 * CRM-12773 - expectation is that civicrm quietly ignores fields without values.
fe6daa04 577 */
00be9182 578 public function testCreateWithNULLCustomCRM12773() {
fe6daa04 579 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__, __FILE__);
580 $params = $this->_params;
581 $params['custom_' . $ids['custom_field_id']] = NULL;
4b58ed3b 582 $this->callAPISuccess('contact', 'create', $params);
fe6daa04 583 $this->customFieldDelete($ids['custom_field_id']);
584 $this->customGroupDelete($ids['custom_group_id']);
585 }
586
9747df8a 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
2930d67a 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
3c27d467 670 $result = $this->callAPISuccess('Contact', 'create', $params);
2930d67a 671 $customFldId = $result['values'][$result['id']]['api.CustomField.create']['id'];
ba4a1892 672 $this->assertNotNull($result['id']);
a15773db 673 $this->assertNotNull($customFldId);
2930d67a 674
675 $params = array(
676 'id' => $result['id'],
677 "custom_{$customFldId}" => $dateTime,
678 'api.CustomValue.get' => 1,
679 );
680
3c27d467 681 $result = $this->callAPISuccess('Contact', 'create', $params);
ba4a1892 682 $this->assertNotNull($result['id']);
2930d67a 683 $customFldDate = date("YmdHis", strtotime($result['values'][$result['id']]['api.CustomValue.get']['values'][0]['latest']));
a15773db 684 $this->assertNotNull($customFldDate);
2930d67a 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(
41755648 692 'id' => $customFldId,
2930d67a 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 );
3c27d467 704 $result = $this->callAPISuccess('Contact', 'create', $params);
ba4a1892 705 $this->assertNotNull($result['id']);
2930d67a 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']));
a15773db 708 $this->assertNotNull($customFldDate);
2930d67a 709 $this->assertEquals($dateTime, $customFldDate);
710 $this->assertEquals(000000, $customFldTime);
3c27d467 711 $this->callAPISuccess('Contact', 'create', $params);
2930d67a 712 }
713
fe6daa04 714
d424ffde 715 /**
381fa321 716 * Test creating a current employer through API.
6a488035 717 */
5896d037 718 public function testContactCreateCurrentEmployer() {
381fa321 719 // Here we will just do the get for set-up purposes.
f6722559 720 $count = $this->callAPISuccess('contact', 'getcount', array(
6a488035 721 'organization_name' => 'new employer org',
21dfd5f5 722 'contact_type' => 'Organization',
6a488035
TO
723 ));
724 $this->assertEquals(0, $count);
f6722559 725 $employerResult = $this->callAPISuccess('contact', 'create', array_merge($this->_params, array(
5896d037
TO
726 'current_employer' => 'new employer org',
727 )
6a488035 728 ));
bb043d6f
E
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(
6c6e6187 731 'current_employer' => 'new employer org',
21dfd5f5 732 'id' => $employerResult['id'],
5896d037 733 )
bb043d6f 734 ));
f6722559 735 $expectedCount = 1;
4b58ed3b 736 $this->callAPISuccess('contact', 'getcount', array(
5896d037 737 'organization_name' => 'new employer org',
21dfd5f5 738 'contact_type' => 'Organization',
5896d037
TO
739 ),
740 $expectedCount);
6a488035 741
f6722559 742 $result = $this->callAPISuccess('contact', 'getsingle', array(
6a488035
TO
743 'id' => $employerResult['id'],
744 ));
745
746 $this->assertEquals('new employer org', $result['current_employer']);
747
748 }
5896d037 749
d424ffde 750 /**
381fa321 751 * Test creating a current employer through API.
752 *
753 * Check it will re-activate a de-activated employer
d424ffde 754 */
5896d037 755 public function testContactCreateDuplicateCurrentEmployerEnables() {
381fa321 756 // Set up - create employer relationship.
bb043d6f 757 $employerResult = $this->callAPISuccess('contact', 'create', array_merge($this->_params, array(
5896d037
TO
758 'current_employer' => 'new employer org',
759 )
bb043d6f 760 ));
6c6e6187 761 $relationship = $this->callAPISuccess('relationship', 'get', array(
bb043d6f 762 'contact_id_a' => $employerResult['id'],
6c6e6187 763 ));
bb043d6f
E
764
765 //disable & check it is disabled
766 $this->callAPISuccess('relationship', 'create', array('id' => $relationship['id'], 'is_active' => 0));
6c6e6187 767 $this->callAPISuccess('relationship', 'getvalue', array(
bb043d6f 768 'id' => $relationship['id'],
21dfd5f5 769 'return' => 'is_active',
bb043d6f
E
770 ), 0);
771
381fa321 772 // Re-set the current employer - thus enabling the relationship.
4b58ed3b 773 $this->callAPISuccess('contact', 'create', array_merge($this->_params, array(
6c6e6187 774 'current_employer' => 'new employer org',
21dfd5f5 775 'id' => $employerResult['id'],
5896d037 776 )
bb043d6f
E
777 ));
778 //check is_active is now 1
6c6e6187 779 $relationship = $this->callAPISuccess('relationship', 'getsingle', array(
5896d037
TO
780 'return' => 'is_active',
781 ));
6c6e6187 782 $this->assertEquals(1, $relationship['is_active']);
bb043d6f
E
783 }
784
8f32b005 785 /**
381fa321 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.
8f32b005 789 */
00be9182 790 public function testGetDeceasedRetrieved() {
4b58ed3b 791 $this->callAPISuccess($this->_entity, 'create', $this->_params);
5896d037 792 $c2 = $this->callAPISuccess($this->_entity, 'create', array(
92915c55
TO
793 'first_name' => 'bb',
794 'last_name' => 'ccc',
795 'contact_type' => 'Individual',
796 'is_deceased' => 1,
797 ));
8f32b005 798 $result = $this->callAPISuccess($this->_entity, 'get', array('is_deceased' => 0));
799 $this->assertFalse(array_key_exists($c2['id'], $result['values']));
800 }
6a488035 801
c490a46a 802 /**
381fa321 803 * Test that sort works - old syntax.
c490a46a 804 */
00be9182 805 public function testGetSort() {
f6722559 806 $c1 = $this->callAPISuccess($this->_entity, 'create', $this->_params);
5896d037 807 $c2 = $this->callAPISuccess($this->_entity, 'create', array(
92915c55
TO
808 'first_name' => 'bb',
809 'last_name' => 'ccc',
810 'contact_type' => 'Individual',
811 ));
5896d037
TO
812 $result = $this->callAPISuccess($this->_entity, 'get', array(
813 'sort' => 'first_name ASC',
814 'return.first_name' => 1,
815 'sequential' => 1,
816 'rowCount' => 1,
c8747697 817 'contact_type' => 'Individual',
5896d037 818 ));
6a488035
TO
819
820 $this->assertEquals('abc1', $result['values'][0]['first_name']);
f6722559 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 ));
6a488035
TO
827 $this->assertEquals('bb', $result['values'][0]['first_name']);
828
f6722559 829 $this->callAPISuccess($this->_entity, 'delete', array('id' => $c1['id']));
830 $this->callAPISuccess($this->_entity, 'delete', array('id' => $c2['id']));
6a488035 831 }
5896d037 832
d424ffde 833 /**
381fa321 834 * Test that we can retrieve contacts using array syntax.
835 *
836 * I.e 'id' => array('IN' => array('3,4')).
d424ffde 837 */
00be9182 838 public function testGetINIDArray() {
78c0bfc0 839 $c1 = $this->callAPISuccess($this->_entity, 'create', $this->_params);
5896d037 840 $c2 = $this->callAPISuccess($this->_entity, 'create', array(
92915c55
TO
841 'first_name' => 'bb',
842 'last_name' => 'ccc',
843 'contact_type' => 'Individual',
844 ));
5896d037 845 $c3 = $this->callAPISuccess($this->_entity, 'create', array(
92915c55
TO
846 'first_name' => 'hh',
847 'last_name' => 'll',
848 'contact_type' => 'Individual',
849 ));
78c0bfc0 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 }
5896d037 857
d424ffde 858 /**
381fa321 859 * Test variants on deleted behaviour.
6a488035 860 */
00be9182 861 public function testGetDeleted() {
6a488035 862 $params = $this->_params;
f6722559 863 $contact1 = $this->callAPISuccess('contact', 'create', $params);
6a488035
TO
864 $params['is_deleted'] = 1;
865 $params['last_name'] = 'bcd';
f6722559 866 $contact2 = $this->callAPISuccess('contact', 'create', $params);
c8747697 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'));
f6722559 874 $countDeleted = $this->callAPISuccess('contact', 'getcount', array(
c8747697 875 'contact_type' => 'Individual',
f6722559 876 'contact_is_deleted' => 1,
5896d037 877 ));
f6722559 878 $countNotDeleted = $this->callAPISuccess('contact', 'getcount', array(
879 'contact_is_deleted' => 0,
c8747697 880 'contact_type' => 'Individual',
5896d037 881 ));
f6722559 882 $this->callAPISuccess('contact', 'delete', array('id' => $contact1['id']));
883 $this->callAPISuccess('contact', 'delete', array('id' => $contact2['id']));
c8747697 884 $this->assertEquals(1, $countNotDeleted, 'contact_is_deleted => 0 is respected');
fe482240
EM
885 $this->assertEquals(1, $countActive);
886 $this->assertEquals(1, $countTrash);
887 $this->assertEquals(2, $countAll);
888 $this->assertEquals(1, $countDeleted);
c8747697 889 $this->assertEquals(1, $countDefault, 'Only active by default in line');
6a488035 890 }
c490a46a
CW
891
892 /**
381fa321 893 * Test that sort works - new syntax.
c490a46a 894 */
381fa321 895 public function testGetSortNewSyntax() {
5896d037
TO
896 $c1 = $this->callAPISuccess($this->_entity, 'create', $this->_params);
897 $c2 = $this->callAPISuccess($this->_entity, 'create', array(
92915c55
TO
898 'first_name' => 'bb',
899 'last_name' => 'ccc',
900 'contact_type' => 'Individual',
901 ));
f6722559 902 $result = $this->callAPISuccess($this->_entity, 'getvalue', array(
6a488035 903 'return' => 'first_name',
c8747697 904 'contact_type' => 'Individual',
5896d037
TO
905 'options' => array(
906 'limit' => 1,
907 'sort' => 'first_name',
908 ),
909 ));
c8747697 910 $this->assertEquals('abc1', $result);
6a488035 911
f6722559 912 $result = $this->callAPISuccess($this->_entity, 'getvalue', array(
5896d037 913 'return' => 'first_name',
c8747697 914 'contact_type' => 'Individual',
5896d037
TO
915 'options' => array(
916 'limit' => 1,
917 'sort' => 'first_name DESC',
918 ),
919 ));
6a488035
TO
920 $this->assertEquals('bb', $result);
921
f6722559 922 $this->callAPISuccess($this->_entity, 'delete', array('id' => $c1['id']));
923 $this->callAPISuccess($this->_entity, 'delete', array('id' => $c2['id']));
6a488035 924 }
c490a46a 925
c4bc3d5a
JV
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
c490a46a 990 /**
381fa321 991 * Test apostrophe works in get & create.
6a488035 992 */
00be9182 993 public function testGetApostropheCRM10857() {
6a488035 994 $params = array_merge($this->_params, array('last_name' => "O'Connor"));
4b58ed3b 995 $this->callAPISuccess($this->_entity, 'create', $params);
f6722559 996 $result = $this->callAPISuccess($this->_entity, 'getsingle', array(
6a488035
TO
997 'last_name' => "O'Connor",
998 'sequential' => 1,
999 ));
1000 $this->assertEquals("O'Connor", $result['last_name'], 'in line' . __LINE__);
1001 }
1002
1003 /**
381fa321 1004 * Check with complete array + custom field.
1005 *
6a488035
TO
1006 * Note that the test is written on purpose without any
1007 * variables specific to participant so it can be replicated into other entities
1008 * and / or moved to the automated test suite
1009 */
00be9182 1010 public function testGetWithCustom() {
6a488035
TO
1011 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__, __FILE__);
1012
1013 $params = $this->_params;
1014 $params['custom_' . $ids['custom_field_id']] = "custom string";
5c49fee0 1015 $description = "This demonstrates setting a custom field through the API.";
6a488035 1016 $subfile = "CustomFieldGet";
f6722559 1017 $result = $this->callAPISuccess($this->_entity, 'create', $params);
6a488035 1018
5896d037 1019 $check = $this->callAPIAndDocument($this->_entity, 'get', array(
92915c55
TO
1020 'return.custom_' . $ids['custom_field_id'] => 1,
1021 'id' => $result['id'],
1022 ), __FUNCTION__, __FILE__, $description, $subfile);
6a488035 1023
4b58ed3b 1024 $this->assertEquals("custom string", $check['values'][$check['id']]['custom_' . $ids['custom_field_id']]);
f6722559 1025 $fields = ($this->callAPISuccess('contact', 'getfields', $params));
6a488035
TO
1026 $this->assertTrue(is_array($fields['values']['custom_' . $ids['custom_field_id']]));
1027 $this->customFieldDelete($ids['custom_field_id']);
1028 $this->customGroupDelete($ids['custom_group_id']);
1029 }
c490a46a
CW
1030
1031 /**
381fa321 1032 * Check with complete array + custom field.
1033 *
c490a46a
CW
1034 * Note that the test is written on purpose without any
1035 * variables specific to participant so it can be replicated into other entities
1036 * and / or moved to the automated test suite
1037 */
00be9182 1038 public function testGetWithCustomReturnSyntax() {
6a488035
TO
1039 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__, __FILE__);
1040
1041 $params = $this->_params;
1042 $params['custom_' . $ids['custom_field_id']] = "custom string";
5c49fee0 1043 $description = "This demonstrates setting a custom field through the API.";
6a488035 1044 $subfile = "CustomFieldGetReturnSyntaxVariation";
f6722559 1045 $result = $this->callAPISuccess($this->_entity, 'create', $params);
1046 $params = array('return' => 'custom_' . $ids['custom_field_id'], 'id' => $result['id']);
1047 $check = $this->callAPIAndDocument($this->_entity, 'get', $params, __FUNCTION__, __FILE__, $description, $subfile);
6a488035 1048
43ef1263 1049 $this->assertEquals("custom string", $check['values'][$check['id']]['custom_' . $ids['custom_field_id']]);
6a488035
TO
1050 $this->customFieldDelete($ids['custom_field_id']);
1051 $this->customGroupDelete($ids['custom_group_id']);
1052 }
1053
43ef1263 1054 /**
66670e4d 1055 * Check that address name, ID is returned if required.
43ef1263 1056 */
66670e4d 1057 public function testGetReturnAddress() {
43ef1263 1058 $contactID = $this->individualCreate();
66670e4d 1059 $result = $this->callAPISuccess('address', 'create', array(
92915c55
TO
1060 'contact_id' => $contactID,
1061 'address_name' => 'My house',
1062 'location_type_id' => 'Home',
1063 'street_address' => '1 my road',
1064 ));
66670e4d 1065 $addressID = $result['id'];
1066
5896d037 1067 $result = $this->callAPISuccessGetSingle('contact', array(
66670e4d 1068 'return' => 'address_name, street_address, address_id',
92915c55
TO
1069 'id' => $contactID,
1070 ));
66670e4d 1071 $this->assertEquals($addressID, $result['address_id']);
43ef1263
EM
1072 $this->assertEquals('1 my road', $result['street_address']);
1073 $this->assertEquals('My house', $result['address_name']);
1074
1075 }
1076
701a69da 1077 /**
1078 * Test group filter syntaxes.
1079 */
00be9182 1080 public function testGetGroupIDFromContact() {
5896d037 1081 $groupId = $this->groupCreate();
5896d037 1082 $params = array(
6a488035
TO
1083 'email' => 'man2@yahoo.com',
1084 'contact_type' => 'Individual',
1085 'location_type_id' => 1,
6a488035
TO
1086 'api.group_contact.create' => array('group_id' => $groupId),
1087 );
1088
4b58ed3b 1089 $this->callAPISuccess('contact', 'create', $params);
6a488035
TO
1090 // testing as integer
1091 $params = array(
d0aa0e47 1092 'filter.group_id' => $groupId,
6a488035
TO
1093 'contact_type' => 'Individual',
1094 );
d0aa0e47 1095 $result = $this->callAPISuccess('contact', 'get', $params);
6a488035
TO
1096 $this->assertEquals(1, $result['count']);
1097 // group 26 doesn't exist, but we can still search contacts in it.
1098 $params = array(
d0aa0e47 1099 'filter.group_id' => 26,
6a488035
TO
1100 'contact_type' => 'Individual',
1101 );
4b58ed3b 1102 $this->callAPISuccess('contact', 'get', $params);
6a488035
TO
1103 // testing as string
1104 $params = array(
d0aa0e47 1105 'filter.group_id' => "$groupId, 26",
6a488035
TO
1106 'contact_type' => 'Individual',
1107 );
d0aa0e47 1108 $result = $this->callAPISuccess('contact', 'get', $params);
6a488035
TO
1109 $this->assertEquals(1, $result['count']);
1110 $params = array(
d0aa0e47 1111 'filter.group_id' => "26,27",
6a488035
TO
1112 'contact_type' => 'Individual',
1113 );
4b58ed3b 1114 $this->callAPISuccess('contact', 'get', $params);
6a488035
TO
1115
1116 // testing as string
6c6e6187 1117 $params = array(
d0aa0e47 1118 'filter.group_id' => array($groupId, 26),
6a488035
TO
1119 'contact_type' => 'Individual',
1120 );
d0aa0e47 1121 $result = $this->callAPISuccess('contact', 'get', $params);
6a488035
TO
1122 $this->assertEquals(1, $result['count']);
1123
1124 //test in conjunction with other criteria
6c6e6187 1125 $params = array(
d0aa0e47 1126 'filter.group_id' => array($groupId, 26),
6a488035
TO
1127 'contact_type' => 'Organization',
1128 );
6c6e6187
TO
1129 $this->callAPISuccess('contact', 'get', $params);
1130 $params = array(
d0aa0e47 1131 'filter.group_id' => array(26, 27),
6a488035
TO
1132 'contact_type' => 'Individual',
1133 );
f6722559 1134 $result = $this->callAPISuccess('contact', 'get', $params);
4b58ed3b 1135 $this->assertEquals(0, $result['count']);
6a488035
TO
1136 }
1137
1138 /**
381fa321 1139 * Verify that attempt to create individual contact with two chained websites succeeds.
6a488035 1140 */
00be9182 1141 public function testCreateIndividualWithContributionDottedSyntax() {
5c49fee0 1142 $description = "This demonstrates the syntax to create 2 chained entities.";
5896d037
TO
1143 $subFile = "ChainTwoWebsites";
1144 $params = array(
6a488035
TO
1145 'first_name' => 'abc3',
1146 'last_name' => 'xyz3',
1147 'contact_type' => 'Individual',
1148 'email' => 'man3@yahoo.com',
6a488035
TO
1149 'api.contribution.create' => array(
1150 'receive_date' => '2010-01-01',
1151 'total_amount' => 100.00,
5896d037 1152 'financial_type_id' => $this->_financialTypeId,
6a488035
TO
1153 'payment_instrument_id' => 1,
1154 'non_deductible_amount' => 10.00,
1155 'fee_amount' => 50.00,
1156 'net_amount' => 90.00,
1157 'trxn_id' => 15345,
1158 'invoice_id' => 67990,
1159 'source' => 'SSF',
1160 'contribution_status_id' => 1,
1161 ),
1162 'api.website.create' => array(
1163 'url' => "http://civicrm.org",
1164 ),
1165 'api.website.create.2' => array(
1166 'url' => "http://chained.org",
1167 ),
1168 );
1169
4b58ed3b 1170 $result = $this->callAPIAndDocument('Contact', 'create', $params, __FUNCTION__, __FILE__, $description, $subFile);
6a488035 1171
f6722559 1172 // checking child function result not covered in callAPIAndDocument
1173 $this->assertAPISuccess($result['values'][$result['id']]['api.website.create']);
fe482240
EM
1174 $this->assertEquals("http://chained.org", $result['values'][$result['id']]['api.website.create.2']['values'][0]['url']);
1175 $this->assertEquals("http://civicrm.org", $result['values'][$result['id']]['api.website.create']['values'][0]['url']);
6a488035
TO
1176
1177 // delete the contact
f6722559 1178 $this->callAPISuccess('contact', 'delete', $result);
6a488035
TO
1179 }
1180
1181 /**
381fa321 1182 * Verify that attempt to create individual contact with chained contribution and website succeeds.
6a488035 1183 */
00be9182 1184 public function testCreateIndividualWithContributionChainedArrays() {
6a488035
TO
1185 $params = array(
1186 'first_name' => 'abc3',
1187 'last_name' => 'xyz3',
1188 'contact_type' => 'Individual',
1189 'email' => 'man3@yahoo.com',
6a488035
TO
1190 'api.contribution.create' => array(
1191 'receive_date' => '2010-01-01',
1192 'total_amount' => 100.00,
5896d037 1193 'financial_type_id' => $this->_financialTypeId,
6a488035
TO
1194 'payment_instrument_id' => 1,
1195 'non_deductible_amount' => 10.00,
1196 'fee_amount' => 50.00,
1197 'net_amount' => 90.00,
1198 'trxn_id' => 12345,
1199 'invoice_id' => 67890,
1200 'source' => 'SSF',
1201 'contribution_status_id' => 1,
1202 ),
1203 'api.website.create' => array(
1204 array(
1205 'url' => "http://civicrm.org",
1206 ),
1207 array(
1208 'url' => "http://chained.org",
1209 'website_type_id' => 2,
1210 ),
1211 ),
1212 );
1213
5c49fee0 1214 $description = "Demonstrates creating two websites as an array.";
5896d037
TO
1215 $subfile = "ChainTwoWebsitesSyntax2";
1216 $result = $this->callAPIAndDocument('Contact', 'create', $params, __FUNCTION__, __FILE__, $description, $subfile);
f6722559 1217
f6722559 1218 // the callAndDocument doesn't check the chained call
fe482240
EM
1219 $this->assertEquals(0, $result['values'][$result['id']]['api.website.create'][0]['is_error']);
1220 $this->assertEquals("http://chained.org", $result['values'][$result['id']]['api.website.create'][1]['values'][0]['url']);
1221 $this->assertEquals("http://civicrm.org", $result['values'][$result['id']]['api.website.create'][0]['values'][0]['url']);
6a488035 1222
f6722559 1223 $this->callAPISuccess('contact', 'delete', $result);
6a488035
TO
1224 }
1225
92d270fd
JV
1226 /**
1227 * Test for direction when chaining relationships.
1228 *
1229 * https://issues.civicrm.org/jira/browse/CRM-16084
1230 */
1231 public function testDirectionChainingRelationshipsCRM16084() {
1232 // Some contact, called Jules.
1233 $create_result_1 = $this->callAPISuccess('contact', 'create', array(
1234 'first_name' => 'Jules',
1235 'last_name' => 'Smos',
1236 'contact_type' => 'Individual',
1237 ));
1238
1239 // Another contact: Jos, child of Jules.
1240 $create_params = array(
1241 'first_name' => 'Jos',
1242 'last_name' => 'Smos',
1243 'contact_type' => 'Individual',
1244 'api.relationship.create' => array(
1245 array(
1246 'contact_id_a' => '$value.id',
1247 'contact_id_b' => $create_result_1['id'],
1248 // child of
1249 'relationship_type_id' => 1,
1250 ),
1251 ),
1252 );
1253 $create_result_2 = $this->callAPISuccess('contact', 'create', $create_params);
1254
1255 // Mia is the child of Jos.
1256 $create_params = array(
1257 'first_name' => 'Mia',
1258 'last_name' => 'Smos',
1259 'contact_type' => 'Individual',
1260 'api.relationship.create' => array(
1261 array(
1262 'contact_id_a' => '$value.id',
1263 'contact_id_b' => $create_result_2['id'],
1264 // child of
1265 'relationship_type_id' => 1,
1266 ),
1267 ),
1268 );
1269 $create_result_3 = $this->callAPISuccess('contact', 'create', $create_params);
1270
1271 // Get Jos and his children.
1272 $get_params = array(
1273 'sequential' => 1,
1274 'id' => $create_result_2['id'],
1275 'api.relationship.get' => array(
1276 'contact_id_b' => '$value.id',
1277 'relationship_type_id' => 1,
1278 ),
1279 );
1280 $get_result = $this->callAPISuccess('contact', 'getsingle', $get_params);
1281
1282 // Clean up first.
1283 $this->callAPISuccess('contact', 'delete', array(
1284 'id' => $create_result_1['id'],
1285 ));
1286 $this->callAPISuccess('contact', 'delete', array(
1287 'id' => $create_result_2['id'],
1288 ));
1289 $this->callAPISuccess('contact', 'delete', array(
1290 'id' => $create_result_2['id'],
1291 ));
1292
1293 // Assert.
1294 $this->assertEquals(1, $get_result['api.relationship.get']['count']);
1295 $this->assertEquals($create_result_3['id'], $get_result['api.relationship.get']['values'][0]['contact_id_a']);
1296 }
1297
6a488035 1298 /**
fe482240 1299 * Verify that attempt to create individual contact with first, and last names and email succeeds.
6a488035 1300 */
00be9182 1301 public function testCreateIndividualWithNameEmail() {
6a488035
TO
1302 $params = array(
1303 'first_name' => 'abc3',
1304 'last_name' => 'xyz3',
1305 'contact_type' => 'Individual',
1306 'email' => 'man3@yahoo.com',
6a488035
TO
1307 );
1308
f6722559 1309 $contact = $this->callAPISuccess('contact', 'create', $params);
6a488035 1310
f6722559 1311 $this->callAPISuccess('contact', 'delete', $contact);
6a488035 1312 }
5896d037 1313
6a488035 1314 /**
eceb18cc 1315 * Verify that attempt to create individual contact with no data fails.
6a488035 1316 */
00be9182 1317 public function testCreateIndividualWithOutNameEmail() {
6a488035
TO
1318 $params = array(
1319 'contact_type' => 'Individual',
6a488035 1320 );
4b58ed3b 1321 $this->callAPIFailure('contact', 'create', $params);
6a488035 1322 }
5896d037 1323
6a488035 1324 /**
fe482240 1325 * Test create individual contact with first &last names, email and location type succeeds.
6a488035 1326 */
00be9182 1327 public function testCreateIndividualWithNameEmailLocationType() {
6a488035
TO
1328 $params = array(
1329 'first_name' => 'abc4',
1330 'last_name' => 'xyz4',
1331 'email' => 'man4@yahoo.com',
1332 'contact_type' => 'Individual',
1333 'location_type_id' => 1,
6a488035 1334 );
f6722559 1335 $result = $this->callAPISuccess('contact', 'create', $params);
6a488035 1336
f6722559 1337 $this->callAPISuccess('contact', 'delete', array('id' => $result['id']));
6a488035
TO
1338 }
1339
1340 /**
fe482240 1341 * Verify that when changing employers the old employer relationship becomes inactive.
6a488035 1342 */
00be9182 1343 public function testCreateIndividualWithEmployer() {
6a488035
TO
1344 $employer = $this->organizationCreate();
1345 $employer2 = $this->organizationCreate();
1346
1347 $params = array(
5896d037
TO
1348 'email' => 'man4@yahoo.com',
1349 'contact_type' => 'Individual',
1350 'employer_id' => $employer,
6a488035
TO
1351 );
1352
f6722559 1353 $result = $this->callAPISuccess('contact', 'create', $params);
1354 $relationships = $this->callAPISuccess('relationship', 'get', array(
6a488035
TO
1355 'contact_id_a' => $result['id'],
1356 'sequential' => 1,
1357 ));
1358
1359 $this->assertEquals($employer, $relationships['values'][0]['contact_id_b']);
1360
1361 // Add more random relationships to make the test more realistic
4b58ed3b
EM
1362 foreach (array('Employee of', 'Volunteer for') as $relationshipType) {
1363 $relTypeId = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_RelationshipType', $relationshipType, 'id', 'name_a_b');
1364 $this->callAPISuccess('relationship', 'create', array(
6a488035
TO
1365 'contact_id_a' => $result['id'],
1366 'contact_id_b' => $this->organizationCreate(),
1367 'is_active' => 1,
1368 'relationship_type_id' => $relTypeId,
1369 ));
6c6e6187 1370 }
6a488035
TO
1371
1372 // Add second employer
1373 $params['employer_id'] = $employer2;
1374 $params['id'] = $result['id'];
f6722559 1375 $result = $this->callAPISuccess('contact', 'create', $params);
6a488035 1376
f6722559 1377 $relationships = $this->callAPISuccess('relationship', 'get', array(
6a488035
TO
1378 'contact_id_a' => $result['id'],
1379 'sequential' => 1,
1380 'is_active' => 0,
1381 ));
1382
1383 $this->assertEquals($employer, $relationships['values'][0]['contact_id_b']);
1384 }
1385
1386 /**
fe482240 1387 * Verify that attempt to create household contact with details succeeds.
6a488035 1388 */
00be9182 1389 public function testCreateHouseholdDetails() {
6a488035
TO
1390 $params = array(
1391 'household_name' => 'abc8\'s House',
1392 'nick_name' => 'x House',
1393 'email' => 'man8@yahoo.com',
1394 'contact_type' => 'Household',
6a488035
TO
1395 );
1396
f6722559 1397 $contact = $this->callAPISuccess('contact', 'create', $params);
1398
f6722559 1399 $this->callAPISuccess('contact', 'delete', $contact);
6a488035 1400 }
5896d037 1401
6a488035 1402 /**
381fa321 1403 * Verify that attempt to create household contact with inadequate details fails.
6a488035 1404 */
00be9182 1405 public function testCreateHouseholdInadequateDetails() {
6a488035
TO
1406 $params = array(
1407 'nick_name' => 'x House',
1408 'email' => 'man8@yahoo.com',
1409 'contact_type' => 'Household',
6a488035 1410 );
4b58ed3b 1411 $this->callAPIFailure('contact', 'create', $params);
6a488035
TO
1412 }
1413
6a488035 1414 /**
381fa321 1415 * Verify successful update of individual contact.
6a488035 1416 */
00be9182 1417 public function testUpdateIndividualWithAll() {
381fa321 1418 // Insert a row in civicrm_contact creating individual contact.
6a488035
TO
1419 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1420 $op->execute($this->_dbconn,
bbfd46a5 1421 $this->createXMLDataSet(
6a488035
TO
1422 dirname(__FILE__) . '/dataset/contact_ind.xml'
1423 )
1424 );
1425
1426 $params = array(
1427 'id' => 23,
1428 'first_name' => 'abcd',
1429 'contact_type' => 'Individual',
1430 'nick_name' => 'This is nickname first',
1431 'do_not_email' => '1',
1432 'do_not_phone' => '1',
1433 'do_not_mail' => '1',
1434 'do_not_trade' => '1',
1435 'legal_identifier' => 'ABC23853ZZ2235',
1436 'external_identifier' => '1928837465',
1437 'image_URL' => 'http://some.url.com/image.jpg',
1438 'home_url' => 'http://www.example.org',
f6722559 1439
1440 );
43ef1263 1441
4b58ed3b 1442 $this->callAPISuccess('Contact', 'Update', $params);
f6722559 1443 $getResult = $this->callAPISuccess('Contact', 'Get', $params);
6a488035
TO
1444 unset($params['contact_id']);
1445 //Todo - neither API v2 or V3 are testing for home_url - not sure if it is being set.
4b58ed3b 1446 //reducing this test partially back to api v2 level to get it through
6a488035
TO
1447 unset($params['home_url']);
1448 foreach ($params as $key => $value) {
4b58ed3b 1449 $this->assertEquals($value, $getResult['values'][23][$key]);
6a488035 1450 }
381fa321 1451 // Check updated civicrm_contact against expected.
bbfd46a5 1452 $expected = $this->createXMLDataSet(
6a488035
TO
1453 dirname(__FILE__) . '/dataset/contact_ind_upd.xml'
1454 );
bbfd46a5 1455 $actual = new PHPUnit_Extensions_Database_DataSet_QueryDataSet(
6a488035
TO
1456 $this->_dbconn
1457 );
1458 $actual->addTable('civicrm_contact');
1459 $expected->matches($actual);
1460 }
1461
1462 /**
eceb18cc 1463 * Verify successful update of organization contact.
6a488035 1464 */
00be9182 1465 public function testUpdateOrganizationWithAll() {
381fa321 1466 // Insert a row in civicrm_contact creating organization contact
6a488035
TO
1467 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1468 $op->execute($this->_dbconn,
bbfd46a5 1469 $this->createXMLDataSet(
6a488035
TO
1470 dirname(__FILE__) . '/dataset/contact_org.xml'
1471 )
1472 );
1473
1474 $params = array(
1475 'id' => 24,
1476 'organization_name' => 'WebAccess India Pvt Ltd',
1477 'legal_name' => 'WebAccess',
1478 'sic_code' => 'ABC12DEF',
1479 'contact_type' => 'Organization',
6a488035
TO
1480 );
1481
4b58ed3b 1482 $this->callAPISuccess('Contact', 'Update', $params);
6a488035 1483
381fa321 1484 // Check updated civicrm_contact against expected.
bbfd46a5 1485 $expected = $this->createXMLDataSet(
6a488035
TO
1486 dirname(__FILE__) . '/dataset/contact_org_upd.xml'
1487 );
bbfd46a5 1488 $actual = new PHPUnit_Extensions_Database_DataSet_QueryDataSet(
6a488035
TO
1489 $this->_dbconn
1490 );
1491 $actual->addTable('civicrm_contact');
1492 $expected->matches($actual);
1493 }
1494
1495 /**
381fa321 1496 * Verify successful update of household contact.
6a488035 1497 */
381fa321 1498 public function testUpdateHouseholdWithAll() {
1499 // Insert a row in civicrm_contact creating household contact
6a488035
TO
1500 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1501 $op->execute($this->_dbconn,
bbfd46a5 1502 $this->createXMLDataSet(
6a488035
TO
1503 dirname(__FILE__) . '/dataset/contact_hld.xml'
1504 )
1505 );
1506
1507 $params = array(
1508 'id' => 25,
1509 'household_name' => 'ABC household',
1510 'nick_name' => 'ABC House',
1511 'contact_type' => 'Household',
6a488035
TO
1512 );
1513
f6722559 1514 $result = $this->callAPISuccess('Contact', 'Update', $params);
6a488035 1515
43ef1263
EM
1516 $expected = array(
1517 'contact_type' => 'Household',
1518 'is_opt_out' => 0,
1519 'sort_name' => 'ABC household',
1520 'display_name' => 'ABC household',
1521 'nick_name' => 'ABC House',
6a488035 1522 );
43ef1263 1523 $this->getAndCheck($expected, $result['id'], 'contact');
6a488035
TO
1524 }
1525
1526 /**
381fa321 1527 * Test civicrm_update() without contact type.
1528 *
1529 * Deliberately exclude contact_type as it should still cope using civicrm_api.
1530 *
1531 * CRM-7645.
6a488035 1532 */
6a488035 1533 public function testUpdateCreateWithID() {
381fa321 1534 // Insert a row in civicrm_contact creating individual contact.
6a488035
TO
1535 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1536 $op->execute($this->_dbconn,
bbfd46a5 1537 $this->createXMLDataSet(
6a488035
TO
1538 dirname(__FILE__) . '/dataset/contact_ind.xml'
1539 )
1540 );
1541
6a488035
TO
1542 $params = array(
1543 'id' => 23,
1544 'first_name' => 'abcd',
1545 'last_name' => 'wxyz',
6a488035 1546 );
4b58ed3b 1547 $this->callAPISuccess('Contact', 'Update', $params);
6a488035
TO
1548 }
1549
1550 /**
381fa321 1551 * Test civicrm_contact_delete() with no contact ID.
6a488035 1552 */
00be9182 1553 public function testContactDeleteNoID() {
6a488035
TO
1554 $params = array(
1555 'foo' => 'bar',
6a488035 1556 );
4b58ed3b 1557 $this->callAPIFailure('contact', 'delete', $params);
6a488035
TO
1558 }
1559
1560 /**
381fa321 1561 * Test civicrm_contact_delete() with error.
6a488035 1562 */
00be9182 1563 public function testContactDeleteError() {
f6722559 1564 $params = array('contact_id' => 999);
4b58ed3b 1565 $this->callAPIFailure('contact', 'delete', $params);
6a488035
TO
1566 }
1567
1568 /**
381fa321 1569 * Test civicrm_contact_delete().
6a488035 1570 */
00be9182 1571 public function testContactDelete() {
f6722559 1572 $contactID = $this->individualCreate();
6a488035 1573 $params = array(
5896d037 1574 'id' => $contactID,
6a488035 1575 );
4b58ed3b 1576 $this->callAPIAndDocument('contact', 'delete', $params, __FUNCTION__, __FILE__);
6a488035
TO
1577 }
1578
1579 /**
381fa321 1580 * Test civicrm_contact_get() return only first name.
6a488035
TO
1581 */
1582 public function testContactGetRetFirst() {
f6722559 1583 $contact = $this->callAPISuccess('contact', 'create', $this->_params);
6a488035
TO
1584 $params = array(
1585 'contact_id' => $contact['id'],
1586 'return_first_name' => TRUE,
1587 'sort' => 'first_name',
6a488035 1588 );
f6722559 1589 $result = $this->callAPISuccess('contact', 'get', $params);
4b58ed3b
EM
1590 $this->assertEquals(1, $result['count']);
1591 $this->assertEquals($contact['id'], $result['id']);
1592 $this->assertEquals('abc1', $result['values'][$contact['id']]['first_name']);
6a488035
TO
1593 }
1594
1595 /**
381fa321 1596 * Test civicrm_contact_get() return only first name & last name.
1597 *
1598 * Use comma separated string return with a space.
6a488035 1599 */
381fa321 1600 public function testContactGetReturnFirstLast() {
f6722559 1601 $contact = $this->callAPISuccess('contact', 'create', $this->_params);
6a488035
TO
1602 $params = array(
1603 'contact_id' => $contact['id'],
1604 'return' => 'first_name, last_name',
6a488035 1605 );
f6722559 1606 $result = $this->callAPISuccess('contact', 'getsingle', $params);
4b58ed3b
EM
1607 $this->assertEquals('abc1', $result['first_name']);
1608 $this->assertEquals('xyz1', $result['last_name']);
6a488035
TO
1609 //check that other defaults not returns
1610 $this->assertArrayNotHasKey('sort_name', $result);
1611 $params = array(
1612 'contact_id' => $contact['id'],
1613 'return' => 'first_name,last_name',
6a488035 1614 );
f6722559 1615 $result = $this->callAPISuccess('contact', 'getsingle', $params);
4b58ed3b
EM
1616 $this->assertEquals('abc1', $result['first_name']);
1617 $this->assertEquals('xyz1', $result['last_name']);
6a488035
TO
1618 //check that other defaults not returns
1619 $this->assertArrayNotHasKey('sort_name', $result);
1620 }
1621
1622 /**
381fa321 1623 * Test civicrm_contact_get() return only first name & last name.
1624 *
d177a2a6 1625 * Use comma separated string return without a space
6a488035 1626 */
381fa321 1627 public function testContactGetReturnFirstLastNoComma() {
f6722559 1628 $contact = $this->callAPISuccess('contact', 'create', $this->_params);
6a488035
TO
1629 $params = array(
1630 'contact_id' => $contact['id'],
1631 'return' => 'first_name,last_name',
6a488035 1632 );
f6722559 1633 $result = $this->callAPISuccess('contact', 'getsingle', $params);
4b58ed3b
EM
1634 $this->assertEquals('abc1', $result['first_name']);
1635 $this->assertEquals('xyz1', $result['last_name']);
6a488035
TO
1636 //check that other defaults not returns
1637 $this->assertArrayNotHasKey('sort_name', $result);
1638 }
1639
1640 /**
381fa321 1641 * Test civicrm_contact_get() with default return properties.
6a488035
TO
1642 */
1643 public function testContactGetRetDefault() {
43ef1263 1644 $contactID = $this->individualCreate();
6a488035 1645 $params = array(
43ef1263 1646 'contact_id' => $contactID,
6a488035 1647 'sort' => 'first_name',
6a488035 1648 );
f6722559 1649 $result = $this->callAPISuccess('contact', 'get', $params);
43ef1263
EM
1650 $this->assertEquals($contactID, $result['values'][$contactID]['contact_id']);
1651 $this->assertEquals('Anthony', $result['values'][$contactID]['first_name']);
6a488035
TO
1652 }
1653
1654 /**
381fa321 1655 * Test civicrm_contact_getquick() with empty name param.
6a488035
TO
1656 */
1657 public function testContactGetQuick() {
fe482240 1658 // Insert a row in civicrm_contact creating individual contact.
6a488035
TO
1659 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1660 $op->execute($this->_dbconn,
bbfd46a5 1661 $this->createXMLDataSet(
6a488035
TO
1662 dirname(__FILE__) . '/dataset/contact_17.xml'
1663 )
1664 );
1665 $op->execute($this->_dbconn,
bbfd46a5 1666 $this->createXMLDataSet(
6a488035
TO
1667 dirname(__FILE__) . '/dataset/email_contact_17.xml'
1668 )
1669 );
1670 $params = array(
1671 'name' => "T",
6a488035
TO
1672 );
1673
1d6020f1 1674 $result = $this->callAPISuccess('contact', 'getquick', $params);
fe482240 1675 $this->assertEquals(17, $result['values'][0]['id']);
6a488035
TO
1676 }
1677
1678 /**
fe482240 1679 * Test civicrm_contact_get) with empty params.
6a488035
TO
1680 */
1681 public function testContactGetEmptyParams() {
4b58ed3b 1682 $this->callAPISuccess('contact', 'get', array());
6a488035
TO
1683 }
1684
1685 /**
fe482240 1686 * Test civicrm_contact_get(,true) with no matches.
6a488035
TO
1687 */
1688 public function testContactGetOldParamsNoMatches() {
fe482240 1689 // Insert a row in civicrm_contact creating contact 17.
6a488035
TO
1690 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1691 $op->execute($this->_dbconn,
bbfd46a5 1692 $this->createXMLDataSet(
6a488035
TO
1693 dirname(__FILE__) . '/dataset/contact_17.xml'
1694 )
1695 );
1696
1697 $params = array(
1698 'first_name' => 'Fred',
6a488035 1699 );
f6722559 1700 $result = $this->callAPISuccess('contact', 'get', $params);
fe482240 1701 $this->assertEquals(0, $result['count']);
6a488035
TO
1702 }
1703
1704 /**
fe482240 1705 * Test civicrm_contact_get(,true) with one match.
6a488035
TO
1706 */
1707 public function testContactGetOldParamsOneMatch() {
fe482240 1708 // Insert a row in civicrm_contact creating contact 17
6a488035
TO
1709 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1710 $op->execute($this->_dbconn,
bbfd46a5 1711 $this->createXMLDataSet(dirname(__FILE__) . '/dataset/contact_17.xml'
6a488035
TO
1712 )
1713 );
1714
1715 $params = array(
1716 'first_name' => 'Test',
6a488035 1717 );
f6722559 1718 $result = $this->callAPISuccess('contact', 'get', $params);
fe482240
EM
1719 $this->assertEquals(17, $result['values'][17]['contact_id']);
1720 $this->assertEquals(17, $result['id']);
6a488035 1721 }
6a488035
TO
1722
1723 /**
fe482240 1724 * Test civicrm_contact_search_count().
6a488035
TO
1725 */
1726 public function testContactGetEmail() {
1727 $params = array(
1728 'email' => 'man2@yahoo.com',
1729 'contact_type' => 'Individual',
1730 'location_type_id' => 1,
6a488035
TO
1731 );
1732
f6722559 1733 $contact = $this->callAPISuccess('contact', 'create', $params);
1734
6a488035
TO
1735 $params = array(
1736 'email' => 'man2@yahoo.com',
6a488035 1737 );
f6722559 1738 $result = $this->callAPIAndDocument('contact', 'get', $params, __FUNCTION__, __FILE__);
c8747697 1739 $this->assertEquals('man2@yahoo.com', $result['values'][$result['id']]['email']);
6a488035 1740
f6722559 1741 $this->callAPISuccess('contact', 'delete', $contact);
6a488035
TO
1742 }
1743
37f7ae88 1744 /**
1745 * Ensure consistent return format for option group fields.
1746 */
1747 public function testSetPreferredCommunicationNull() {
1748 $contact = $this->callAPISuccess('contact', 'create', array_merge($this->_params, array(
1749 'preferred_communication_method' => array('Phone', 'SMS'),
1750 )));
1751 $preferredCommunicationMethod = $this->callAPISuccessGetValue('Contact', array(
1752 'id' => $contact['id'],
1753 'return' => 'preferred_communication_method',
1754 ));
1755 $this->assertNotEmpty($preferredCommunicationMethod);
1756 $contact = $this->callAPISuccess('contact', 'create', array_merge($this->_params, array(
1757 'preferred_communication_method' => 'null',
1758 'id' => $contact['id'],
1759 )));
1760 $preferredCommunicationMethod = $this->callAPISuccessGetValue('Contact', array(
1761 'id' => $contact['id'],
1762 'return' => 'preferred_communication_method',
1763 ));
1764 $this->assertEmpty($preferredCommunicationMethod);
1765 }
1766
86ab13b7 1767 /**
1768 * Ensure consistent return format for option group fields.
1769 */
1770 public function testPseudoFields() {
1771 $params = array(
1772 'preferred_communication_method' => array('Phone', 'SMS'),
1773 'preferred_language' => 'en_US',
1774 'gender_id' => 'Female',
1775 'prefix_id' => 'Mrs.',
1776 'suffix_id' => 'II',
1777 'communication_style_id' => 'Formal',
1778 );
1779
1780 $contact = $this->callAPISuccess('contact', 'create', array_merge($this->_params, $params));
1781
1782 $result = $this->callAPISuccess('contact', 'getsingle', array('id' => $contact['id']));
1783 $this->assertEquals('Both', $result['preferred_mail_format']);
1784
1785 $this->assertEquals('en_US', $result['preferred_language']);
1786 $this->assertEquals(1, $result['communication_style_id']);
1787 $this->assertEquals(1, $result['gender_id']);
1788 $this->assertEquals('Female', $result['gender']);
1789 $this->assertEquals('Mrs.', $result['individual_prefix']);
1790 $this->assertEquals(1, $result['prefix_id']);
1791 $this->assertEquals('II', $result['individual_suffix']);
1792 $this->assertEquals(CRM_Core_PseudoConstant::getKey("CRM_Contact_BAO_Contact", 'suffix_id', 'II'), $result['suffix_id']);
1793 $this->callAPISuccess('contact', 'delete', $contact);
1794 $this->assertEquals(array(
1795 CRM_Core_PseudoConstant::getKey("CRM_Contact_BAO_Contact", 'preferred_communication_method', 'Phone'),
1796 CRM_Core_PseudoConstant::getKey("CRM_Contact_BAO_Contact", 'preferred_communication_method', 'SMS'),
1797 ), $result['preferred_communication_method']);
1798 }
1799
1800
b1f09bea 1801 /**
fe482240
EM
1802 * Test birth date parameters.
1803 *
1804 * These include value, array & birth_date_high, birth_date_low
1805 * && deceased.
b1f09bea 1806 */
4b58ed3b 1807 public function testContactGetBirthDate() {
b1f09bea
E
1808 $contact1 = $this->callAPISuccess('contact', 'create', array_merge($this->_params, array('birth_date' => 'first day of next month - 2 years')));
1809 $contact2 = $this->callAPISuccess('contact', 'create', array_merge($this->_params, array('birth_date' => 'first day of next month - 5 years')));
1810 $contact3 = $this->callAPISuccess('contact', 'create', array_merge($this->_params, array('birth_date' => 'first day of next month -20 years')));
1811
1812 $result = $this->callAPISuccess('contact', 'get', array());
1813 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -2 years')), $result['values'][$contact1['id']]['birth_date']);
1814 $result = $this->callAPISuccess('contact', 'get', array('birth_date' => 'first day of next month -5 years'));
1815 $this->assertEquals(1, $result['count']);
1816 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -5 years')), $result['values'][$contact2['id']]['birth_date']);
1817 $result = $this->callAPISuccess('contact', 'get', array('birth_date_high' => date('Y-m-d', strtotime('-6 years'))));
1818 $this->assertEquals(1, $result['count']);
1819 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -20 years')), $result['values'][$contact3['id']]['birth_date']);
5896d037 1820 $result = $this->callAPISuccess('contact', 'get', array(
92915c55
TO
1821 'birth_date_low' => date('Y-m-d', strtotime('-6 years')),
1822 'birth_date_high' => date('Y-m-d', strtotime('- 3 years')),
1823 ));
b1f09bea
E
1824 $this->assertEquals(1, $result['count']);
1825 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -5 years')), $result['values'][$contact2['id']]['birth_date']);
5896d037 1826 $result = $this->callAPISuccess('contact', 'get', array(
92915c55
TO
1827 'birth_date_low' => '-6 years',
1828 'birth_date_high' => '- 3 years',
1829 ));
9f60788a
EM
1830 $this->assertEquals(1, $result['count']);
1831 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -5 years')), $result['values'][$contact2['id']]['birth_date']);
b1f09bea
E
1832 }
1833
d0bfb983 1834 /**
1835 * Test Address parameters
1836 *
1837 * This include state_province, state_province_name, country
1838 */
1839 public function testContactGetWithAddressFields() {
1840 $individuals = array(
1841 array(
1842 'first_name' => 'abc1',
1843 'contact_type' => 'Individual',
1844 'last_name' => 'xyz1',
1845 'api.address.create' => array(
1846 'country' => 'United States',
1847 'state_province_id' => 'Michigan',
1848 'location_type_id' => 1,
1849 ),
1850 ),
1851 array(
1852 'first_name' => 'abc2',
1853 'contact_type' => 'Individual',
1854 'last_name' => 'xyz2',
1855 'api.address.create' => array(
1856 'country' => 'United States',
1857 'state_province_id' => 'Alabama',
1858 'location_type_id' => 1,
1859 ),
1860 ),
1861 );
1862 foreach ($individuals as $params) {
1863 $contact = $this->callAPISuccess('contact', 'create', $params);
1864 }
1865
1866 // Check whether Contact get API return successfully with below Address params.
1867 $fieldsToTest = array(
1868 'state_province_name' => 'Michigan',
1869 'state_province' => 'Michigan',
1870 'country' => 'United States',
1871 'state_province_name' => array('IN' => array('Michigan', 'Alabama')),
1872 'state_province' => array('IN' => array('Michigan', 'Alabama')),
1873 );
1874 foreach ($fieldsToTest as $field => $value) {
1875 $getParams = array(
1876 'id' => $contact['id'],
1877 $field => $value,
1878 );
41a74135 1879 $result = $this->callAPISuccess('Contact', 'get', $getParams);
1880 $this->assertEquals(1, $result['count']);
d0bfb983 1881 }
1882 }
1883
b1f09bea 1884 /**
fe482240
EM
1885 * Test Deceased date parameters.
1886 *
1887 * These include value, array & Deceased_date_high, Deceased date_low
d177a2a6 1888 * && deceased.
b1f09bea 1889 */
4b58ed3b 1890 public function testContactGetDeceasedDate() {
b1f09bea
E
1891 $contact1 = $this->callAPISuccess('contact', 'create', array_merge($this->_params, array('deceased_date' => 'first day of next month - 2 years')));
1892 $contact2 = $this->callAPISuccess('contact', 'create', array_merge($this->_params, array('deceased_date' => 'first day of next month - 5 years')));
1893 $contact3 = $this->callAPISuccess('contact', 'create', array_merge($this->_params, array('deceased_date' => 'first day of next month -20 years')));
1894
1895 $result = $this->callAPISuccess('contact', 'get', array());
1896 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -2 years')), $result['values'][$contact1['id']]['deceased_date']);
1897 $result = $this->callAPISuccess('contact', 'get', array('deceased_date' => 'first day of next month -5 years'));
1898 $this->assertEquals(1, $result['count']);
1899 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -5 years')), $result['values'][$contact2['id']]['deceased_date']);
1900 $result = $this->callAPISuccess('contact', 'get', array('deceased_date_high' => date('Y-m-d', strtotime('-6 years'))));
1901 $this->assertEquals(1, $result['count']);
1902 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -20 years')), $result['values'][$contact3['id']]['deceased_date']);
5896d037 1903 $result = $this->callAPISuccess('contact', 'get', array(
92915c55
TO
1904 'deceased_date_low' => '-6 years',
1905 'deceased_date_high' => date('Y-m-d', strtotime('- 3 years')),
1906 ));
b1f09bea
E
1907 $this->assertEquals(1, $result['count']);
1908 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -5 years')), $result['values'][$contact2['id']]['deceased_date']);
1909 }
1910
e635f9d4 1911 /**
fe482240 1912 * Test for Contact.get id=@user:username.
e635f9d4 1913 */
00be9182 1914 public function testContactGetByUsername() {
fe482240 1915 // Setup - create contact with a uf-match.
e635f9d4
TO
1916 $cid = $this->individualCreate(array(
1917 'contact_type' => 'Individual',
1918 'first_name' => 'testGetByUsername',
1919 'last_name' => 'testGetByUsername',
1920 ));
1921
1922 $ufMatchParams = array(
1923 'domain_id' => CRM_Core_Config::domainID(),
1924 'uf_id' => 99,
1925 'uf_name' => 'the-email-matching-key-is-not-really-the-username',
1926 'contact_id' => $cid,
1927 );
1928 $ufMatch = CRM_Core_BAO_UFMatch::create($ufMatchParams);
1929 $this->assertTrue(is_numeric($ufMatch->id));
1930
1931 // setup - mock the calls to CRM_Utils_System_*::getUfId
1932 $userSystem = $this->getMock('CRM_Utils_System_UnitTests', array('getUfId'));
1933 $userSystem->expects($this->once())
1934 ->method('getUfId')
1935 ->with($this->equalTo('exampleUser'))
1936 ->will($this->returnValue(99));
1937 CRM_Core_Config::singleton()->userSystem = $userSystem;
1938
1939 // perform a lookup
1940 $result = $this->callAPISuccess('Contact', 'get', array(
e635f9d4
TO
1941 'id' => '@user:exampleUser',
1942 ));
1943 $this->assertEquals('testGetByUsername', $result['values'][$cid]['first_name']);
1944 }
1945
265cc07d 1946 /**
eceb18cc 1947 * Test to check return works OK.
265cc07d 1948 */
00be9182 1949 public function testContactGetReturnValues() {
701a69da 1950 $extraParams = array(
1951 'nick_name' => 'Bob',
1952 'phone' => '456',
1953 'email' => 'e@mail.com',
1954 );
265cc07d 1955 $contactID = $this->individualCreate($extraParams);
1956 //actually it turns out the above doesn't create a phone
6c6e6187 1957 $this->callAPISuccess('phone', 'create', array('contact_id' => $contactID, 'phone' => '456'));
265cc07d 1958 $result = $this->callAPISuccess('contact', 'getsingle', array('id' => $contactID));
1959 foreach ($extraParams as $key => $value) {
1960 $this->assertEquals($result[$key], $value);
1961 }
1962 //now we check they are still returned with 'return' key
5896d037 1963 $result = $this->callAPISuccess('contact', 'getsingle', array(
92915c55
TO
1964 'id' => $contactID,
1965 'return' => array_keys($extraParams),
1966 ));
265cc07d 1967 foreach ($extraParams as $key => $value) {
1968 $this->assertEquals($result[$key], $value);
1969 }
1970 }
1971
701a69da 1972 /**
1973 * Test creating multiple phones using chaining.
1974 *
1975 * @throws \Exception
1976 */
00be9182 1977 public function testCRM13252MultipleChainedPhones() {
265cc07d 1978 $contactID = $this->householdCreate();
1979 $this->callAPISuccessGetCount('phone', array('contact_id' => $contactID), 0);
1980 $params = array(
5896d037
TO
1981 'contact_id' => $contactID,
1982 'household_name' => 'Household 1',
1983 'contact_type' => 'Household',
1984 'api.phone.create' => array(
265cc07d 1985 0 => array(
1986 'phone' => '111-111-1111',
1987 'location_type_id' => 1,
1988 'phone_type_id' => 1,
1989 ),
1990 1 => array(
1991 'phone' => '222-222-2222',
1992 'location_type_id' => 1,
1993 'phone_type_id' => 2,
21dfd5f5
TO
1994 ),
1995 ),
265cc07d 1996 );
4b58ed3b 1997 $this->callAPISuccess('contact', 'create', $params);
265cc07d 1998 $this->callAPISuccessGetCount('phone', array('contact_id' => $contactID), 2);
1999
2000 }
5896d037 2001
e635f9d4 2002 /**
fe482240 2003 * Test for Contact.get id=@user:username (with an invalid username).
e635f9d4 2004 */
00be9182 2005 public function testContactGetByUnknownUsername() {
e635f9d4
TO
2006 // setup - mock the calls to CRM_Utils_System_*::getUfId
2007 $userSystem = $this->getMock('CRM_Utils_System_UnitTests', array('getUfId'));
2008 $userSystem->expects($this->once())
2009 ->method('getUfId')
2010 ->with($this->equalTo('exampleUser'))
2011 ->will($this->returnValue(NULL));
2012 CRM_Core_Config::singleton()->userSystem = $userSystem;
2013
2014 // perform a lookup
2015 $result = $this->callAPIFailure('Contact', 'get', array(
e635f9d4
TO
2016 'id' => '@user:exampleUser',
2017 ));
2018 $this->assertRegExp('/cannot be resolved to a contact ID/', $result['error_message']);
2019 }
2020
6a488035 2021 /**
701a69da 2022 * Verify attempt to create individual with chained arrays and sequential.
48bb2598
JV
2023 */
2024 public function testGetIndividualWithChainedArraysAndSequential() {
2025 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__, __FILE__);
2026 $params['custom_' . $ids['custom_field_id']] = "custom string";
2027
84b51197 2028 $moreIDs = $this->CustomGroupMultipleCreateWithFields();
48bb2598
JV
2029 $params = array(
2030 'sequential' => 1,
2031 'first_name' => 'abc3',
2032 'last_name' => 'xyz3',
2033 'contact_type' => 'Individual',
2034 'email' => 'man3@yahoo.com',
2035 'api.website.create' => array(
2036 array(
2037 'url' => "http://civicrm.org",
2038 ),
2039 array(
2040 'url' => "https://civicrm.org",
2041 ),
2042 ),
2043 );
2044
2045 $result = $this->callAPISuccess('Contact', 'create', $params);
2046
48bb2598
JV
2047 // delete the contact and custom groups
2048 $this->callAPISuccess('contact', 'delete', array('id' => $result['id']));
2049 $this->customGroupDelete($ids['custom_group_id']);
84b51197 2050 $this->customGroupDelete($moreIDs['custom_group_id']);
48bb2598
JV
2051
2052 $this->assertEquals($result['id'], $result['values'][0]['id']);
2053 $this->assertArrayKeyExists('api.website.create', $result['values'][0]);
2054 }
2055
2056 /**
701a69da 2057 * Verify attempt to create individual with chained arrays.
6a488035 2058 */
00be9182 2059 public function testGetIndividualWithChainedArrays() {
6a488035
TO
2060 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__, __FILE__);
2061 $params['custom_' . $ids['custom_field_id']] = "custom string";
2062
381fa321 2063 $moreIDs = $this->CustomGroupMultipleCreateWithFields();
5c49fee0 2064 $description = "This demonstrates the usage of chained api functions.\nIn this case no notes or custom fields have been created.";
5896d037
TO
2065 $subfile = "APIChainedArray";
2066 $params = array(
6a488035
TO
2067 'first_name' => 'abc3',
2068 'last_name' => 'xyz3',
2069 'contact_type' => 'Individual',
2070 'email' => 'man3@yahoo.com',
6a488035
TO
2071 'api.contribution.create' => array(
2072 'receive_date' => '2010-01-01',
2073 'total_amount' => 100.00,
2074 'financial_type_id' => 1,
2075 'payment_instrument_id' => 1,
2076 'non_deductible_amount' => 10.00,
2077 'fee_amount' => 50.00,
2078 'net_amount' => 90.00,
2079 'trxn_id' => 12345,
2080 'invoice_id' => 67890,
2081 'source' => 'SSF',
2082 'contribution_status_id' => 1,
2083 ),
2084 'api.contribution.create.1' => array(
2085 'receive_date' => '2011-01-01',
2086 'total_amount' => 120.00,
6c6e6187 2087 'financial_type_id' => $this->_financialTypeId = 1,
6a488035
TO
2088 'payment_instrument_id' => 1,
2089 'non_deductible_amount' => 10.00,
2090 'fee_amount' => 50.00,
2091 'net_amount' => 90.00,
2092 'trxn_id' => 12335,
2093 'invoice_id' => 67830,
2094 'source' => 'SSF',
2095 'contribution_status_id' => 1,
2096 ),
2097 'api.website.create' => array(
2098 array(
2099 'url' => "http://civicrm.org",
2100 ),
2101 ),
2102 );
2103
f6722559 2104 $result = $this->callAPISuccess('Contact', 'create', $params);
6a488035 2105 $params = array(
f6722559 2106 'id' => $result['id'],
6a488035
TO
2107 'api.website.get' => array(),
2108 'api.Contribution.get' => array(
2109 'total_amount' => '120.00',
5896d037
TO
2110 ),
2111 'api.CustomValue.get' => 1,
6a488035
TO
2112 'api.Note.get' => 1,
2113 );
f6722559 2114 $result = $this->callAPIAndDocument('Contact', 'Get', $params, __FUNCTION__, __FILE__, $description, $subfile);
6a488035 2115 // delete the contact
f6722559 2116 $this->callAPISuccess('contact', 'delete', $result);
6a488035 2117 $this->customGroupDelete($ids['custom_group_id']);
381fa321 2118 $this->customGroupDelete($moreIDs['custom_group_id']);
4b58ed3b
EM
2119 $this->assertEquals(0, $result['values'][$result['id']]['api.website.get']['is_error']);
2120 $this->assertEquals("http://civicrm.org", $result['values'][$result['id']]['api.website.get']['values'][0]['url']);
6a488035
TO
2121 }
2122
a77b0380 2123 /**
701a69da 2124 * Verify attempt to create individual with chained arrays and sequential.
a77b0380
JV
2125 *
2126 * See https://issues.civicrm.org/jira/browse/CRM-15815
2127 */
2128 public function testCreateIndividualWithChainedArrayAndSequential() {
2129 $params = array(
2130 'sequential' => 1,
2131 'first_name' => 'abc5',
2132 'last_name' => 'xyz5',
2133 'contact_type' => 'Individual',
2134 'email' => 'woman5@yahoo.com',
2135 'api.phone.create' => array(
2136 array('phone' => '03-231 07 95'),
2137 array('phone' => '03-232 51 62'),
2138 ),
2139 'api.website.create' => array(
2140 'url' => 'http://civicrm.org',
2141 ),
2142 );
2143 $result = $this->callAPISuccess('Contact', 'create', $params);
2144
2145 // I could try to parse the result to see whether the two phone numbers
2146 // and the website are there, but I am not sure about the correct format.
2147 // So I will just fetch it again before checking.
2148 // See also http://forum.civicrm.org/index.php/topic,35393.0.html
2149 $params = array(
2150 'sequential' => 1,
2151 'id' => $result['id'],
2152 'api.website.get' => array(),
2153 'api.phone.get' => array(),
2154 );
2155 $result = $this->callAPISuccess('Contact', 'get', $params);
2156
2157 // delete the contact
2158 $this->callAPISuccess('contact', 'delete', $result);
2159
2160 $this->assertEquals(2, $result['values'][0]['api.phone.get']['count']);
2161 $this->assertEquals(1, $result['values'][0]['api.website.get']['count']);
2162 }
2163
701a69da 2164 /**
2165 * Test retrieving an individual with chained array syntax.
2166 */
00be9182 2167 public function testGetIndividualWithChainedArraysFormats() {
5c49fee0 2168 $description = "This demonstrates the usage of chained api functions.\nIn this case no notes or custom fields have been created.";
6a488035
TO
2169 $subfile = "APIChainedArrayFormats";
2170 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__, __FILE__);
2171 $params['custom_' . $ids['custom_field_id']] = "custom string";
2172
381fa321 2173 $moreIDs = $this->CustomGroupMultipleCreateWithFields();
6a488035
TO
2174 $params = array(
2175 'first_name' => 'abc3',
2176 'last_name' => 'xyz3',
2177 'contact_type' => 'Individual',
2178 'email' => 'man3@yahoo.com',
6a488035
TO
2179 'api.contribution.create' => array(
2180 'receive_date' => '2010-01-01',
2181 'total_amount' => 100.00,
f6722559 2182 'financial_type_id' => $this->_financialTypeId,
6a488035
TO
2183 'payment_instrument_id' => 1,
2184 'non_deductible_amount' => 10.00,
2185 'fee_amount' => 50.00,
2186 'net_amount' => 90.00,
2187 'source' => 'SSF',
2188 'contribution_status_id' => 1,
2189 ),
2190 'api.contribution.create.1' => array(
2191 'receive_date' => '2011-01-01',
2192 'total_amount' => 120.00,
f6722559 2193 'financial_type_id' => $this->_financialTypeId,
6a488035
TO
2194 'payment_instrument_id' => 1,
2195 'non_deductible_amount' => 10.00,
2196 'fee_amount' => 50.00,
2197 'net_amount' => 90.00,
2198 'source' => 'SSF',
2199 'contribution_status_id' => 1,
2200 ),
2201 'api.website.create' => array(
2202 array(
2203 'url' => "http://civicrm.org",
2204 ),
2205 ),
2206 );
2207
f6722559 2208 $result = $this->callAPISuccess('Contact', 'create', $params);
6a488035 2209 $params = array(
f6722559 2210 'id' => $result['id'],
6a488035
TO
2211 'api.website.getValue' => array('return' => 'url'),
2212 'api.Contribution.getCount' => array(),
2213 'api.CustomValue.get' => 1,
2214 'api.Note.get' => 1,
2215 'api.Membership.getCount' => array(),
2216 );
f6722559 2217 $result = $this->callAPIAndDocument('Contact', 'Get', $params, __FUNCTION__, __FILE__, $description, $subfile);
4b58ed3b
EM
2218 $this->assertEquals(2, $result['values'][$result['id']]['api.Contribution.getCount']);
2219 $this->assertEquals(0, $result['values'][$result['id']]['api.Note.get']['is_error']);
2220 $this->assertEquals("http://civicrm.org", $result['values'][$result['id']]['api.website.getValue']);
6a488035 2221
f6722559 2222 $this->callAPISuccess('contact', 'delete', $result);
6a488035 2223 $this->customGroupDelete($ids['custom_group_id']);
381fa321 2224 $this->customGroupDelete($moreIDs['custom_group_id']);
6a488035
TO
2225 }
2226
381fa321 2227 /**
2228 * Test complex chaining.
2229 */
00be9182 2230 public function testGetIndividualWithChainedArraysAndMultipleCustom() {
6a488035
TO
2231 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__, __FILE__);
2232 $params['custom_' . $ids['custom_field_id']] = "custom string";
381fa321 2233 $moreIDs = $this->CustomGroupMultipleCreateWithFields();
2234 $andMoreIDs = $this->CustomGroupMultipleCreateWithFields(array(
92915c55
TO
2235 'title' => "another group",
2236 'name' => 'another name',
2237 ));
5c49fee0 2238 $description = "This demonstrates the usage of chained api functions with multiple custom fields.";
6a488035
TO
2239 $subfile = "APIChainedArrayMultipleCustom";
2240 $params = array(
2241 'first_name' => 'abc3',
2242 'last_name' => 'xyz3',
2243 'contact_type' => 'Individual',
2244 'email' => 'man3@yahoo.com',
6a488035
TO
2245 'api.contribution.create' => array(
2246 'receive_date' => '2010-01-01',
2247 'total_amount' => 100.00,
5896d037 2248 'financial_type_id' => 1,
6a488035
TO
2249 'payment_instrument_id' => 1,
2250 'non_deductible_amount' => 10.00,
2251 'fee_amount' => 50.00,
2252 'net_amount' => 90.00,
2253 'trxn_id' => 12345,
2254 'invoice_id' => 67890,
2255 'source' => 'SSF',
2256 'contribution_status_id' => 1,
2257 ),
2258 'api.contribution.create.1' => array(
2259 'receive_date' => '2011-01-01',
2260 'total_amount' => 120.00,
5896d037 2261 'financial_type_id' => 1,
6a488035
TO
2262 'payment_instrument_id' => 1,
2263 'non_deductible_amount' => 10.00,
2264 'fee_amount' => 50.00,
2265 'net_amount' => 90.00,
2266 'trxn_id' => 12335,
2267 'invoice_id' => 67830,
2268 'source' => 'SSF',
2269 'contribution_status_id' => 1,
2270 ),
2271 'api.website.create' => array(
2272 array(
2273 'url' => "http://civicrm.org",
2274 ),
2275 ),
2276 'custom_' . $ids['custom_field_id'] => "value 1",
381fa321 2277 'custom_' . $moreIDs['custom_field_id'][0] => "value 2",
2278 'custom_' . $moreIDs['custom_field_id'][1] => "warm beer",
2279 'custom_' . $andMoreIDs['custom_field_id'][1] => "vegemite",
6a488035
TO
2280 );
2281
f6722559 2282 $result = $this->callAPISuccess('Contact', 'create', $params);
2283 $result = $this->callAPISuccess('Contact', 'create', array(
6c6e6187 2284 'contact_type' => 'Individual',
5896d037
TO
2285 'id' => $result['id'],
2286 'custom_' .
381fa321 2287 $moreIDs['custom_field_id'][0] => "value 3",
5896d037
TO
2288 'custom_' .
2289 $ids['custom_field_id'] => "value 4",
2290 ));
6a488035
TO
2291
2292 $params = array(
f6722559 2293 'id' => $result['id'],
6a488035
TO
2294 'api.website.getValue' => array('return' => 'url'),
2295 'api.Contribution.getCount' => array(),
2296 'api.CustomValue.get' => 1,
2297 );
f6722559 2298 $result = $this->callAPIAndDocument('Contact', 'Get', $params, __FUNCTION__, __FILE__, $description, $subfile);
2299
6a488035 2300 $this->customGroupDelete($ids['custom_group_id']);
381fa321 2301 $this->customGroupDelete($moreIDs['custom_group_id']);
2302 $this->customGroupDelete($andMoreIDs['custom_group_id']);
4b58ed3b
EM
2303 $this->assertEquals(0, $result['values'][$result['id']]['api.CustomValue.get']['is_error']);
2304 $this->assertEquals('http://civicrm.org', $result['values'][$result['id']]['api.website.getValue']);
6a488035 2305 }
5896d037 2306
d424ffde 2307 /**
381fa321 2308 * Test checks usage of $values to pick & choose inputs.
6a488035 2309 */
00be9182 2310 public function testChainingValuesCreate() {
5c49fee0
CW
2311 $description = "This demonstrates the usage of chained api functions. Specifically it has one 'parent function' &
2312 2 child functions - one receives values from the parent (Contact) and the other child (Tag).";
6a488035
TO
2313 $subfile = "APIChainedArrayValuesFromSiblingFunction";
2314 $params = array(
6c6e6187 2315 'display_name' => 'batman',
5896d037 2316 'contact_type' => 'Individual',
701a69da 2317 'api.tag.create' => array(
2318 'name' => '$value.id',
2319 'description' => '$value.display_name',
2320 'format.only_id' => 1,
2321 ),
6a488035
TO
2322 'api.entity_tag.create' => array('tag_id' => '$value.api.tag.create'),
2323 );
f6722559 2324 $result = $this->callAPIAndDocument('Contact', 'Create', $params, __FUNCTION__, __FILE__, $description, $subfile);
6a488035 2325 $this->assertEquals(0, $result['values'][$result['id']]['api.entity_tag.create']['is_error']);
f6722559 2326
6a488035
TO
2327 $tablesToTruncate = array(
2328 'civicrm_contact',
2329 'civicrm_activity',
2330 'civicrm_entity_tag',
2331 'civicrm_tag',
2332 );
2333 $this->quickCleanup($tablesToTruncate, TRUE);
2334 }
2335
d424ffde 2336 /**
fe482240 2337 * Test TrueFalse format - I couldn't come up with an easy way to get an error on Get.
6a488035 2338 */
00be9182 2339 public function testContactGetFormatIsSuccessTrue() {
6a488035
TO
2340 $this->createContactFromXML();
2341 $description = "This demonstrates use of the 'format.is_success' param.
2342 This param causes only the success or otherwise of the function to be returned as BOOLEAN";
2343 $subfile = "FormatIsSuccess_True";
5896d037
TO
2344 $params = array('id' => 17, 'format.is_success' => 1);
2345 $result = $this->callAPIAndDocument('Contact', 'Get', $params, __FUNCTION__, __FILE__, $description, $subfile);
6a488035 2346 $this->assertEquals(1, $result);
f6722559 2347 $this->callAPISuccess('Contact', 'Delete', $params);
6a488035 2348 }
5896d037 2349
d424ffde 2350 /**
fe482240 2351 * Test TrueFalse format.
6a488035 2352 */
00be9182 2353 public function testContactCreateFormatIsSuccessFalse() {
6a488035
TO
2354
2355 $description = "This demonstrates use of the 'format.is_success' param.
2356 This param causes only the success or otherwise of the function to be returned as BOOLEAN";
2357 $subfile = "FormatIsSuccess_Fail";
5896d037
TO
2358 $params = array('id' => 500, 'format.is_success' => 1);
2359 $result = $this->callAPIAndDocument('Contact', 'Create', $params, __FUNCTION__, __FILE__, $description, $subfile);
6a488035
TO
2360 $this->assertEquals(0, $result);
2361 }
5896d037 2362
d424ffde 2363 /**
fe482240 2364 * Test Single Entity format.
6a488035 2365 */
fe482240 2366 public function testContactGetSingleEntityArray() {
6a488035
TO
2367 $this->createContactFromXML();
2368 $description = "This demonstrates use of the 'format.single_entity_array' param.
5c49fee0
CW
2369 This param causes the only contact to be returned as an array without the other levels.
2370 It will be ignored if there is not exactly 1 result";
6a488035 2371 $subfile = "GetSingleContact";
5896d037
TO
2372 $params = array('id' => 17);
2373 $result = $this->callAPIAndDocument('Contact', 'GetSingle', $params, __FUNCTION__, __FILE__, $description, $subfile);
4b58ed3b 2374 $this->assertEquals('Test Contact', $result['display_name']);
f6722559 2375 $this->callAPISuccess('Contact', 'Delete', $params);
6a488035
TO
2376 }
2377
d424ffde 2378 /**
381fa321 2379 * Test Single Entity format.
6a488035 2380 */
fe482240 2381 public function testContactGetFormatCountOnly() {
6a488035 2382 $this->createContactFromXML();
5c49fee0
CW
2383 $description = "This demonstrates use of the 'getCount' action.
2384 This param causes the count of the only function to be returned as an integer.";
5896d037 2385 $params = array('id' => 17);
381fa321 2386 $result = $this->callAPIAndDocument('Contact', 'GetCount', $params, __FUNCTION__, __FILE__, $description,
84b51197 2387 'GetCountContact');
4b58ed3b 2388 $this->assertEquals('1', $result);
f6722559 2389 $this->callAPISuccess('Contact', 'Delete', $params);
6a488035 2390 }
5896d037 2391
d424ffde 2392 /**
381fa321 2393 * Test id only format.
408b79bf 2394 */
fe482240 2395 public function testContactGetFormatIDOnly() {
6a488035 2396 $this->createContactFromXML();
5c49fee0
CW
2397 $description = "This demonstrates use of the 'format.id_only' param.
2398 This param causes the id of the only entity to be returned as an integer.
2399 It will be ignored if there is not exactly 1 result";
6a488035 2400 $subfile = "FormatOnlyID";
5896d037
TO
2401 $params = array('id' => 17, 'format.only_id' => 1);
2402 $result = $this->callAPIAndDocument('Contact', 'Get', $params, __FUNCTION__, __FILE__, $description, $subfile);
4b58ed3b 2403 $this->assertEquals('17', $result);
f6722559 2404 $this->callAPISuccess('Contact', 'Delete', $params);
6a488035
TO
2405 }
2406
d424ffde 2407 /**
381fa321 2408 * Test id only format.
408b79bf 2409 */
00be9182 2410 public function testContactGetFormatSingleValue() {
6a488035
TO
2411 $this->createContactFromXML();
2412 $description = "This demonstrates use of the 'format.single_value' param.
5c49fee0
CW
2413 This param causes only a single value of the only entity to be returned as an string.
2414 It will be ignored if there is not exactly 1 result";
4b58ed3b 2415 $subFile = "FormatSingleValue";
5896d037 2416 $params = array('id' => 17, 'return' => 'display_name');
a828d7b8 2417 $result = $this->callAPIAndDocument('Contact', 'getvalue', $params, __FUNCTION__, __FILE__, $description, $subFile);
4b58ed3b 2418 $this->assertEquals('Test Contact', $result);
f6722559 2419 $this->callAPISuccess('Contact', 'Delete', $params);
6a488035
TO
2420 }
2421
b2130237 2422 /**
381fa321 2423 * Test that permissions are respected when creating contacts.
b2130237 2424 */
00be9182 2425 public function testContactCreationPermissions() {
6a488035 2426 $params = array(
6c6e6187 2427 'contact_type' => 'Individual',
5896d037 2428 'first_name' => 'Foo',
6a488035
TO
2429 'last_name' => 'Bear',
2430 'check_permissions' => TRUE,
6a488035
TO
2431 );
2432 $config = CRM_Core_Config::singleton();
2433 $config->userPermissionClass->permissions = array('access CiviCRM');
d0e1eff2 2434 $result = $this->callAPIFailure('contact', 'create', $params);
1644b908 2435 $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');
6a488035
TO
2436
2437 $config->userPermissionClass->permissions = array('access CiviCRM', 'add contacts', 'import contacts');
701a69da 2438 $this->callAPISuccess('contact', 'create', $params);
6a488035
TO
2439 }
2440
fa6448fa
EM
2441 /**
2442 * Test that delete with skip undelete respects permissions.
2443 */
2444 public function testContactDeletePermissions() {
2445 $contactID = $this->individualCreate();
2446 CRM_Core_Config::singleton()->userPermissionClass->permissions = array('access CiviCRM');
2447 $this->callAPIFailure('Contact', 'delete', array(
2448 'id' => $contactID,
2449 'check_permissions' => 1,
2450 'skip_undelete' => 1,
2451 ));
2452 $this->callAPISuccess('Contact', 'delete', array(
2453 'id' => $contactID,
2454 'check_permissions' => 0,
2455 'skip_undelete' => 1,
2456 ));
2457 }
2458
381fa321 2459 /**
2460 * Test update with check permissions set.
2461 */
00be9182 2462 public function testContactUpdatePermissions() {
5896d037
TO
2463 $params = array(
2464 'contact_type' => 'Individual',
2465 'first_name' => 'Foo',
2466 'last_name' => 'Bear',
21dfd5f5 2467 'check_permissions' => TRUE,
5896d037 2468 );
f6722559 2469 $result = $this->callAPISuccess('contact', 'create', $params);
6a488035 2470 $config = CRM_Core_Config::singleton();
5896d037
TO
2471 $params = array(
2472 'id' => $result['id'],
2473 'contact_type' => 'Individual',
2474 'last_name' => 'Bar',
21dfd5f5 2475 'check_permissions' => TRUE,
5896d037 2476 );
6a488035
TO
2477
2478 $config->userPermissionClass->permissions = array('access CiviCRM');
d0e1eff2 2479 $result = $this->callAPIFailure('contact', 'update', $params);
0a61b6e2 2480 $this->assertEquals('Permission denied to modify contact record', $result['error_message']);
6a488035 2481
5896d037
TO
2482 $config->userPermissionClass->permissions = array(
2483 'access CiviCRM',
2484 'add contacts',
2485 'view all contacts',
2486 'edit all contacts',
21dfd5f5 2487 'import contacts',
5896d037 2488 );
701a69da 2489 $this->callAPISuccess('contact', 'update', $params);
6a488035
TO
2490 }
2491
381fa321 2492 /**
2493 * Set up helper to create a contact.
2494 */
00be9182 2495 public function createContactFromXML() {
381fa321 2496 // Insert a row in civicrm_contact creating contact 17.
6a488035
TO
2497 $op = new PHPUnit_Extensions_Database_Operation_Insert();
2498 $op->execute($this->_dbconn,
bbfd46a5 2499 $this->createXMLDataSet(
6a488035
TO
2500 dirname(__FILE__) . '/dataset/contact_17.xml'
2501 )
2502 );
2503 }
2504
381fa321 2505 /**
2506 * Test contact proximity api.
2507 */
00be9182 2508 public function testContactProximity() {
6a488035
TO
2509 // first create a contact with a SF location with a specific
2510 // geocode
2511 $contactID = $this->organizationCreate();
2512
2513 // now create the address
2514 $params = array(
2515 'street_address' => '123 Main Street',
2516 'city' => 'San Francisco',
2517 'is_primary' => 1,
2518 'country_id' => 1228,
2519 'state_province_id' => 1004,
2520 'geo_code_1' => '37.79',
2521 'geo_code_2' => '-122.40',
2522 'location_type_id' => 1,
2523 'contact_id' => $contactID,
6a488035
TO
2524 );
2525
f6722559 2526 $result = $this->callAPISuccess('address', 'create', $params);
ba4a1892 2527 $this->assertEquals(1, $result['count']);
6a488035
TO
2528
2529 // now do a proximity search with a close enough geocode and hope to match
2530 // that specific contact only!
2531 $proxParams = array(
2532 'latitude' => 37.7,
2533 'longitude' => -122.3,
2534 'unit' => 'mile',
2535 'distance' => 10,
6a488035 2536 );
f6722559 2537 $result = $this->callAPISuccess('contact', 'proximity', $proxParams);
ba4a1892 2538 $this->assertEquals(1, $result['count']);
6a488035 2539 }
60ec9f43
E
2540
2541 /**
381fa321 2542 * Test that Ajax API permission is sufficient to access getquick api.
2543 *
1d6020f1 2544 * (note that getquick api is required for autocomplete & has ACL permissions applied)
60ec9f43 2545 */
fe482240 2546 public function testGetquickPermissionCRM13744() {
60ec9f43 2547 CRM_Core_Config::singleton()->userPermissionClass->permissions = array('access CiviEvent');
4b58ed3b 2548 $this->callAPIFailure('contact', 'getquick', array('name' => 'b', 'check_permissions' => TRUE));
60ec9f43 2549 CRM_Core_Config::singleton()->userPermissionClass->permissions = array('access CiviCRM');
4b58ed3b 2550 $this->callAPISuccess('contact', 'getquick', array('name' => 'b', 'check_permissions' => TRUE));
60ec9f43 2551 CRM_Core_Config::singleton()->userPermissionClass->permissions = array('access AJAX API');
4b58ed3b 2552 $this->callAPISuccess('contact', 'getquick', array('name' => 'b', 'check_permissions' => TRUE));
60ec9f43 2553 }
9c8096cb 2554
08f4ab8d 2555 /**
2556 * Test that getquick returns contacts with an exact first name match first.
2baa1e00 2557 *
2558 * The search string 'b' & 'bob' both return ordered by sort_name if includeOrderByClause
2559 * is true (default) but if it is false then matches are returned in ID order.
613643e0 2560 *
2561 * @dataProvider getSearchSortOptions
08f4ab8d 2562 */
613643e0 2563 public function testGetQuickExactFirst($searchParameters, $settings, $firstContact, $secondContact = NULL) {
08f4ab8d 2564 $this->getQuickSearchSampleData();
613643e0 2565 $this->callAPISuccess('Setting', 'create', $settings);
2566 $result = $this->callAPISuccess('contact', 'getquick', $searchParameters);
2567 $this->assertEquals($firstContact, $result['values'][0]['sort_name']);
2568 $this->assertEquals($secondContact, $result['values'][1]['sort_name']);
2569 $this->callAPISuccess('Setting', 'create', array('includeWildCardInName' => TRUE, 'includeOrderByClause' => TRUE));
2570 }
2571
2572 public function getSearchSortOptions() {
2573 $firstAlphabeticalContactBySortName = 'A Bobby, Bobby';
2574 $secondAlphabeticalContactBySortName = 'Aadvark, Bob';
2575 $secondAlphabeticalContactWithEmailBySortName = 'Bob, Bob';
2576 $firstAlphabeticalContactFirstNameBob = 'Aadvark, Bob';
2577 $secondAlphabeticalContactFirstNameBob = 'Bob, Bob';
2578 $firstByIDContactFirstNameBob = 'Bob, Bob';
2579 $secondByIDContactFirstNameBob = 'K Bobby, Bob';
2580 $firstContactByID = 'Bob, Bob';
2581 $secondContactByID = 'E Bobby, Bobby';
2582 $bobLikeEmail = 'A Bobby, Bobby';
2583
2584 return array(
2585 'empty_search_basic' => array(
2586 'search_parameters' => array('name' => '%'),
2587 'settings' => array('includeWildCardInName' => TRUE, 'includeOrderByClause' => TRUE),
2588 'first_contact' => $firstAlphabeticalContactBySortName,
2589 'second_contact' => $secondAlphabeticalContactBySortName,
2590 ),
2591 'empty_search_basic_no_wildcard' => array(
2592 'search_parameters' => array('name' => '%'),
2593 'settings' => array('includeWildCardInName' => FALSE, 'includeOrderByClause' => TRUE),
2594 'first_contact' => $firstAlphabeticalContactBySortName,
2595 'second_contact' => $secondAlphabeticalContactBySortName,
2596 ),
2597 'single_letter_search_basic' => array(
2598 'search_parameters' => array('name' => 'b'),
2599 'settings' => array('includeWildCardInName' => TRUE, 'includeOrderByClause' => TRUE),
2600 'first_contact' => $firstAlphabeticalContactBySortName,
2601 'second_contact' => $secondAlphabeticalContactBySortName,
2602 ),
2603 'bob_search_basic' => array(
2604 'search_parameters' => array('name' => 'bob'),
2605 'settings' => array('includeWildCardInName' => TRUE, 'includeOrderByClause' => TRUE),
2606 'first_contact' => $firstAlphabeticalContactBySortName,
2607 'second_contact' => $secondAlphabeticalContactBySortName,
2608 ),
2609 'bob_search_no_orderby' => array(
2610 'search_parameters' => array('name' => 'bob'),
2611 'settings' => array('includeWildCardInName' => TRUE, 'includeOrderByClause' => FALSE),
2612 'first_contact' => $firstContactByID,
2613 'second_contact' => $secondContactByID,
2614 ),
2615 'bob_search_no_wildcard' => array(
2616 'search_parameters' => array('name' => 'bob'),
2617 'settings' => array('includeWildCardInName' => FALSE, 'includeOrderByClause' => TRUE),
2618 'second_contact' => $bobLikeEmail,
2619 'first_contact' => $secondAlphabeticalContactFirstNameBob,
2620 ),
2621 // This should be the same as just no wildcard as if we had an exactMatch while searching by
2622 // sort name it would rise to the top CRM-19547
2623 'bob_search_no_wildcard_no_orderby' => array(
2624 'search_parameters' => array('name' => 'bob'),
2625 'settings' => array('includeWildCardInName' => FALSE, 'includeOrderByClause' => TRUE),
2626 'second_contact' => $bobLikeEmail,
2627 'first_contact' => $secondAlphabeticalContactFirstNameBob,
2628 ),
2629 'first_name_search_basic' => array(
2630 'search_parameters' => array('name' => 'bob', 'field_name' => 'first_name'),
2631 'settings' => array('includeWildCardInName' => TRUE, 'includeOrderByClause' => TRUE),
2632 'first_contact' => $firstAlphabeticalContactFirstNameBob,
2633 'second_contact' => $secondAlphabeticalContactFirstNameBob,
2634 ),
2635 'first_name_search_no_wildcard' => array(
2636 'search_parameters' => array('name' => 'bob', 'field_name' => 'first_name'),
2637 'settings' => array('includeWildCardInName' => FALSE, 'includeOrderByClause' => TRUE),
2638 'first_contact' => $firstAlphabeticalContactFirstNameBob,
2639 'second_contact' => $secondAlphabeticalContactFirstNameBob,
2640 ),
2641 'first_name_search_no_orderby' => array(
2642 'search_parameters' => array('name' => 'bob', 'field_name' => 'first_name'),
2643 'settings' => array('includeWildCardInName' => TRUE, 'includeOrderByClause' => FALSE),
2644 'first_contact' => $firstByIDContactFirstNameBob,
2645 'second_contact' => $secondByIDContactFirstNameBob,
2646 ),
2647 'email_search_basic' => array(
2648 'search_parameters' => array('name' => 'bob', 'field_name' => 'email', 'table_name' => 'eml'),
2649 'settings' => array('includeWildCardInName' => FALSE, 'includeOrderByClause' => TRUE),
2650 'first_contact' => $firstAlphabeticalContactBySortName,
2651 'second_contact' => $secondAlphabeticalContactWithEmailBySortName,
2652 ),
2653 );
2baa1e00 2654 }
2655
e9e27a80 2656 /**
2657 * Test that getquick returns contacts with an exact first name match first.
2658 */
2659 public function testGetQuickEmail() {
2660 $this->getQuickSearchSampleData();
1ca22999 2661 $loggedInContactID = $this->createLoggedInUser();
e9e27a80 2662 $result = $this->callAPISuccess('contact', 'getquick', array(
2663 'name' => 'c',
2664 ));
2665 $expectedData = array(
613643e0 2666 'A Bobby, Bobby :: bob@bobby.com',
e9e27a80 2667 'Bob, Bob :: bob@bob.com',
2668 'C Bobby, Bobby',
e9e27a80 2669 'H Bobby, Bobby :: bob@h.com',
1ca22999 2670 'Second Domain',
2671 $this->callAPISuccessGetValue('Contact', array('id' => $loggedInContactID, 'return' => 'last_name')) . ', Logged In :: anthony_anderson@civicrm.org',
e9e27a80 2672 );
1ca22999 2673 $this->assertEquals(6, $result['count']);
e9e27a80 2674 foreach ($expectedData as $index => $value) {
2675 $this->assertEquals($value, $result['values'][$index]['data']);
2676 }
7f6f3df1 2677 $result = $this->callAPISuccess('contact', 'getquick', array(
2678 'name' => 'h.',
2679 ));
2680 $expectedData = array(
2681 'H Bobby, Bobby :: bob@h.com',
2682 );
2683 foreach ($expectedData as $index => $value) {
2684 $this->assertEquals($value, $result['values'][$index]['data']);
2685 }
2686 $this->callAPISuccess('Setting', 'create', array('includeWildCardInName' => FALSE));
2687 $result = $this->callAPISuccess('contact', 'getquick', array(
2688 'name' => 'h.',
2689 ));
2690 $this->callAPISuccess('Setting', 'create', array('includeWildCardInName' => TRUE));
2691 $this->assertEquals(0, $result['count']);
e9e27a80 2692 }
2693
c37a2d66 2694 /**
2695 * Test that getquick returns contacts with an exact first name match first.
2696 */
2697 public function testGetQuickEmailACL() {
2698 $this->getQuickSearchSampleData();
1ca22999 2699 $loggedInContactID = $this->createLoggedInUser();
c37a2d66 2700 CRM_Core_Config::singleton()->userPermissionClass->permissions = array();
2701 $result = $this->callAPISuccess('contact', 'getquick', array(
2702 'name' => 'c',
2703 ));
2704 $this->assertEquals(0, $result['count']);
2705
2706 $this->hookClass->setHook('civicrm_aclWhereClause', array($this, 'aclWhereNoBobH'));
1ca22999 2707 CRM_Contact_BAO_Contact_Permission::cache($loggedInContactID, CRM_Core_Permission::VIEW, TRUE);
c37a2d66 2708 $result = $this->callAPISuccess('contact', 'getquick', array(
2709 'name' => 'c',
2710 ));
1ca22999 2711
2712 // Without the acl it would be 6 like the previous email getquick test.
2713 $this->assertEquals(5, $result['count']);
c37a2d66 2714 $expectedData = array(
613643e0 2715 'A Bobby, Bobby :: bob@bobby.com',
c37a2d66 2716 'Bob, Bob :: bob@bob.com',
2717 'C Bobby, Bobby',
1ca22999 2718 'Second Domain',
2719 $this->callAPISuccessGetValue('Contact', array('id' => $loggedInContactID, 'return' => 'last_name')) . ', Logged In :: anthony_anderson@civicrm.org',
c37a2d66 2720 );
2721 foreach ($expectedData as $index => $value) {
2722 $this->assertEquals($value, $result['values'][$index]['data']);
2723 }
2724 }
2725
2baa1e00 2726 /**
2727 * Test that getquick returns contacts with an exact first name match first.
2728 */
2729 public function testGetQuickExternalID() {
2730 $this->getQuickSearchSampleData();
2731 $result = $this->callAPISuccess('contact', 'getquick', array(
2732 'name' => 'b',
2733 'field_name' => 'external_identifier',
2734 'table_name' => 'cc',
2735 ));
2736 $this->assertEquals(0, $result['count']);
2737 $result = $this->callAPISuccess('contact', 'getquick', array(
2738 'name' => 'abc',
2739 'field_name' => 'external_identifier',
2740 'table_name' => 'cc',
2741 ));
2742 $this->assertEquals(1, $result['count']);
2743 $this->assertEquals('Bob, Bob', $result['values'][0]['sort_name']);
2744 }
2745
2746 /**
2747 * Test that getquick returns contacts with an exact first name match first.
2748 */
2749 public function testGetQuickID() {
1ca22999 2750 $max = CRM_Core_DAO::singleValueQuery("SELECT max(id) FROM civicrm_contact");
2baa1e00 2751 $this->getQuickSearchSampleData();
2752 $result = $this->callAPISuccess('contact', 'getquick', array(
1ca22999 2753 'name' => $max + 2,
2baa1e00 2754 'field_name' => 'id',
2755 'table_name' => 'cc',
2756 ));
2757 $this->assertEquals(1, $result['count']);
613643e0 2758 $this->assertEquals('E Bobby, Bobby', $result['values'][0]['sort_name']);
2baa1e00 2759 $result = $this->callAPISuccess('contact', 'getquick', array(
1ca22999 2760 'name' => $max + 2,
2baa1e00 2761 'field_name' => 'contact_id',
2762 'table_name' => 'cc',
2763 ));
2764 $this->assertEquals(1, $result['count']);
613643e0 2765 $this->assertEquals('E Bobby, Bobby', $result['values'][0]['sort_name']);
2baa1e00 2766 }
2767
2768 /**
2769 * Test that getquick returns contacts with an exact first name match first.
ef3fd279 2770 *
2771 * Depending on the setting the sort name sort might click in next or not - test!
2baa1e00 2772 */
2773 public function testGetQuickFirstName() {
2774 $this->getQuickSearchSampleData();
ef3fd279 2775 $this->callAPISuccess('Setting', 'create', array('includeOrderByClause' => TRUE));
2baa1e00 2776 $result = $this->callAPISuccess('contact', 'getquick', array(
2777 'name' => 'Bob',
2778 'field_name' => 'first_name',
2779 'table_name' => 'cc',
2780 ));
e9e27a80 2781 $expected = array(
613643e0 2782 'Aadvark, Bob',
e9e27a80 2783 'Bob, Bob',
2784 'K Bobby, Bob',
2785 'A Bobby, Bobby',
2786 );
2787
2788 foreach ($expected as $index => $value) {
2789 $this->assertEquals($value, $result['values'][$index]['sort_name']);
2790 }
08f4ab8d 2791 $this->callAPISuccess('Setting', 'create', array('includeOrderByClause' => FALSE));
2792 $result = $this->callAPISuccess('contact', 'getquick', array('name' => 'bob'));
2793 $this->assertEquals('Bob, Bob', $result['values'][0]['sort_name']);
613643e0 2794 $this->assertEquals('E Bobby, Bobby', $result['values'][1]['sort_name']);
08f4ab8d 2795 }
2796
1b9c2802 2797 /**
2798 * Test that getquick applies ACLs.
2799 */
2800 public function testGetQuickFirstNameACLs() {
2801 $this->getQuickSearchSampleData();
2802 $userID = $this->createLoggedInUser();
613643e0 2803 $this->callAPISuccess('Setting', 'create', array('includeOrderByClause' => TRUE, 'search_autocomplete_count' => 15));
1b9c2802 2804 CRM_Core_Config::singleton()->userPermissionClass->permissions = array();
2805 $result = $this->callAPISuccess('contact', 'getquick', array(
2806 'name' => 'Bob',
2807 'field_name' => 'first_name',
2808 'table_name' => 'cc',
2809 ));
2810 $this->assertEquals(0, $result['count']);
2811
2812 $this->hookClass->setHook('civicrm_aclWhereClause', array($this, 'aclWhereNoBobH'));
2813 CRM_Contact_BAO_Contact_Permission::cache($userID, CRM_Core_Permission::VIEW, TRUE);
2814 $result = $this->callAPISuccess('contact', 'getquick', array(
2815 'name' => 'Bob',
2816 'field_name' => 'first_name',
2817 'table_name' => 'cc',
2818 ));
613643e0 2819 $this->assertEquals('K Bobby, Bob', $result['values'][2]['sort_name']);
1b9c2802 2820 // Without the ACL 9 would be bob@h.com.
613643e0 2821 $this->assertEquals('I Bobby, Bobby', $result['values'][10]['sort_name']);
1b9c2802 2822 }
2823
2824 /**
2825 * Full results returned.
2826 * @implements CRM_Utils_Hook::aclWhereClause
2827 *
2828 * @param string $type
2829 * @param array $tables
2830 * @param array $whereTables
2831 * @param int $contactID
2832 * @param string $where
2833 */
2834 public function aclWhereNoBobH($type, &$tables, &$whereTables, &$contactID, &$where) {
c37a2d66 2835 $where = " (email <> 'bob@h.com' OR email IS NULL) ";
1b9c2802 2836 $whereTables['civicrm_email'] = "LEFT JOIN civicrm_email e ON contact_a.id = e.contact_id";
2837 }
2838
e9e27a80 2839 /**
2840 * Test that getquick returns contacts with an exact last name match first.
2841 */
2842 public function testGetQuickLastName() {
2843 $this->getQuickSearchSampleData();
2844 $this->callAPISuccess('Setting', 'create', array('includeOrderByClause' => TRUE));
2845 $result = $this->callAPISuccess('contact', 'getquick', array(
2846 'name' => 'Bob',
2847 'field_name' => 'last_name',
2848 'table_name' => 'cc',
2849 ));
2850 $expected = array(
2851 'Bob, Bob',
2852 'A Bobby, Bobby',
36575b09 2853 'B Bobby, Bobby',
e9e27a80 2854 );
2855
2856 foreach ($expected as $index => $value) {
2857 $this->assertEquals($value, $result['values'][$index]['sort_name']);
2858 }
2859 $this->callAPISuccess('Setting', 'create', array('includeOrderByClause' => FALSE));
2860 $result = $this->callAPISuccess('contact', 'getquick', array('name' => 'bob'));
2861 $this->assertEquals('Bob, Bob :: bob@bob.com', $result['values'][0]['data']);
2862 }
2863
2864 /**
2865 * Test that getquick returns contacts by city.
2866 */
2867 public function testGetQuickCity() {
2868 $this->getQuickSearchSampleData();
2869 $result = $this->callAPISuccess('contact', 'getquick', array(
2870 'name' => 'o',
2871 'field_name' => 'city',
2872 'table_name' => 'sts',
2873 ));
2874 $this->assertEquals('B Bobby, Bobby :: Toronto', $result['values'][0]['data']);
2875 $result = $this->callAPISuccess('contact', 'getquick', array(
2876 'name' => 'n',
2877 'field_name' => 'city',
2878 'table_name' => 'sts',
2879 ));
2880 $this->assertEquals('B Bobby, Bobby :: Toronto', $result['values'][0]['data']);
2881 $this->assertEquals('C Bobby, Bobby :: Whanganui', $result['values'][1]['data']);
2882 }
2883
08f4ab8d 2884 /**
2885 * Set up some sample data for testing quicksearch.
2886 */
2887 public function getQuickSearchSampleData() {
2888 $contacts = array(
e9e27a80 2889 array('first_name' => 'Bob', 'last_name' => 'Bob', 'external_identifier' => 'abc', 'email' => 'bob@bob.com'),
613643e0 2890 array('first_name' => 'Bobby', 'last_name' => 'E Bobby', 'external_identifier' => 'abcd'),
36575b09 2891 array(
2892 'first_name' => 'Bobby',
2893 'last_name' => 'B Bobby',
2894 'external_identifier' => 'bcd',
2895 'api.address.create' => array(
2896 'street_address' => 'Sesame Street',
2897 'city' => 'Toronto',
2898 'location_type_id' => 1,
2899 ),
2900 ),
2901 array(
2902 'first_name' => 'Bobby',
2903 'last_name' => 'C Bobby',
2904 'external_identifier' => 'bcde',
2905 'api.address.create' => array(
2906 'street_address' => 'Te huarahi',
2907 'city' => 'Whanganui',
2908 'location_type_id' => 1,
2909 ),
2910 ),
2baa1e00 2911 array('first_name' => 'Bobby', 'last_name' => 'D Bobby', 'external_identifier' => 'efg'),
613643e0 2912 array('first_name' => 'Bobby', 'last_name' => 'A Bobby', 'external_identifier' => 'hij', 'email' => 'bob@bobby.com'),
2baa1e00 2913 array('first_name' => 'Bobby', 'last_name' => 'F Bobby', 'external_identifier' => 'klm'),
2914 array('first_name' => 'Bobby', 'last_name' => 'G Bobby', 'external_identifier' => 'nop'),
e9e27a80 2915 array('first_name' => 'Bobby', 'last_name' => 'H Bobby', 'external_identifier' => 'qrs', 'email' => 'bob@h.com'),
2baa1e00 2916 array('first_name' => 'Bobby', 'last_name' => 'I Bobby'),
2917 array('first_name' => 'Bobby', 'last_name' => 'J Bobby'),
2918 array('first_name' => 'Bob', 'last_name' => 'K Bobby', 'external_identifier' => 'bcdef'),
613643e0 2919 array('first_name' => 'Bob', 'last_name' => 'Aadvark'),
08f4ab8d 2920 );
2921 foreach ($contacts as $type => $contact) {
2922 $contact['contact_type'] = 'Individual';
2923 $this->callAPISuccess('Contact', 'create', $contact);
2924 }
2925 }
2926
b2130237 2927 /**
381fa321 2928 * Test get ref api - gets a list of references to an entity.
b2130237 2929 */
00be9182 2930 public function testGetReferenceCounts() {
9c8096cb
TO
2931 $result = $this->callAPISuccess('Contact', 'create', array(
2932 'first_name' => 'Testily',
2933 'last_name' => 'McHaste',
2934 'contact_type' => 'Individual',
2935 'api.Address.replace' => array(
2936 'values' => array(),
2937 ),
2938 'api.Email.replace' => array(
2939 'values' => array(
2940 array(
2941 'email' => 'spam@dev.null',
2942 'is_primary' => 0,
2943 'location_type_id' => 1,
21dfd5f5 2944 ),
9c8096cb
TO
2945 ),
2946 ),
2947 'api.Phone.replace' => array(
2948 'values' => array(
2949 array(
2950 'phone' => '234-567-0001',
2951 'is_primary' => 1,
2952 'location_type_id' => 1,
2953 ),
2954 array(
2955 'phone' => '234-567-0002',
2956 'is_primary' => 0,
2957 'location_type_id' => 1,
2958 ),
2959 ),
2960 ),
2961 ));
2962
2963 //$dao = new CRM_Contact_BAO_Contact();
2964 //$dao->id = $result['id'];
2965 //$this->assertTrue((bool) $dao->find(TRUE));
2966 //
2967 //$refCounts = $dao->getReferenceCounts();
2968 //$this->assertTrue(is_array($refCounts));
2969 //$refCountsIdx = CRM_Utils_Array::index(array('name'), $refCounts);
2970
2971 $refCounts = $this->callAPISuccess('Contact', 'getrefcount', array(
21dfd5f5 2972 'id' => $result['id'],
9c8096cb
TO
2973 ));
2974 $refCountsIdx = CRM_Utils_Array::index(array('name'), $refCounts['values']);
2975
2976 $this->assertEquals(1, $refCountsIdx['sql:civicrm_email:contact_id']['count']);
2977 $this->assertEquals('civicrm_email', $refCountsIdx['sql:civicrm_email:contact_id']['table']);
2978 $this->assertEquals(2, $refCountsIdx['sql:civicrm_phone:contact_id']['count']);
2979 $this->assertEquals('civicrm_phone', $refCountsIdx['sql:civicrm_phone:contact_id']['table']);
2980 $this->assertTrue(!isset($refCountsIdx['sql:civicrm_address:contact_id']));
2981 }
2982
701a69da 2983 /**
2984 * Test the use of sql operators.
2985 */
00be9182 2986 public function testSQLOperatorsOnContactAPI() {
a75c13cc
EM
2987 $this->individualCreate();
2988 $this->organizationCreate();
2989 $this->householdCreate();
2990 $contacts = $this->callAPISuccess('contact', 'get', array('legal_name' => array('IS NOT NULL' => TRUE)));
2991 $this->assertEquals($contacts['count'], CRM_Core_DAO::singleValueQuery('select count(*) FROM civicrm_contact WHERE legal_name IS NOT NULL'));
2992 $contacts = $this->callAPISuccess('contact', 'get', array('legal_name' => array('IS NULL' => TRUE)));
2993 $this->assertEquals($contacts['count'], CRM_Core_DAO::singleValueQuery('select count(*) FROM civicrm_contact WHERE legal_name IS NULL'));
2994 }
9bee5ea2 2995
9bee5ea2 2996 /**
fe482240 2997 * CRM-14743 - test api respects search operators.
9bee5ea2 2998 */
00be9182 2999 public function testGetModifiedDateByOperators() {
9bee5ea2
EM
3000 $preExistingContactCount = CRM_Core_DAO::singleValueQuery('select count(*) FROM civicrm_contact');
3001 $contact1 = $this->individualCreate();
3002 $sql = "UPDATE civicrm_contact SET created_date = '2012-01-01', modified_date = '2013-01-01' WHERE id = " . $contact1;
3003 CRM_Core_DAO::executeQuery($sql);
3004 $contact2 = $this->individualCreate();
3005 $sql = "UPDATE civicrm_contact SET created_date = '2012-02-01', modified_date = '2013-02-01' WHERE id = " . $contact2;
3006 CRM_Core_DAO::executeQuery($sql);
3007 $contact3 = $this->householdCreate();
3008 $sql = "UPDATE civicrm_contact SET created_date = '2012-03-01', modified_date = '2013-03-01' WHERE id = " . $contact3;
3009 CRM_Core_DAO::executeQuery($sql);
3010 $contacts = $this->callAPISuccess('contact', 'get', array('modified_date' => array('<' => '2014-01-01')));
3011 $this->assertEquals($contacts['count'], 3);
3012 $contacts = $this->callAPISuccess('contact', 'get', array('modified_date' => array('>' => '2014-01-01')));
3013 $this->assertEquals($contacts['count'], $preExistingContactCount);
3014 }
2134e310 3015
2134e310 3016 /**
fe482240 3017 * CRM-14743 - test api respects search operators.
2134e310 3018 */
00be9182 3019 public function testGetCreatedDateByOperators() {
2134e310
EM
3020 $preExistingContactCount = CRM_Core_DAO::singleValueQuery('select count(*) FROM civicrm_contact');
3021 $contact1 = $this->individualCreate();
3022 $sql = "UPDATE civicrm_contact SET created_date = '2012-01-01' WHERE id = " . $contact1;
3023 CRM_Core_DAO::executeQuery($sql);
3024 $contact2 = $this->individualCreate();
3025 $sql = "UPDATE civicrm_contact SET created_date = '2012-02-01' WHERE id = " . $contact2;
3026 CRM_Core_DAO::executeQuery($sql);
3027 $contact3 = $this->householdCreate();
3028 $sql = "UPDATE civicrm_contact SET created_date = '2012-03-01' WHERE id = " . $contact3;
3029 CRM_Core_DAO::executeQuery($sql);
3030 $contacts = $this->callAPISuccess('contact', 'get', array('created_date' => array('<' => '2014-01-01')));
3031 $this->assertEquals($contacts['count'], 3);
3032 $contacts = $this->callAPISuccess('contact', 'get', array('created_date' => array('>' => '2014-01-01')));
3033 $this->assertEquals($contacts['count'], $preExistingContactCount);
3034 }
e5fccefb
EM
3035
3036 /**
fe482240 3037 * CRM-14263 check that API is not affected by search profile related bug.
e5fccefb 3038 */
5896d037 3039 public function testReturnCityProfile() {
e5fccefb
EM
3040 $contactID = $this->individualCreate();
3041 CRM_Core_Config::singleton()->defaultSearchProfileID = 1;
5896d037 3042 $this->callAPISuccess('address', 'create', array(
92915c55
TO
3043 'contact_id' => $contactID,
3044 'city' => 'Cool City',
3045 'location_type_id' => 1,
3046 ));
e5fccefb
EM
3047 $result = $this->callAPISuccess('contact', 'get', array('city' => 'Cool City', 'return' => 'contact_type'));
3048 $this->assertEquals(1, $result['count']);
3049 }
eaa112a5 3050
eaa112a5 3051 /**
701a69da 3052 * CRM-15443 - ensure getlist api does not return deleted contacts.
eaa112a5 3053 */
00be9182 3054 public function testGetlistExcludeConditions() {
eaa112a5 3055 $name = md5(time());
45fcf8b7 3056 $contact = $this->individualCreate(array('last_name' => $name));
381fa321 3057 $this->individualCreate(array('last_name' => $name, 'is_deceased' => 1));
3058 $this->individualCreate(array('last_name' => $name, 'is_deleted' => 1));
3059 // We should get all but the deleted contact.
eaa112a5 3060 $result = $this->callAPISuccess('contact', 'getlist', array('input' => $name));
ba4a1892 3061 $this->assertEquals(2, $result['count']);
381fa321 3062 // Force-exclude the deceased contact.
5896d037 3063 $result = $this->callAPISuccess('contact', 'getlist', array(
92915c55
TO
3064 'input' => $name,
3065 'params' => array('is_deceased' => 0),
3066 ));
ba4a1892
TM
3067 $this->assertEquals(1, $result['count']);
3068 $this->assertEquals($contact, $result['values'][0]['id']);
eaa112a5 3069 }
92776611
CW
3070
3071 /**
fe482240 3072 * Test contact getactions.
92776611 3073 */
00be9182 3074 public function testGetActions() {
92776611
CW
3075 $description = "Getting the available actions for an entity.";
3076 $result = $this->callAPIAndDocument($this->_entity, 'getactions', array(), __FUNCTION__, __FILE__, $description);
3077 $expected = array(
3078 'create',
3079 'delete',
3080 'get',
3081 'getactions',
3082 'getcount',
3083 'getfields',
3084 'getlist',
3085 'getoptions',
3086 'getquick',
3087 'getrefcount',
3088 'getsingle',
3089 'getvalue',
3090 'merge',
3091 'proximity',
3092 'replace',
3093 'setvalue',
3094 'update',
3095 );
3096 $deprecated = array(
3097 'update',
3098 'getquick',
3099 );
3100 foreach ($expected as $action) {
3101 $this->assertTrue(in_array($action, $result['values']), "Expected action $action");
3102 }
3103 foreach ($deprecated as $action) {
3104 $this->assertArrayKeyExists($action, $result['deprecated']);
3105 }
3106 }
96025800 3107
ffe87781 3108 /**
3109 * Test the duplicate check function.
3110 */
3111 public function testDuplicateCheck() {
fedc3428 3112 $harry = array(
ffe87781 3113 'first_name' => 'Harry',
3114 'last_name' => 'Potter',
3115 'email' => 'harry@hogwarts.edu',
3116 'contact_type' => 'Individual',
fedc3428 3117 );
3118 $this->callAPISuccess('Contact', 'create', $harry);
ffe87781 3119 $result = $this->callAPISuccess('Contact', 'duplicatecheck', array(
fedc3428 3120 'match' => $harry,
ffe87781 3121 ));
3122
3123 $this->assertEquals(1, $result['count']);
3124 $result = $this->callAPISuccess('Contact', 'duplicatecheck', array(
3125 'match' => array(
3126 'first_name' => 'Harry',
3127 'last_name' => 'Potter',
3128 'email' => 'no5@privet.drive',
3129 'contact_type' => 'Individual',
3130 ),
3131 ));
3132 $this->assertEquals(0, $result['count']);
fedc3428 3133 $this->callAPIFailure('Contact', 'create', array_merge($harry, array('dupe_check' => 1)));
ffe87781 3134 }
3135
a2dd33d3 3136 /**
3137 * Test the duplicate check function.
3138 */
3139 public function testDuplicateCheckRuleNotReserved() {
3140 $harry = array(
3141 'first_name' => 'Harry',
3142 'last_name' => 'Potter',
3143 'email' => 'harry@hogwarts.edu',
3144 'contact_type' => 'Individual',
3145 );
3146 $defaultRule = $this->callAPISuccess('RuleGroup', 'getsingle', array('used' => 'Unsupervised', 'is_reserved' => 1));
3147 $this->callAPISuccess('RuleGroup', 'create', array('id' => $defaultRule['id'], 'is_reserved' => 0));
3148 $this->callAPISuccess('Contact', 'create', $harry);
3149 $result = $this->callAPISuccess('Contact', 'duplicatecheck', array(
3150 'match' => $harry,
3151 ));
3152
3153 $this->assertEquals(1, $result['count']);
3154 $this->callAPISuccess('RuleGroup', 'create', array('id' => $defaultRule['id'], 'is_reserved' => 1));
3155 }
3156
3157 /**
3158 * Test variants on retrieving contact by type.
3159 */
46b3417a
CW
3160 public function testGetByContactType() {
3161 $individual = $this->callAPISuccess('Contact', 'create', array(
3162 'email' => 'individual@test.com',
3163 'contact_type' => 'Individual',
3164 ));
3165 $household = $this->callAPISuccess('Contact', 'create', array(
3166 'household_name' => 'household@test.com',
3167 'contact_type' => 'Household',
3168 ));
3169 $organization = $this->callAPISuccess('Contact', 'create', array(
3170 'organization_name' => 'organization@test.com',
3171 'contact_type' => 'Organization',
3172 ));
3173 // Test with id - getsingle will throw an exception if not found
3174 $this->callAPISuccess('Contact', 'getsingle', array(
3175 'id' => $individual['id'],
3176 'contact_type' => 'Individual',
3177 ));
3178 $this->callAPISuccess('Contact', 'getsingle', array(
3179 'id' => $individual['id'],
3180 'contact_type' => array('IN' => array('Individual')),
3181 'return' => 'id',
3182 ));
3183 $this->callAPISuccess('Contact', 'getsingle', array(
3184 'id' => $organization['id'],
3185 'contact_type' => array('IN' => array('Individual', 'Organization')),
3186 ));
3187 // Test as array
3188 $result = $this->callAPISuccess('Contact', 'get', array(
3189 'contact_type' => array('IN' => array('Individual', 'Organization')),
3190 'options' => array('limit' => 0),
3191 'return' => 'id',
3192 ));
3193 $this->assertContains($organization['id'], array_keys($result['values']));
3194 $this->assertContains($individual['id'], array_keys($result['values']));
3195 $this->assertNotContains($household['id'], array_keys($result['values']));
3196 // Test as string
3197 $result = $this->callAPISuccess('Contact', 'get', array(
3198 'contact_type' => 'Household',
3199 'options' => array('limit' => 0),
3200 'return' => 'id',
3201 ));
3202 $this->assertNotContains($organization['id'], array_keys($result['values']));
3203 $this->assertNotContains($individual['id'], array_keys($result['values']));
3204 $this->assertContains($household['id'], array_keys($result['values']));
3205 }
3206
12d73bba 3207 /**
3208 * Test merging 2 contacts.
5ea06a7b 3209 *
3210 * Someone kindly bequethed us the legacy of mixed up use of main_id & other_id
3211 * in the params for contact.merge api.
3212 *
3213 * This test protects that legacy.
12d73bba 3214 */
5ea06a7b 3215 public function testMergeBizzareOldParams() {
3216 $this->createLoggedInUser();
12d73bba 3217 $otherContact = $this->callAPISuccess('contact', 'create', $this->_params);
3218 $mainContact = $this->callAPISuccess('contact', 'create', $this->_params);
5ea06a7b 3219 $this->callAPISuccess('contact', 'merge', array(
3220 'main_id' => $mainContact['id'],
3221 'other_id' => $otherContact['id'],
3222 ));
12d73bba 3223 $contacts = $this->callAPISuccess('contact', 'get', $this->_params);
3224 $this->assertEquals($otherContact['id'], $contacts['id']);
5ea06a7b 3225 }
3226
3227 /**
3228 * Test merging 2 contacts.
3229 */
3230 public function testMerge() {
3231 $this->createLoggedInUser();
3232 $otherContact = $this->callAPISuccess('contact', 'create', $this->_params);
3233 $retainedContact = $this->callAPISuccess('contact', 'create', $this->_params);
3234 $this->callAPISuccess('contact', 'merge', array(
3235 'to_keep_id' => $retainedContact['id'],
3236 'to_remove_id' => $otherContact['id'],
3237 'auto_flip' => FALSE,
3238 ));
3239
3240 $contacts = $this->callAPISuccess('contact', 'get', $this->_params);
3241 $this->assertEquals($retainedContact['id'], $contacts['id']);
3242 $activity = $this->callAPISuccess('Activity', 'getsingle', array(
3243 'target_contact_id' => $retainedContact['id'],
3244 'activity_type_id' => 'Contact Merged',
3245 ));
3246 $this->assertEquals(date('Y-m-d'), date('Y-m-d', strtotime($activity['activity_date_time'])));
f00283b5 3247 $activity2 = $this->callAPISuccess('Activity', 'getsingle', array(
3248 'target_contact_id' => $otherContact['id'],
3249 'activity_type_id' => 'Contact Deleted by Merge',
3250 ));
3251 $this->assertEquals($activity['id'], $activity2['parent_id']);
3252 $this->assertEquals('Normal', civicrm_api3('option_value', 'getvalue', array(
3253 'value' => $activity['priority_id'],
3254 'return' => 'label',
3255 'option_group_id' => 'priority',
3256 )));
12d73bba 3257
3258 }
3259
4d834a99 3260 /**
3261 * Test merging 2 contacts with delete to trash off.
3262 *
3263 * We are checking that there is no error due to attempting to add an activity for the
3264 * deleted contact.
3265 *
3266 * CRM-18307
3267 */
3268 public function testMergeNoTrash() {
3269 $this->createLoggedInUser();
3270 $this->callAPISuccess('Setting', 'create', array('contact_undelete' => FALSE));
3271 $otherContact = $this->callAPISuccess('contact', 'create', $this->_params);
3272 $retainedContact = $this->callAPISuccess('contact', 'create', $this->_params);
3273 $this->callAPISuccess('contact', 'merge', array(
3274 'to_keep_id' => $retainedContact['id'],
3275 'to_remove_id' => $otherContact['id'],
3276 'auto_flip' => FALSE,
3277 ));
3278 $this->callAPISuccess('Setting', 'create', array('contact_undelete' => TRUE));
3279 }
3280
00ed3e04
CB
3281 /**
3282 * Ensure format with return=group shows comma-separated group IDs.
3283 *
3284 * CRM-19426
3285 */
3286 public function testContactGetReturnGroup() {
3287 // Set up a contact, asser that they were created.
3288 $contact_params = array(
3289 'contact_type' => 'Individual',
3290 'first_name' => 'Test',
3291 'last_name' => 'Groupmember',
3292 'email' => 'test@example.org',
3293 );
3294 $create_contact = $this->callApiSuccess('Contact', 'create', $contact_params);
3295 $this->assertEquals(0, $create_contact['is_error']);
3296 $this->assertInternalType('int', $create_contact['id']);
3297
3298 $created_contact_id = $create_contact['id'];
3299
3300 // Set up multiple groups, add the contact to the groups.
3301 $test_groups = array('Test group A', 'Test group B');
3302 foreach ($test_groups as $title) {
3303 // Use this contact as group owner, since we know they exist.
3304 $group_params = array(
3305 'title' => $title,
3306 'created_id' => $created_contact_id,
3307 );
3308 $create_group = $this->callApiSuccess('Group', 'create', $group_params);
3309 $this->assertEquals(0, $create_group['is_error']);
3310 $this->assertInternalType('int', $create_group['id']);
3311
3312 $created_group_ids[] = $create_group['id'];
3313
3314 // Add contact to the new group.
3315 $group_contact_params = array(
3316 'contact_id' => $created_contact_id,
3317 'group_id' => $create_group['id'],
3318 );
3319 $create_group_contact = $this->callApiSuccess('GroupContact', 'create', $group_contact_params);
3320 $this->assertEquals(0, $create_group_contact['is_error']);
3321 $this->assertInternalType('int', $create_group_contact['added']);
3322 }
3323
3324 // Use the Contact,get API to retrieve the contact
3325 $contact_get_params = array(
3326 'id' => $created_contact_id,
3327 'return' => 'group',
3328 );
3329 $contact_get = $this->callApiSuccess('Contact', 'get', $contact_get_params);
3330 $this->assertInternalType('array', $contact_get['values'][$created_contact_id]);
3331 $this->assertInternalType('string', $contact_get['values'][$created_contact_id]['groups']);
3332
3333 // Ensure they are shown as being in each created group.
3334 $contact_group_ids = explode(',', $contact_get['values'][$created_contact_id]['groups']);
3335 foreach ($created_group_ids as $created_group_id) {
3336 $this->assertContains($created_group_id, $contact_group_ids);
3337 }
3338 }
3339
309f98a9
SL
3340 /**
3341 * CRM-20144 Verify that passing title of group works as well as id
0c66b30c
SL
3342 * Tests the following formats
3343 * contact.get group='title1'
3344 * contact.get group=id1
309f98a9
SL
3345 */
3346 public function testContactGetWithGroupTitle() {
3347 // Set up a contact, asser that they were created.
3348 $contact_params = array(
3349 'contact_type' => 'Individual',
3350 'first_name' => 'Test2',
3351 'last_name' => 'Groupmember',
3352 'email' => 'test@example.org',
3353 );
3354 $create_contact = $this->callApiSuccess('Contact', 'create', $contact_params);
3355 $created_contact_id = $create_contact['id'];
3356 // Set up multiple groups, add the contact to the groups.
3357 $test_groups = array('Test group C', 'Test group D');
3358 foreach ($test_groups as $title) {
3359 $group_params = array(
3360 'title' => $title,
3361 'created_id' => $created_contact_id,
3362 );
3363 $create_group = $this->callApiSuccess('Group', 'create', $group_params);
3364 $created_group_id = $create_group['id'];
3365
3366 // Add contact to the new group.
3367 $group_contact_params = array(
3368 'contact_id' => $created_contact_id,
3369 'group_id' => $create_group['id'],
3370 );
6d054a8e 3371 $this->callApiSuccess('GroupContact', 'create', $group_contact_params);
309f98a9
SL
3372 $contact_get = $this->callAPISuccess('contact', 'get', array('group' => $title, 'return' => 'group'));
3373 $this->assertEquals(1, $contact_get['count']);
3374 $this->assertEquals($created_contact_id, $contact_get['id']);
3375 $contact_groups = explode(',', $contact_get['values'][$created_contact_id]['groups']);
3376 $this->assertContains((string) $create_group['id'], $contact_groups);
3377 $contact_get2 = $this->callAPISuccess('contact', 'get', array('group' => $created_group_id, 'return' => 'group'));
3378 $this->assertEquals($created_contact_id, $contact_get2['id']);
3379 $contact_groups2 = explode(',', $contact_get2['values'][$created_contact_id]['groups']);
3380 $this->assertContains((string) $create_group['id'], $contact_groups2);
3381 $this->callAPISuccess('group', 'delete', array('id' => $created_group_id));
3382 }
3383 $this->callAPISuccess('contact', 'delete', array('id' => $created_contact_id, 'skip_undelete' => TRUE));
3384 }
3385
0c66b30c
SL
3386 /**
3387 * CRM-20144 Verify that passing title of group works as well as id
3388 * Tests the following formats
3389 * contact.get group=array('title1', title1)
3390 * contact.get group=array('IN' => array('title1', 'title2)
3391 */
3392 public function testContactGetWithGroupTitleMultipleGroups() {
d0aa0e47
SL
3393 $description = "Get all from group and display contacts.";
3394 $subFile = "GroupFilterUsingContactAPI";
0c66b30c
SL
3395 // Set up a contact, asser that they were created.
3396 $contact_params = array(
3397 'contact_type' => 'Individual',
3398 'first_name' => 'Test2',
3399 'last_name' => 'Groupmember',
3400 'email' => 'test@example.org',
3401 );
3402 $create_contact = $this->callApiSuccess('Contact', 'create', $contact_params);
3403 $created_contact_id = $create_contact['id'];
3404 $createdGroupsTitles = $createdGroupsIds = array();
3405 // Set up multiple groups, add the contact to the groups.
3406 $test_groups = array('Test group C', 'Test group D');
3407 foreach ($test_groups as $title) {
3408 $group_params = array(
3409 'title' => $title,
3410 'created_id' => $created_contact_id,
3411 );
3412 $create_group = $this->callApiSuccess('Group', 'create', $group_params);
3413 $created_group_id = $create_group['id'];
3414 $createdGroupsIds[] = $create_group['id'];
3415 $createdGroupTitles[] = $title;
3416 // Add contact to the new group.
3417 $group_contact_params = array(
3418 'contact_id' => $created_contact_id,
3419 'group_id' => $create_group['id'],
3420 );
3421 $create_group_contact = $this->callApiSuccess('GroupContact', 'create', $group_contact_params);
3422 }
3423 $contact_get = $this->callAPISuccess('contact', 'get', array('group' => $createdGroupTitles, 'return' => 'group'));
3424 $this->assertEquals(1, $contact_get['count']);
3425 $this->assertEquals($created_contact_id, $contact_get['id']);
3426 $contact_groups = explode(',', $contact_get['values'][$created_contact_id]['groups']);
3427 foreach ($createdGroupsIds as $id) {
3428 $this->assertContains((string) $id, $contact_groups);
3429 }
d0aa0e47 3430 $contact_get2 = $this->callAPIAndDocument('contact', 'get', array('group' => array('IN' => $createdGroupTitles)), __FUNCTION__, __FILE__, $description, $subFile);
0c66b30c
SL
3431 $contact_get2 = $this->callAPISuccess('contact', 'get', array('group' => array('IN' => $createdGroupTitles), 'return' => 'group'));
3432 $this->assertEquals($created_contact_id, $contact_get2['id']);
3433 $contact_groups2 = explode(',', $contact_get2['values'][$created_contact_id]['groups']);
3434 foreach ($createdGroupsIds as $id) {
3435 $this->assertContains((string) $id, $contact_groups2);
3436 }
3437 foreach ($createdGroupsIds as $id) {
3438 $this->callAPISuccess('group', 'delete', array('id' => $id));
3439 }
3440 $this->callAPISuccess('contact', 'delete', array('id' => $created_contact_id, 'skip_undelete' => TRUE));
3441 }
3442
b6b28d93
SL
3443 /**
3444 * CRM-20144 Verify that passing title of group works as well as id
3445 * Tests the following formats
3446 * contact.get group=array('title1' => 1)
3447 * contact.get group=array('titke1' => 1, 'title2' => 1)
3448 * contact.get group=array('id1' => 1)
3449 * contact.get group=array('id1' => 1, id2 => 1)
3450 */
3451 public function testContactGetWithGroupTitleMultipleGroupsLegacyFormat() {
3452 // Set up a contact, asser that they were created.
3453 $contact_params = array(
3454 'contact_type' => 'Individual',
3455 'first_name' => 'Test2',
3456 'last_name' => 'Groupmember',
3457 'email' => 'test@example.org',
3458 );
3459 $create_contact = $this->callApiSuccess('Contact', 'create', $contact_params);
3460 $created_contact_id = $create_contact['id'];
3461 $createdGroupsTitles = $createdGroupsIds = array();
3462 // Set up multiple groups, add the contact to the groups.
3463 $test_groups = array('Test group C', 'Test group D');
3464 foreach ($test_groups as $title) {
3465 $group_params = array(
3466 'title' => $title,
3467 'created_id' => $created_contact_id,
3468 );
3469 $create_group = $this->callApiSuccess('Group', 'create', $group_params);
3470 $created_group_id = $create_group['id'];
3471 $createdGroupsIds[] = $create_group['id'];
3472 $createdGroupTitles[] = $title;
3473 // Add contact to the new group.
3474 $group_contact_params = array(
3475 'contact_id' => $created_contact_id,
3476 'group_id' => $create_group['id'],
3477 );
3478 $create_group_contact = $this->callApiSuccess('GroupContact', 'create', $group_contact_params);
3479 }
3480 $contact_get = $this->callAPISuccess('contact', 'get', array('group' => array($createdGroupTitles[0] => 1), 'return' => 'group'));
3481 $this->assertEquals(1, $contact_get['count']);
3482 $this->assertEquals($created_contact_id, $contact_get['id']);
3483 $contact_groups = explode(',', $contact_get['values'][$created_contact_id]['groups']);
3484 foreach ($createdGroupsIds as $id) {
3485 $this->assertContains((string) $id, $contact_groups);
3486 }
3487 $contact_get2 = $this->callAPISuccess('contact', 'get', array('group' => array($createdGroupTitles[0] => 1, $createdGroupTitles[1] => 1), 'return' => 'group'));
3488 $this->assertEquals(1, $contact_get2['count']);
3489 $this->assertEquals($created_contact_id, $contact_get2['id']);
62b8c91c 3490 $contact_groups2 = explode(',', $contact_get2['values'][$created_contact_id]['groups']);
b6b28d93 3491 foreach ($createdGroupsIds as $id) {
62b8c91c 3492 $this->assertContains((string) $id, $contact_groups2);
b6b28d93
SL
3493 }
3494 $contact_get3 = $this->callAPISuccess('contact', 'get', array('group' => array($createdGroupsIds[0] => 1), 'return' => 'group'));
3495 $this->assertEquals($created_contact_id, $contact_get3['id']);
3496 $contact_groups3 = explode(',', $contact_get3['values'][$created_contact_id]['groups']);
3497 foreach ($createdGroupsIds as $id) {
62b8c91c 3498 $this->assertContains((string) $id, $contact_groups3);
b6b28d93
SL
3499 }
3500 $contact_get4 = $this->callAPISuccess('contact', 'get', array('group' => array($createdGroupsIds[0] => 1, $createdGroupsIds[1] => 1), 'return' => 'group'));
3501 $this->assertEquals($created_contact_id, $contact_get4['id']);
62b8c91c 3502 $contact_groups4 = explode(',', $contact_get4['values'][$created_contact_id]['groups']);
b6b28d93 3503 foreach ($createdGroupsIds as $id) {
62b8c91c 3504 $this->assertContains((string) $id, $contact_groups4);
b6b28d93
SL
3505 }
3506 foreach ($createdGroupsIds as $id) {
3507 $this->callAPISuccess('group', 'delete', array('id' => $id));
3508 }
3509 $this->callAPISuccess('contact', 'delete', array('id' => $created_contact_id, 'skip_undelete' => TRUE));
3510 }
3511
83d02301
SL
3512 public function testLoggedInUserAPISupportToken() {
3513 $description = "Get contact id of the current logged in user";
3514 $subFile = "ContactIDOfLoggedInUserContactAPI";
3515 $cid = $this->createLoggedInUser();
3516 $contact = $this->callAPIAndDocument('contact', 'get', array('id' => 'user_contact_id'), __FUNCTION__, __FILE__, $description, $subFile);
3517 $this->assertEquals($cid, $contact['id']);
3518 }
3519
ec52a65a 3520 /**
3521 * @param $groupID
3522 * @param $contact
3523 */
3524 protected function putGroupContactCacheInClearableState($groupID, $contact) {
bb2d2335 3525 // We need to force the situation where there is invalid data in the cache and it
ec52a65a 3526 // is due to be cleared.
3527 CRM_Core_DAO::executeQuery("
3528 INSERT INTO civicrm_group_contact_cache (group_id, contact_id)
3529 VALUES ({$groupID}, {$contact['id']})
3530 ");
3531 CRM_Core_DAO::executeQuery("UPDATE civicrm_group SET cache_date = '2017-01-01'");
3532 // Reset so it does not skip.
3533 Civi::$statics['CRM_Contact_BAO_GroupContactCache']['is_refresh_init'] = FALSE;
3534 }
3535
6a488035 3536}