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