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