Merge pull request #9295 from JMAConsulting/CRM-19540
[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
2930d67a 575 $result = $this->callAPIAndDocument('Contact', 'create', $params, __FUNCTION__, __FILE__);
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
586 $result = $this->callAPIAndDocument('Contact', 'create', $params, __FUNCTION__, __FILE__);
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 );
609 $result = $this->callAPIAndDocument('Contact', 'create', $params, __FUNCTION__, __FILE__);
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);
84b51197 616 $this->callAPIAndDocument('Contact', 'create', $params, __FUNCTION__, __FILE__);
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();
5c49fee0 987 $description = "Get all from group and display contacts.";
5896d037
TO
988 $subFile = "GroupFilterUsingContactAPI";
989 $params = array(
6a488035
TO
990 'email' => 'man2@yahoo.com',
991 'contact_type' => 'Individual',
992 'location_type_id' => 1,
6a488035
TO
993 'api.group_contact.create' => array('group_id' => $groupId),
994 );
995
4b58ed3b 996 $this->callAPISuccess('contact', 'create', $params);
6a488035
TO
997 // testing as integer
998 $params = array(
999 'filter.group_id' => $groupId,
6a488035
TO
1000 'contact_type' => 'Individual',
1001 );
4b58ed3b 1002 $result = $this->callAPIAndDocument('contact', 'get', $params, __FUNCTION__, __FILE__, $description, $subFile);
6a488035
TO
1003 $this->assertEquals(1, $result['count']);
1004 // group 26 doesn't exist, but we can still search contacts in it.
1005 $params = array(
1006 'filter.group_id' => 26,
6a488035
TO
1007 'contact_type' => 'Individual',
1008 );
4b58ed3b 1009 $this->callAPISuccess('contact', 'get', $params);
6a488035
TO
1010 // testing as string
1011 $params = array(
f6722559 1012 'filter.group_id' => "$groupId, 26",
6a488035
TO
1013 'contact_type' => 'Individual',
1014 );
4b58ed3b 1015 $result = $this->callAPIAndDocument('contact', 'get', $params, __FUNCTION__, __FILE__, $description, $subFile);
6a488035
TO
1016 $this->assertEquals(1, $result['count']);
1017 $params = array(
1018 'filter.group_id' => "26,27",
6a488035
TO
1019 'contact_type' => 'Individual',
1020 );
4b58ed3b 1021 $this->callAPISuccess('contact', 'get', $params);
6a488035
TO
1022
1023 // testing as string
6c6e6187 1024 $params = array(
5896d037 1025 'filter.group_id' => array($groupId, 26),
6a488035
TO
1026 'contact_type' => 'Individual',
1027 );
4b58ed3b 1028 $result = $this->callAPIAndDocument('contact', 'get', $params, __FUNCTION__, __FILE__, $description, $subFile);
6a488035
TO
1029 $this->assertEquals(1, $result['count']);
1030
1031 //test in conjunction with other criteria
6c6e6187 1032 $params = array(
5896d037 1033 'filter.group_id' => array($groupId, 26),
6a488035
TO
1034 'contact_type' => 'Organization',
1035 );
6c6e6187
TO
1036 $this->callAPISuccess('contact', 'get', $params);
1037 $params = array(
5896d037 1038 'filter.group_id' => array(26, 27),
6a488035
TO
1039 'contact_type' => 'Individual',
1040 );
f6722559 1041 $result = $this->callAPISuccess('contact', 'get', $params);
4b58ed3b 1042 $this->assertEquals(0, $result['count']);
6a488035
TO
1043 }
1044
1045 /**
381fa321 1046 * Verify that attempt to create individual contact with two chained websites succeeds.
6a488035 1047 */
00be9182 1048 public function testCreateIndividualWithContributionDottedSyntax() {
5c49fee0 1049 $description = "This demonstrates the syntax to create 2 chained entities.";
5896d037
TO
1050 $subFile = "ChainTwoWebsites";
1051 $params = array(
6a488035
TO
1052 'first_name' => 'abc3',
1053 'last_name' => 'xyz3',
1054 'contact_type' => 'Individual',
1055 'email' => 'man3@yahoo.com',
6a488035
TO
1056 'api.contribution.create' => array(
1057 'receive_date' => '2010-01-01',
1058 'total_amount' => 100.00,
5896d037 1059 'financial_type_id' => $this->_financialTypeId,
6a488035
TO
1060 'payment_instrument_id' => 1,
1061 'non_deductible_amount' => 10.00,
1062 'fee_amount' => 50.00,
1063 'net_amount' => 90.00,
1064 'trxn_id' => 15345,
1065 'invoice_id' => 67990,
1066 'source' => 'SSF',
1067 'contribution_status_id' => 1,
1068 ),
1069 'api.website.create' => array(
1070 'url' => "http://civicrm.org",
1071 ),
1072 'api.website.create.2' => array(
1073 'url' => "http://chained.org",
1074 ),
1075 );
1076
4b58ed3b 1077 $result = $this->callAPIAndDocument('Contact', 'create', $params, __FUNCTION__, __FILE__, $description, $subFile);
6a488035 1078
f6722559 1079 // checking child function result not covered in callAPIAndDocument
1080 $this->assertAPISuccess($result['values'][$result['id']]['api.website.create']);
fe482240
EM
1081 $this->assertEquals("http://chained.org", $result['values'][$result['id']]['api.website.create.2']['values'][0]['url']);
1082 $this->assertEquals("http://civicrm.org", $result['values'][$result['id']]['api.website.create']['values'][0]['url']);
6a488035
TO
1083
1084 // delete the contact
f6722559 1085 $this->callAPISuccess('contact', 'delete', $result);
6a488035
TO
1086 }
1087
1088 /**
381fa321 1089 * Verify that attempt to create individual contact with chained contribution and website succeeds.
6a488035 1090 */
00be9182 1091 public function testCreateIndividualWithContributionChainedArrays() {
6a488035
TO
1092 $params = array(
1093 'first_name' => 'abc3',
1094 'last_name' => 'xyz3',
1095 'contact_type' => 'Individual',
1096 'email' => 'man3@yahoo.com',
6a488035
TO
1097 'api.contribution.create' => array(
1098 'receive_date' => '2010-01-01',
1099 'total_amount' => 100.00,
5896d037 1100 'financial_type_id' => $this->_financialTypeId,
6a488035
TO
1101 'payment_instrument_id' => 1,
1102 'non_deductible_amount' => 10.00,
1103 'fee_amount' => 50.00,
1104 'net_amount' => 90.00,
1105 'trxn_id' => 12345,
1106 'invoice_id' => 67890,
1107 'source' => 'SSF',
1108 'contribution_status_id' => 1,
1109 ),
1110 'api.website.create' => array(
1111 array(
1112 'url' => "http://civicrm.org",
1113 ),
1114 array(
1115 'url' => "http://chained.org",
1116 'website_type_id' => 2,
1117 ),
1118 ),
1119 );
1120
5c49fee0 1121 $description = "Demonstrates creating two websites as an array.";
5896d037
TO
1122 $subfile = "ChainTwoWebsitesSyntax2";
1123 $result = $this->callAPIAndDocument('Contact', 'create', $params, __FUNCTION__, __FILE__, $description, $subfile);
f6722559 1124
f6722559 1125 // the callAndDocument doesn't check the chained call
fe482240
EM
1126 $this->assertEquals(0, $result['values'][$result['id']]['api.website.create'][0]['is_error']);
1127 $this->assertEquals("http://chained.org", $result['values'][$result['id']]['api.website.create'][1]['values'][0]['url']);
1128 $this->assertEquals("http://civicrm.org", $result['values'][$result['id']]['api.website.create'][0]['values'][0]['url']);
6a488035 1129
f6722559 1130 $this->callAPISuccess('contact', 'delete', $result);
6a488035
TO
1131 }
1132
92d270fd
JV
1133 /**
1134 * Test for direction when chaining relationships.
1135 *
1136 * https://issues.civicrm.org/jira/browse/CRM-16084
1137 */
1138 public function testDirectionChainingRelationshipsCRM16084() {
1139 // Some contact, called Jules.
1140 $create_result_1 = $this->callAPISuccess('contact', 'create', array(
1141 'first_name' => 'Jules',
1142 'last_name' => 'Smos',
1143 'contact_type' => 'Individual',
1144 ));
1145
1146 // Another contact: Jos, child of Jules.
1147 $create_params = array(
1148 'first_name' => 'Jos',
1149 'last_name' => 'Smos',
1150 'contact_type' => 'Individual',
1151 'api.relationship.create' => array(
1152 array(
1153 'contact_id_a' => '$value.id',
1154 'contact_id_b' => $create_result_1['id'],
1155 // child of
1156 'relationship_type_id' => 1,
1157 ),
1158 ),
1159 );
1160 $create_result_2 = $this->callAPISuccess('contact', 'create', $create_params);
1161
1162 // Mia is the child of Jos.
1163 $create_params = array(
1164 'first_name' => 'Mia',
1165 'last_name' => 'Smos',
1166 'contact_type' => 'Individual',
1167 'api.relationship.create' => array(
1168 array(
1169 'contact_id_a' => '$value.id',
1170 'contact_id_b' => $create_result_2['id'],
1171 // child of
1172 'relationship_type_id' => 1,
1173 ),
1174 ),
1175 );
1176 $create_result_3 = $this->callAPISuccess('contact', 'create', $create_params);
1177
1178 // Get Jos and his children.
1179 $get_params = array(
1180 'sequential' => 1,
1181 'id' => $create_result_2['id'],
1182 'api.relationship.get' => array(
1183 'contact_id_b' => '$value.id',
1184 'relationship_type_id' => 1,
1185 ),
1186 );
1187 $get_result = $this->callAPISuccess('contact', 'getsingle', $get_params);
1188
1189 // Clean up first.
1190 $this->callAPISuccess('contact', 'delete', array(
1191 'id' => $create_result_1['id'],
1192 ));
1193 $this->callAPISuccess('contact', 'delete', array(
1194 'id' => $create_result_2['id'],
1195 ));
1196 $this->callAPISuccess('contact', 'delete', array(
1197 'id' => $create_result_2['id'],
1198 ));
1199
1200 // Assert.
1201 $this->assertEquals(1, $get_result['api.relationship.get']['count']);
1202 $this->assertEquals($create_result_3['id'], $get_result['api.relationship.get']['values'][0]['contact_id_a']);
1203 }
1204
6a488035 1205 /**
fe482240 1206 * Verify that attempt to create individual contact with first, and last names and email succeeds.
6a488035 1207 */
00be9182 1208 public function testCreateIndividualWithNameEmail() {
6a488035
TO
1209 $params = array(
1210 'first_name' => 'abc3',
1211 'last_name' => 'xyz3',
1212 'contact_type' => 'Individual',
1213 'email' => 'man3@yahoo.com',
6a488035
TO
1214 );
1215
f6722559 1216 $contact = $this->callAPISuccess('contact', 'create', $params);
6a488035 1217
f6722559 1218 $this->callAPISuccess('contact', 'delete', $contact);
6a488035 1219 }
5896d037 1220
6a488035 1221 /**
eceb18cc 1222 * Verify that attempt to create individual contact with no data fails.
6a488035 1223 */
00be9182 1224 public function testCreateIndividualWithOutNameEmail() {
6a488035
TO
1225 $params = array(
1226 'contact_type' => 'Individual',
6a488035 1227 );
4b58ed3b 1228 $this->callAPIFailure('contact', 'create', $params);
6a488035 1229 }
5896d037 1230
6a488035 1231 /**
fe482240 1232 * Test create individual contact with first &last names, email and location type succeeds.
6a488035 1233 */
00be9182 1234 public function testCreateIndividualWithNameEmailLocationType() {
6a488035
TO
1235 $params = array(
1236 'first_name' => 'abc4',
1237 'last_name' => 'xyz4',
1238 'email' => 'man4@yahoo.com',
1239 'contact_type' => 'Individual',
1240 'location_type_id' => 1,
6a488035 1241 );
f6722559 1242 $result = $this->callAPISuccess('contact', 'create', $params);
6a488035 1243
f6722559 1244 $this->callAPISuccess('contact', 'delete', array('id' => $result['id']));
6a488035
TO
1245 }
1246
1247 /**
fe482240 1248 * Verify that when changing employers the old employer relationship becomes inactive.
6a488035 1249 */
00be9182 1250 public function testCreateIndividualWithEmployer() {
6a488035
TO
1251 $employer = $this->organizationCreate();
1252 $employer2 = $this->organizationCreate();
1253
1254 $params = array(
5896d037
TO
1255 'email' => 'man4@yahoo.com',
1256 'contact_type' => 'Individual',
1257 'employer_id' => $employer,
6a488035
TO
1258 );
1259
f6722559 1260 $result = $this->callAPISuccess('contact', 'create', $params);
1261 $relationships = $this->callAPISuccess('relationship', 'get', array(
6a488035
TO
1262 'contact_id_a' => $result['id'],
1263 'sequential' => 1,
1264 ));
1265
1266 $this->assertEquals($employer, $relationships['values'][0]['contact_id_b']);
1267
1268 // Add more random relationships to make the test more realistic
4b58ed3b
EM
1269 foreach (array('Employee of', 'Volunteer for') as $relationshipType) {
1270 $relTypeId = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_RelationshipType', $relationshipType, 'id', 'name_a_b');
1271 $this->callAPISuccess('relationship', 'create', array(
6a488035
TO
1272 'contact_id_a' => $result['id'],
1273 'contact_id_b' => $this->organizationCreate(),
1274 'is_active' => 1,
1275 'relationship_type_id' => $relTypeId,
1276 ));
6c6e6187 1277 }
6a488035
TO
1278
1279 // Add second employer
1280 $params['employer_id'] = $employer2;
1281 $params['id'] = $result['id'];
f6722559 1282 $result = $this->callAPISuccess('contact', 'create', $params);
6a488035 1283
f6722559 1284 $relationships = $this->callAPISuccess('relationship', 'get', array(
6a488035
TO
1285 'contact_id_a' => $result['id'],
1286 'sequential' => 1,
1287 'is_active' => 0,
1288 ));
1289
1290 $this->assertEquals($employer, $relationships['values'][0]['contact_id_b']);
1291 }
1292
1293 /**
fe482240 1294 * Verify that attempt to create household contact with details succeeds.
6a488035 1295 */
00be9182 1296 public function testCreateHouseholdDetails() {
6a488035
TO
1297 $params = array(
1298 'household_name' => 'abc8\'s House',
1299 'nick_name' => 'x House',
1300 'email' => 'man8@yahoo.com',
1301 'contact_type' => 'Household',
6a488035
TO
1302 );
1303
f6722559 1304 $contact = $this->callAPISuccess('contact', 'create', $params);
1305
f6722559 1306 $this->callAPISuccess('contact', 'delete', $contact);
6a488035 1307 }
5896d037 1308
6a488035 1309 /**
381fa321 1310 * Verify that attempt to create household contact with inadequate details fails.
6a488035 1311 */
00be9182 1312 public function testCreateHouseholdInadequateDetails() {
6a488035
TO
1313 $params = array(
1314 'nick_name' => 'x House',
1315 'email' => 'man8@yahoo.com',
1316 'contact_type' => 'Household',
6a488035 1317 );
4b58ed3b 1318 $this->callAPIFailure('contact', 'create', $params);
6a488035
TO
1319 }
1320
6a488035 1321 /**
381fa321 1322 * Verify successful update of individual contact.
6a488035 1323 */
00be9182 1324 public function testUpdateIndividualWithAll() {
381fa321 1325 // Insert a row in civicrm_contact creating individual contact.
6a488035
TO
1326 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1327 $op->execute($this->_dbconn,
bbfd46a5 1328 $this->createXMLDataSet(
6a488035
TO
1329 dirname(__FILE__) . '/dataset/contact_ind.xml'
1330 )
1331 );
1332
1333 $params = array(
1334 'id' => 23,
1335 'first_name' => 'abcd',
1336 'contact_type' => 'Individual',
1337 'nick_name' => 'This is nickname first',
1338 'do_not_email' => '1',
1339 'do_not_phone' => '1',
1340 'do_not_mail' => '1',
1341 'do_not_trade' => '1',
1342 'legal_identifier' => 'ABC23853ZZ2235',
1343 'external_identifier' => '1928837465',
1344 'image_URL' => 'http://some.url.com/image.jpg',
1345 'home_url' => 'http://www.example.org',
f6722559 1346
1347 );
43ef1263 1348
4b58ed3b 1349 $this->callAPISuccess('Contact', 'Update', $params);
f6722559 1350 $getResult = $this->callAPISuccess('Contact', 'Get', $params);
6a488035
TO
1351 unset($params['contact_id']);
1352 //Todo - neither API v2 or V3 are testing for home_url - not sure if it is being set.
4b58ed3b 1353 //reducing this test partially back to api v2 level to get it through
6a488035
TO
1354 unset($params['home_url']);
1355 foreach ($params as $key => $value) {
4b58ed3b 1356 $this->assertEquals($value, $getResult['values'][23][$key]);
6a488035 1357 }
381fa321 1358 // Check updated civicrm_contact against expected.
bbfd46a5 1359 $expected = $this->createXMLDataSet(
6a488035
TO
1360 dirname(__FILE__) . '/dataset/contact_ind_upd.xml'
1361 );
bbfd46a5 1362 $actual = new PHPUnit_Extensions_Database_DataSet_QueryDataSet(
6a488035
TO
1363 $this->_dbconn
1364 );
1365 $actual->addTable('civicrm_contact');
1366 $expected->matches($actual);
1367 }
1368
1369 /**
eceb18cc 1370 * Verify successful update of organization contact.
6a488035 1371 */
00be9182 1372 public function testUpdateOrganizationWithAll() {
381fa321 1373 // Insert a row in civicrm_contact creating organization contact
6a488035
TO
1374 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1375 $op->execute($this->_dbconn,
bbfd46a5 1376 $this->createXMLDataSet(
6a488035
TO
1377 dirname(__FILE__) . '/dataset/contact_org.xml'
1378 )
1379 );
1380
1381 $params = array(
1382 'id' => 24,
1383 'organization_name' => 'WebAccess India Pvt Ltd',
1384 'legal_name' => 'WebAccess',
1385 'sic_code' => 'ABC12DEF',
1386 'contact_type' => 'Organization',
6a488035
TO
1387 );
1388
4b58ed3b 1389 $this->callAPISuccess('Contact', 'Update', $params);
6a488035 1390
381fa321 1391 // Check updated civicrm_contact against expected.
bbfd46a5 1392 $expected = $this->createXMLDataSet(
6a488035
TO
1393 dirname(__FILE__) . '/dataset/contact_org_upd.xml'
1394 );
bbfd46a5 1395 $actual = new PHPUnit_Extensions_Database_DataSet_QueryDataSet(
6a488035
TO
1396 $this->_dbconn
1397 );
1398 $actual->addTable('civicrm_contact');
1399 $expected->matches($actual);
1400 }
1401
1402 /**
381fa321 1403 * Verify successful update of household contact.
6a488035 1404 */
381fa321 1405 public function testUpdateHouseholdWithAll() {
1406 // Insert a row in civicrm_contact creating household contact
6a488035
TO
1407 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1408 $op->execute($this->_dbconn,
bbfd46a5 1409 $this->createXMLDataSet(
6a488035
TO
1410 dirname(__FILE__) . '/dataset/contact_hld.xml'
1411 )
1412 );
1413
1414 $params = array(
1415 'id' => 25,
1416 'household_name' => 'ABC household',
1417 'nick_name' => 'ABC House',
1418 'contact_type' => 'Household',
6a488035
TO
1419 );
1420
f6722559 1421 $result = $this->callAPISuccess('Contact', 'Update', $params);
6a488035 1422
43ef1263
EM
1423 $expected = array(
1424 'contact_type' => 'Household',
1425 'is_opt_out' => 0,
1426 'sort_name' => 'ABC household',
1427 'display_name' => 'ABC household',
1428 'nick_name' => 'ABC House',
6a488035 1429 );
43ef1263 1430 $this->getAndCheck($expected, $result['id'], 'contact');
6a488035
TO
1431 }
1432
1433 /**
381fa321 1434 * Test civicrm_update() without contact type.
1435 *
1436 * Deliberately exclude contact_type as it should still cope using civicrm_api.
1437 *
1438 * CRM-7645.
6a488035 1439 */
6a488035 1440 public function testUpdateCreateWithID() {
381fa321 1441 // Insert a row in civicrm_contact creating individual contact.
6a488035
TO
1442 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1443 $op->execute($this->_dbconn,
bbfd46a5 1444 $this->createXMLDataSet(
6a488035
TO
1445 dirname(__FILE__) . '/dataset/contact_ind.xml'
1446 )
1447 );
1448
6a488035
TO
1449 $params = array(
1450 'id' => 23,
1451 'first_name' => 'abcd',
1452 'last_name' => 'wxyz',
6a488035 1453 );
4b58ed3b 1454 $this->callAPISuccess('Contact', 'Update', $params);
6a488035
TO
1455 }
1456
1457 /**
381fa321 1458 * Test civicrm_contact_delete() with no contact ID.
6a488035 1459 */
00be9182 1460 public function testContactDeleteNoID() {
6a488035
TO
1461 $params = array(
1462 'foo' => 'bar',
6a488035 1463 );
4b58ed3b 1464 $this->callAPIFailure('contact', 'delete', $params);
6a488035
TO
1465 }
1466
1467 /**
381fa321 1468 * Test civicrm_contact_delete() with error.
6a488035 1469 */
00be9182 1470 public function testContactDeleteError() {
f6722559 1471 $params = array('contact_id' => 999);
4b58ed3b 1472 $this->callAPIFailure('contact', 'delete', $params);
6a488035
TO
1473 }
1474
1475 /**
381fa321 1476 * Test civicrm_contact_delete().
6a488035 1477 */
00be9182 1478 public function testContactDelete() {
f6722559 1479 $contactID = $this->individualCreate();
6a488035 1480 $params = array(
5896d037 1481 'id' => $contactID,
6a488035 1482 );
4b58ed3b 1483 $this->callAPIAndDocument('contact', 'delete', $params, __FUNCTION__, __FILE__);
6a488035
TO
1484 }
1485
1486 /**
381fa321 1487 * Test civicrm_contact_get() return only first name.
6a488035
TO
1488 */
1489 public function testContactGetRetFirst() {
f6722559 1490 $contact = $this->callAPISuccess('contact', 'create', $this->_params);
6a488035
TO
1491 $params = array(
1492 'contact_id' => $contact['id'],
1493 'return_first_name' => TRUE,
1494 'sort' => 'first_name',
6a488035 1495 );
f6722559 1496 $result = $this->callAPISuccess('contact', 'get', $params);
4b58ed3b
EM
1497 $this->assertEquals(1, $result['count']);
1498 $this->assertEquals($contact['id'], $result['id']);
1499 $this->assertEquals('abc1', $result['values'][$contact['id']]['first_name']);
6a488035
TO
1500 }
1501
1502 /**
381fa321 1503 * Test civicrm_contact_get() return only first name & last name.
1504 *
1505 * Use comma separated string return with a space.
6a488035 1506 */
381fa321 1507 public function testContactGetReturnFirstLast() {
f6722559 1508 $contact = $this->callAPISuccess('contact', 'create', $this->_params);
6a488035
TO
1509 $params = array(
1510 'contact_id' => $contact['id'],
1511 'return' => 'first_name, last_name',
6a488035 1512 );
f6722559 1513 $result = $this->callAPISuccess('contact', 'getsingle', $params);
4b58ed3b
EM
1514 $this->assertEquals('abc1', $result['first_name']);
1515 $this->assertEquals('xyz1', $result['last_name']);
6a488035
TO
1516 //check that other defaults not returns
1517 $this->assertArrayNotHasKey('sort_name', $result);
1518 $params = array(
1519 'contact_id' => $contact['id'],
1520 'return' => 'first_name,last_name',
6a488035 1521 );
f6722559 1522 $result = $this->callAPISuccess('contact', 'getsingle', $params);
4b58ed3b
EM
1523 $this->assertEquals('abc1', $result['first_name']);
1524 $this->assertEquals('xyz1', $result['last_name']);
6a488035
TO
1525 //check that other defaults not returns
1526 $this->assertArrayNotHasKey('sort_name', $result);
1527 }
1528
1529 /**
381fa321 1530 * Test civicrm_contact_get() return only first name & last name.
1531 *
d177a2a6 1532 * Use comma separated string return without a space
6a488035 1533 */
381fa321 1534 public function testContactGetReturnFirstLastNoComma() {
f6722559 1535 $contact = $this->callAPISuccess('contact', 'create', $this->_params);
6a488035
TO
1536 $params = array(
1537 'contact_id' => $contact['id'],
1538 'return' => 'first_name,last_name',
6a488035 1539 );
f6722559 1540 $result = $this->callAPISuccess('contact', 'getsingle', $params);
4b58ed3b
EM
1541 $this->assertEquals('abc1', $result['first_name']);
1542 $this->assertEquals('xyz1', $result['last_name']);
6a488035
TO
1543 //check that other defaults not returns
1544 $this->assertArrayNotHasKey('sort_name', $result);
1545 }
1546
1547 /**
381fa321 1548 * Test civicrm_contact_get() with default return properties.
6a488035
TO
1549 */
1550 public function testContactGetRetDefault() {
43ef1263 1551 $contactID = $this->individualCreate();
6a488035 1552 $params = array(
43ef1263 1553 'contact_id' => $contactID,
6a488035 1554 'sort' => 'first_name',
6a488035 1555 );
f6722559 1556 $result = $this->callAPISuccess('contact', 'get', $params);
43ef1263
EM
1557 $this->assertEquals($contactID, $result['values'][$contactID]['contact_id']);
1558 $this->assertEquals('Anthony', $result['values'][$contactID]['first_name']);
6a488035
TO
1559 }
1560
1561 /**
381fa321 1562 * Test civicrm_contact_getquick() with empty name param.
6a488035
TO
1563 */
1564 public function testContactGetQuick() {
fe482240 1565 // Insert a row in civicrm_contact creating individual contact.
6a488035
TO
1566 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1567 $op->execute($this->_dbconn,
bbfd46a5 1568 $this->createXMLDataSet(
6a488035
TO
1569 dirname(__FILE__) . '/dataset/contact_17.xml'
1570 )
1571 );
1572 $op->execute($this->_dbconn,
bbfd46a5 1573 $this->createXMLDataSet(
6a488035
TO
1574 dirname(__FILE__) . '/dataset/email_contact_17.xml'
1575 )
1576 );
1577 $params = array(
1578 'name' => "T",
6a488035
TO
1579 );
1580
1d6020f1 1581 $result = $this->callAPISuccess('contact', 'getquick', $params);
fe482240 1582 $this->assertEquals(17, $result['values'][0]['id']);
6a488035
TO
1583 }
1584
1585 /**
fe482240 1586 * Test civicrm_contact_get) with empty params.
6a488035
TO
1587 */
1588 public function testContactGetEmptyParams() {
4b58ed3b 1589 $this->callAPISuccess('contact', 'get', array());
6a488035
TO
1590 }
1591
1592 /**
fe482240 1593 * Test civicrm_contact_get(,true) with no matches.
6a488035
TO
1594 */
1595 public function testContactGetOldParamsNoMatches() {
fe482240 1596 // Insert a row in civicrm_contact creating contact 17.
6a488035
TO
1597 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1598 $op->execute($this->_dbconn,
bbfd46a5 1599 $this->createXMLDataSet(
6a488035
TO
1600 dirname(__FILE__) . '/dataset/contact_17.xml'
1601 )
1602 );
1603
1604 $params = array(
1605 'first_name' => 'Fred',
6a488035 1606 );
f6722559 1607 $result = $this->callAPISuccess('contact', 'get', $params);
fe482240 1608 $this->assertEquals(0, $result['count']);
6a488035
TO
1609 }
1610
1611 /**
fe482240 1612 * Test civicrm_contact_get(,true) with one match.
6a488035
TO
1613 */
1614 public function testContactGetOldParamsOneMatch() {
fe482240 1615 // Insert a row in civicrm_contact creating contact 17
6a488035
TO
1616 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1617 $op->execute($this->_dbconn,
bbfd46a5 1618 $this->createXMLDataSet(dirname(__FILE__) . '/dataset/contact_17.xml'
6a488035
TO
1619 )
1620 );
1621
1622 $params = array(
1623 'first_name' => 'Test',
6a488035 1624 );
f6722559 1625 $result = $this->callAPISuccess('contact', 'get', $params);
fe482240
EM
1626 $this->assertEquals(17, $result['values'][17]['contact_id']);
1627 $this->assertEquals(17, $result['id']);
6a488035 1628 }
6a488035
TO
1629
1630 /**
fe482240 1631 * Test civicrm_contact_search_count().
6a488035
TO
1632 */
1633 public function testContactGetEmail() {
1634 $params = array(
1635 'email' => 'man2@yahoo.com',
1636 'contact_type' => 'Individual',
1637 'location_type_id' => 1,
6a488035
TO
1638 );
1639
f6722559 1640 $contact = $this->callAPISuccess('contact', 'create', $params);
1641
6a488035
TO
1642 $params = array(
1643 'email' => 'man2@yahoo.com',
6a488035 1644 );
f6722559 1645 $result = $this->callAPIAndDocument('contact', 'get', $params, __FUNCTION__, __FILE__);
c8747697 1646 $this->assertEquals('man2@yahoo.com', $result['values'][$result['id']]['email']);
6a488035 1647
f6722559 1648 $this->callAPISuccess('contact', 'delete', $contact);
6a488035
TO
1649 }
1650
b1f09bea 1651 /**
fe482240
EM
1652 * Test birth date parameters.
1653 *
1654 * These include value, array & birth_date_high, birth_date_low
1655 * && deceased.
b1f09bea 1656 */
4b58ed3b 1657 public function testContactGetBirthDate() {
b1f09bea
E
1658 $contact1 = $this->callAPISuccess('contact', 'create', array_merge($this->_params, array('birth_date' => 'first day of next month - 2 years')));
1659 $contact2 = $this->callAPISuccess('contact', 'create', array_merge($this->_params, array('birth_date' => 'first day of next month - 5 years')));
1660 $contact3 = $this->callAPISuccess('contact', 'create', array_merge($this->_params, array('birth_date' => 'first day of next month -20 years')));
1661
1662 $result = $this->callAPISuccess('contact', 'get', array());
1663 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -2 years')), $result['values'][$contact1['id']]['birth_date']);
1664 $result = $this->callAPISuccess('contact', 'get', array('birth_date' => 'first day of next month -5 years'));
1665 $this->assertEquals(1, $result['count']);
1666 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -5 years')), $result['values'][$contact2['id']]['birth_date']);
1667 $result = $this->callAPISuccess('contact', 'get', array('birth_date_high' => date('Y-m-d', strtotime('-6 years'))));
1668 $this->assertEquals(1, $result['count']);
1669 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -20 years')), $result['values'][$contact3['id']]['birth_date']);
5896d037 1670 $result = $this->callAPISuccess('contact', 'get', array(
92915c55
TO
1671 'birth_date_low' => date('Y-m-d', strtotime('-6 years')),
1672 'birth_date_high' => date('Y-m-d', strtotime('- 3 years')),
1673 ));
b1f09bea
E
1674 $this->assertEquals(1, $result['count']);
1675 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -5 years')), $result['values'][$contact2['id']]['birth_date']);
5896d037 1676 $result = $this->callAPISuccess('contact', 'get', array(
92915c55
TO
1677 'birth_date_low' => '-6 years',
1678 'birth_date_high' => '- 3 years',
1679 ));
9f60788a
EM
1680 $this->assertEquals(1, $result['count']);
1681 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -5 years')), $result['values'][$contact2['id']]['birth_date']);
b1f09bea
E
1682 }
1683
d0bfb983 1684 /**
1685 * Test Address parameters
1686 *
1687 * This include state_province, state_province_name, country
1688 */
1689 public function testContactGetWithAddressFields() {
1690 $individuals = array(
1691 array(
1692 'first_name' => 'abc1',
1693 'contact_type' => 'Individual',
1694 'last_name' => 'xyz1',
1695 'api.address.create' => array(
1696 'country' => 'United States',
1697 'state_province_id' => 'Michigan',
1698 'location_type_id' => 1,
1699 ),
1700 ),
1701 array(
1702 'first_name' => 'abc2',
1703 'contact_type' => 'Individual',
1704 'last_name' => 'xyz2',
1705 'api.address.create' => array(
1706 'country' => 'United States',
1707 'state_province_id' => 'Alabama',
1708 'location_type_id' => 1,
1709 ),
1710 ),
1711 );
1712 foreach ($individuals as $params) {
1713 $contact = $this->callAPISuccess('contact', 'create', $params);
1714 }
1715
1716 // Check whether Contact get API return successfully with below Address params.
1717 $fieldsToTest = array(
1718 'state_province_name' => 'Michigan',
1719 'state_province' => 'Michigan',
1720 'country' => 'United States',
1721 'state_province_name' => array('IN' => array('Michigan', 'Alabama')),
1722 'state_province' => array('IN' => array('Michigan', 'Alabama')),
1723 );
1724 foreach ($fieldsToTest as $field => $value) {
1725 $getParams = array(
1726 'id' => $contact['id'],
1727 $field => $value,
1728 );
41a74135 1729 $result = $this->callAPISuccess('Contact', 'get', $getParams);
1730 $this->assertEquals(1, $result['count']);
d0bfb983 1731 }
1732 }
1733
b1f09bea 1734 /**
fe482240
EM
1735 * Test Deceased date parameters.
1736 *
1737 * These include value, array & Deceased_date_high, Deceased date_low
d177a2a6 1738 * && deceased.
b1f09bea 1739 */
4b58ed3b 1740 public function testContactGetDeceasedDate() {
b1f09bea
E
1741 $contact1 = $this->callAPISuccess('contact', 'create', array_merge($this->_params, array('deceased_date' => 'first day of next month - 2 years')));
1742 $contact2 = $this->callAPISuccess('contact', 'create', array_merge($this->_params, array('deceased_date' => 'first day of next month - 5 years')));
1743 $contact3 = $this->callAPISuccess('contact', 'create', array_merge($this->_params, array('deceased_date' => 'first day of next month -20 years')));
1744
1745 $result = $this->callAPISuccess('contact', 'get', array());
1746 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -2 years')), $result['values'][$contact1['id']]['deceased_date']);
1747 $result = $this->callAPISuccess('contact', 'get', array('deceased_date' => 'first day of next month -5 years'));
1748 $this->assertEquals(1, $result['count']);
1749 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -5 years')), $result['values'][$contact2['id']]['deceased_date']);
1750 $result = $this->callAPISuccess('contact', 'get', array('deceased_date_high' => date('Y-m-d', strtotime('-6 years'))));
1751 $this->assertEquals(1, $result['count']);
1752 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -20 years')), $result['values'][$contact3['id']]['deceased_date']);
5896d037 1753 $result = $this->callAPISuccess('contact', 'get', array(
92915c55
TO
1754 'deceased_date_low' => '-6 years',
1755 'deceased_date_high' => date('Y-m-d', strtotime('- 3 years')),
1756 ));
b1f09bea
E
1757 $this->assertEquals(1, $result['count']);
1758 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -5 years')), $result['values'][$contact2['id']]['deceased_date']);
1759 }
1760
e635f9d4 1761 /**
fe482240 1762 * Test for Contact.get id=@user:username.
e635f9d4 1763 */
00be9182 1764 public function testContactGetByUsername() {
fe482240 1765 // Setup - create contact with a uf-match.
e635f9d4
TO
1766 $cid = $this->individualCreate(array(
1767 'contact_type' => 'Individual',
1768 'first_name' => 'testGetByUsername',
1769 'last_name' => 'testGetByUsername',
1770 ));
1771
1772 $ufMatchParams = array(
1773 'domain_id' => CRM_Core_Config::domainID(),
1774 'uf_id' => 99,
1775 'uf_name' => 'the-email-matching-key-is-not-really-the-username',
1776 'contact_id' => $cid,
1777 );
1778 $ufMatch = CRM_Core_BAO_UFMatch::create($ufMatchParams);
1779 $this->assertTrue(is_numeric($ufMatch->id));
1780
1781 // setup - mock the calls to CRM_Utils_System_*::getUfId
1782 $userSystem = $this->getMock('CRM_Utils_System_UnitTests', array('getUfId'));
1783 $userSystem->expects($this->once())
1784 ->method('getUfId')
1785 ->with($this->equalTo('exampleUser'))
1786 ->will($this->returnValue(99));
1787 CRM_Core_Config::singleton()->userSystem = $userSystem;
1788
1789 // perform a lookup
1790 $result = $this->callAPISuccess('Contact', 'get', array(
e635f9d4
TO
1791 'id' => '@user:exampleUser',
1792 ));
1793 $this->assertEquals('testGetByUsername', $result['values'][$cid]['first_name']);
1794 }
1795
265cc07d 1796 /**
eceb18cc 1797 * Test to check return works OK.
265cc07d 1798 */
00be9182 1799 public function testContactGetReturnValues() {
701a69da 1800 $extraParams = array(
1801 'nick_name' => 'Bob',
1802 'phone' => '456',
1803 'email' => 'e@mail.com',
1804 );
265cc07d 1805 $contactID = $this->individualCreate($extraParams);
1806 //actually it turns out the above doesn't create a phone
6c6e6187 1807 $this->callAPISuccess('phone', 'create', array('contact_id' => $contactID, 'phone' => '456'));
265cc07d 1808 $result = $this->callAPISuccess('contact', 'getsingle', array('id' => $contactID));
1809 foreach ($extraParams as $key => $value) {
1810 $this->assertEquals($result[$key], $value);
1811 }
1812 //now we check they are still returned with 'return' key
5896d037 1813 $result = $this->callAPISuccess('contact', 'getsingle', array(
92915c55
TO
1814 'id' => $contactID,
1815 'return' => array_keys($extraParams),
1816 ));
265cc07d 1817 foreach ($extraParams as $key => $value) {
1818 $this->assertEquals($result[$key], $value);
1819 }
1820 }
1821
701a69da 1822 /**
1823 * Test creating multiple phones using chaining.
1824 *
1825 * @throws \Exception
1826 */
00be9182 1827 public function testCRM13252MultipleChainedPhones() {
265cc07d 1828 $contactID = $this->householdCreate();
1829 $this->callAPISuccessGetCount('phone', array('contact_id' => $contactID), 0);
1830 $params = array(
5896d037
TO
1831 'contact_id' => $contactID,
1832 'household_name' => 'Household 1',
1833 'contact_type' => 'Household',
1834 'api.phone.create' => array(
265cc07d 1835 0 => array(
1836 'phone' => '111-111-1111',
1837 'location_type_id' => 1,
1838 'phone_type_id' => 1,
1839 ),
1840 1 => array(
1841 'phone' => '222-222-2222',
1842 'location_type_id' => 1,
1843 'phone_type_id' => 2,
21dfd5f5
TO
1844 ),
1845 ),
265cc07d 1846 );
4b58ed3b 1847 $this->callAPISuccess('contact', 'create', $params);
265cc07d 1848 $this->callAPISuccessGetCount('phone', array('contact_id' => $contactID), 2);
1849
1850 }
5896d037 1851
e635f9d4 1852 /**
fe482240 1853 * Test for Contact.get id=@user:username (with an invalid username).
e635f9d4 1854 */
00be9182 1855 public function testContactGetByUnknownUsername() {
e635f9d4
TO
1856 // setup - mock the calls to CRM_Utils_System_*::getUfId
1857 $userSystem = $this->getMock('CRM_Utils_System_UnitTests', array('getUfId'));
1858 $userSystem->expects($this->once())
1859 ->method('getUfId')
1860 ->with($this->equalTo('exampleUser'))
1861 ->will($this->returnValue(NULL));
1862 CRM_Core_Config::singleton()->userSystem = $userSystem;
1863
1864 // perform a lookup
1865 $result = $this->callAPIFailure('Contact', 'get', array(
e635f9d4
TO
1866 'id' => '@user:exampleUser',
1867 ));
1868 $this->assertRegExp('/cannot be resolved to a contact ID/', $result['error_message']);
1869 }
1870
6a488035 1871 /**
701a69da 1872 * Verify attempt to create individual with chained arrays and sequential.
48bb2598
JV
1873 */
1874 public function testGetIndividualWithChainedArraysAndSequential() {
1875 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__, __FILE__);
1876 $params['custom_' . $ids['custom_field_id']] = "custom string";
1877
84b51197 1878 $moreIDs = $this->CustomGroupMultipleCreateWithFields();
48bb2598
JV
1879 $params = array(
1880 'sequential' => 1,
1881 'first_name' => 'abc3',
1882 'last_name' => 'xyz3',
1883 'contact_type' => 'Individual',
1884 'email' => 'man3@yahoo.com',
1885 'api.website.create' => array(
1886 array(
1887 'url' => "http://civicrm.org",
1888 ),
1889 array(
1890 'url' => "https://civicrm.org",
1891 ),
1892 ),
1893 );
1894
1895 $result = $this->callAPISuccess('Contact', 'create', $params);
1896
48bb2598
JV
1897 // delete the contact and custom groups
1898 $this->callAPISuccess('contact', 'delete', array('id' => $result['id']));
1899 $this->customGroupDelete($ids['custom_group_id']);
84b51197 1900 $this->customGroupDelete($moreIDs['custom_group_id']);
48bb2598
JV
1901
1902 $this->assertEquals($result['id'], $result['values'][0]['id']);
1903 $this->assertArrayKeyExists('api.website.create', $result['values'][0]);
1904 }
1905
1906 /**
701a69da 1907 * Verify attempt to create individual with chained arrays.
6a488035 1908 */
00be9182 1909 public function testGetIndividualWithChainedArrays() {
6a488035
TO
1910 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__, __FILE__);
1911 $params['custom_' . $ids['custom_field_id']] = "custom string";
1912
381fa321 1913 $moreIDs = $this->CustomGroupMultipleCreateWithFields();
5c49fee0 1914 $description = "This demonstrates the usage of chained api functions.\nIn this case no notes or custom fields have been created.";
5896d037
TO
1915 $subfile = "APIChainedArray";
1916 $params = array(
6a488035
TO
1917 'first_name' => 'abc3',
1918 'last_name' => 'xyz3',
1919 'contact_type' => 'Individual',
1920 'email' => 'man3@yahoo.com',
6a488035
TO
1921 'api.contribution.create' => array(
1922 'receive_date' => '2010-01-01',
1923 'total_amount' => 100.00,
1924 'financial_type_id' => 1,
1925 'payment_instrument_id' => 1,
1926 'non_deductible_amount' => 10.00,
1927 'fee_amount' => 50.00,
1928 'net_amount' => 90.00,
1929 'trxn_id' => 12345,
1930 'invoice_id' => 67890,
1931 'source' => 'SSF',
1932 'contribution_status_id' => 1,
1933 ),
1934 'api.contribution.create.1' => array(
1935 'receive_date' => '2011-01-01',
1936 'total_amount' => 120.00,
6c6e6187 1937 'financial_type_id' => $this->_financialTypeId = 1,
6a488035
TO
1938 'payment_instrument_id' => 1,
1939 'non_deductible_amount' => 10.00,
1940 'fee_amount' => 50.00,
1941 'net_amount' => 90.00,
1942 'trxn_id' => 12335,
1943 'invoice_id' => 67830,
1944 'source' => 'SSF',
1945 'contribution_status_id' => 1,
1946 ),
1947 'api.website.create' => array(
1948 array(
1949 'url' => "http://civicrm.org",
1950 ),
1951 ),
1952 );
1953
f6722559 1954 $result = $this->callAPISuccess('Contact', 'create', $params);
6a488035 1955 $params = array(
f6722559 1956 'id' => $result['id'],
6a488035
TO
1957 'api.website.get' => array(),
1958 'api.Contribution.get' => array(
1959 'total_amount' => '120.00',
5896d037
TO
1960 ),
1961 'api.CustomValue.get' => 1,
6a488035
TO
1962 'api.Note.get' => 1,
1963 );
f6722559 1964 $result = $this->callAPIAndDocument('Contact', 'Get', $params, __FUNCTION__, __FILE__, $description, $subfile);
6a488035 1965 // delete the contact
f6722559 1966 $this->callAPISuccess('contact', 'delete', $result);
6a488035 1967 $this->customGroupDelete($ids['custom_group_id']);
381fa321 1968 $this->customGroupDelete($moreIDs['custom_group_id']);
4b58ed3b
EM
1969 $this->assertEquals(0, $result['values'][$result['id']]['api.website.get']['is_error']);
1970 $this->assertEquals("http://civicrm.org", $result['values'][$result['id']]['api.website.get']['values'][0]['url']);
6a488035
TO
1971 }
1972
a77b0380 1973 /**
701a69da 1974 * Verify attempt to create individual with chained arrays and sequential.
a77b0380
JV
1975 *
1976 * See https://issues.civicrm.org/jira/browse/CRM-15815
1977 */
1978 public function testCreateIndividualWithChainedArrayAndSequential() {
1979 $params = array(
1980 'sequential' => 1,
1981 'first_name' => 'abc5',
1982 'last_name' => 'xyz5',
1983 'contact_type' => 'Individual',
1984 'email' => 'woman5@yahoo.com',
1985 'api.phone.create' => array(
1986 array('phone' => '03-231 07 95'),
1987 array('phone' => '03-232 51 62'),
1988 ),
1989 'api.website.create' => array(
1990 'url' => 'http://civicrm.org',
1991 ),
1992 );
1993 $result = $this->callAPISuccess('Contact', 'create', $params);
1994
1995 // I could try to parse the result to see whether the two phone numbers
1996 // and the website are there, but I am not sure about the correct format.
1997 // So I will just fetch it again before checking.
1998 // See also http://forum.civicrm.org/index.php/topic,35393.0.html
1999 $params = array(
2000 'sequential' => 1,
2001 'id' => $result['id'],
2002 'api.website.get' => array(),
2003 'api.phone.get' => array(),
2004 );
2005 $result = $this->callAPISuccess('Contact', 'get', $params);
2006
2007 // delete the contact
2008 $this->callAPISuccess('contact', 'delete', $result);
2009
2010 $this->assertEquals(2, $result['values'][0]['api.phone.get']['count']);
2011 $this->assertEquals(1, $result['values'][0]['api.website.get']['count']);
2012 }
2013
701a69da 2014 /**
2015 * Test retrieving an individual with chained array syntax.
2016 */
00be9182 2017 public function testGetIndividualWithChainedArraysFormats() {
5c49fee0 2018 $description = "This demonstrates the usage of chained api functions.\nIn this case no notes or custom fields have been created.";
6a488035
TO
2019 $subfile = "APIChainedArrayFormats";
2020 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__, __FILE__);
2021 $params['custom_' . $ids['custom_field_id']] = "custom string";
2022
381fa321 2023 $moreIDs = $this->CustomGroupMultipleCreateWithFields();
6a488035
TO
2024 $params = array(
2025 'first_name' => 'abc3',
2026 'last_name' => 'xyz3',
2027 'contact_type' => 'Individual',
2028 'email' => 'man3@yahoo.com',
6a488035
TO
2029 'api.contribution.create' => array(
2030 'receive_date' => '2010-01-01',
2031 'total_amount' => 100.00,
f6722559 2032 'financial_type_id' => $this->_financialTypeId,
6a488035
TO
2033 'payment_instrument_id' => 1,
2034 'non_deductible_amount' => 10.00,
2035 'fee_amount' => 50.00,
2036 'net_amount' => 90.00,
2037 'source' => 'SSF',
2038 'contribution_status_id' => 1,
2039 ),
2040 'api.contribution.create.1' => array(
2041 'receive_date' => '2011-01-01',
2042 'total_amount' => 120.00,
f6722559 2043 'financial_type_id' => $this->_financialTypeId,
6a488035
TO
2044 'payment_instrument_id' => 1,
2045 'non_deductible_amount' => 10.00,
2046 'fee_amount' => 50.00,
2047 'net_amount' => 90.00,
2048 'source' => 'SSF',
2049 'contribution_status_id' => 1,
2050 ),
2051 'api.website.create' => array(
2052 array(
2053 'url' => "http://civicrm.org",
2054 ),
2055 ),
2056 );
2057
f6722559 2058 $result = $this->callAPISuccess('Contact', 'create', $params);
6a488035 2059 $params = array(
f6722559 2060 'id' => $result['id'],
6a488035
TO
2061 'api.website.getValue' => array('return' => 'url'),
2062 'api.Contribution.getCount' => array(),
2063 'api.CustomValue.get' => 1,
2064 'api.Note.get' => 1,
2065 'api.Membership.getCount' => array(),
2066 );
f6722559 2067 $result = $this->callAPIAndDocument('Contact', 'Get', $params, __FUNCTION__, __FILE__, $description, $subfile);
4b58ed3b
EM
2068 $this->assertEquals(2, $result['values'][$result['id']]['api.Contribution.getCount']);
2069 $this->assertEquals(0, $result['values'][$result['id']]['api.Note.get']['is_error']);
2070 $this->assertEquals("http://civicrm.org", $result['values'][$result['id']]['api.website.getValue']);
6a488035 2071
f6722559 2072 $this->callAPISuccess('contact', 'delete', $result);
6a488035 2073 $this->customGroupDelete($ids['custom_group_id']);
381fa321 2074 $this->customGroupDelete($moreIDs['custom_group_id']);
6a488035
TO
2075 }
2076
381fa321 2077 /**
2078 * Test complex chaining.
2079 */
00be9182 2080 public function testGetIndividualWithChainedArraysAndMultipleCustom() {
6a488035
TO
2081 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__, __FILE__);
2082 $params['custom_' . $ids['custom_field_id']] = "custom string";
381fa321 2083 $moreIDs = $this->CustomGroupMultipleCreateWithFields();
2084 $andMoreIDs = $this->CustomGroupMultipleCreateWithFields(array(
92915c55
TO
2085 'title' => "another group",
2086 'name' => 'another name',
2087 ));
5c49fee0 2088 $description = "This demonstrates the usage of chained api functions with multiple custom fields.";
6a488035
TO
2089 $subfile = "APIChainedArrayMultipleCustom";
2090 $params = array(
2091 'first_name' => 'abc3',
2092 'last_name' => 'xyz3',
2093 'contact_type' => 'Individual',
2094 'email' => 'man3@yahoo.com',
6a488035
TO
2095 'api.contribution.create' => array(
2096 'receive_date' => '2010-01-01',
2097 'total_amount' => 100.00,
5896d037 2098 'financial_type_id' => 1,
6a488035
TO
2099 'payment_instrument_id' => 1,
2100 'non_deductible_amount' => 10.00,
2101 'fee_amount' => 50.00,
2102 'net_amount' => 90.00,
2103 'trxn_id' => 12345,
2104 'invoice_id' => 67890,
2105 'source' => 'SSF',
2106 'contribution_status_id' => 1,
2107 ),
2108 'api.contribution.create.1' => array(
2109 'receive_date' => '2011-01-01',
2110 'total_amount' => 120.00,
5896d037 2111 'financial_type_id' => 1,
6a488035
TO
2112 'payment_instrument_id' => 1,
2113 'non_deductible_amount' => 10.00,
2114 'fee_amount' => 50.00,
2115 'net_amount' => 90.00,
2116 'trxn_id' => 12335,
2117 'invoice_id' => 67830,
2118 'source' => 'SSF',
2119 'contribution_status_id' => 1,
2120 ),
2121 'api.website.create' => array(
2122 array(
2123 'url' => "http://civicrm.org",
2124 ),
2125 ),
2126 'custom_' . $ids['custom_field_id'] => "value 1",
381fa321 2127 'custom_' . $moreIDs['custom_field_id'][0] => "value 2",
2128 'custom_' . $moreIDs['custom_field_id'][1] => "warm beer",
2129 'custom_' . $andMoreIDs['custom_field_id'][1] => "vegemite",
6a488035
TO
2130 );
2131
f6722559 2132 $result = $this->callAPISuccess('Contact', 'create', $params);
2133 $result = $this->callAPISuccess('Contact', 'create', array(
6c6e6187 2134 'contact_type' => 'Individual',
5896d037
TO
2135 'id' => $result['id'],
2136 'custom_' .
381fa321 2137 $moreIDs['custom_field_id'][0] => "value 3",
5896d037
TO
2138 'custom_' .
2139 $ids['custom_field_id'] => "value 4",
2140 ));
6a488035
TO
2141
2142 $params = array(
f6722559 2143 'id' => $result['id'],
6a488035
TO
2144 'api.website.getValue' => array('return' => 'url'),
2145 'api.Contribution.getCount' => array(),
2146 'api.CustomValue.get' => 1,
2147 );
f6722559 2148 $result = $this->callAPIAndDocument('Contact', 'Get', $params, __FUNCTION__, __FILE__, $description, $subfile);
2149
6a488035 2150 $this->customGroupDelete($ids['custom_group_id']);
381fa321 2151 $this->customGroupDelete($moreIDs['custom_group_id']);
2152 $this->customGroupDelete($andMoreIDs['custom_group_id']);
4b58ed3b
EM
2153 $this->assertEquals(0, $result['values'][$result['id']]['api.CustomValue.get']['is_error']);
2154 $this->assertEquals('http://civicrm.org', $result['values'][$result['id']]['api.website.getValue']);
6a488035 2155 }
5896d037 2156
d424ffde 2157 /**
381fa321 2158 * Test checks usage of $values to pick & choose inputs.
6a488035 2159 */
00be9182 2160 public function testChainingValuesCreate() {
5c49fee0
CW
2161 $description = "This demonstrates the usage of chained api functions. Specifically it has one 'parent function' &
2162 2 child functions - one receives values from the parent (Contact) and the other child (Tag).";
6a488035
TO
2163 $subfile = "APIChainedArrayValuesFromSiblingFunction";
2164 $params = array(
6c6e6187 2165 'display_name' => 'batman',
5896d037 2166 'contact_type' => 'Individual',
701a69da 2167 'api.tag.create' => array(
2168 'name' => '$value.id',
2169 'description' => '$value.display_name',
2170 'format.only_id' => 1,
2171 ),
6a488035
TO
2172 'api.entity_tag.create' => array('tag_id' => '$value.api.tag.create'),
2173 );
f6722559 2174 $result = $this->callAPIAndDocument('Contact', 'Create', $params, __FUNCTION__, __FILE__, $description, $subfile);
6a488035 2175 $this->assertEquals(0, $result['values'][$result['id']]['api.entity_tag.create']['is_error']);
f6722559 2176
6a488035
TO
2177 $tablesToTruncate = array(
2178 'civicrm_contact',
2179 'civicrm_activity',
2180 'civicrm_entity_tag',
2181 'civicrm_tag',
2182 );
2183 $this->quickCleanup($tablesToTruncate, TRUE);
2184 }
2185
d424ffde 2186 /**
fe482240 2187 * Test TrueFalse format - I couldn't come up with an easy way to get an error on Get.
6a488035 2188 */
00be9182 2189 public function testContactGetFormatIsSuccessTrue() {
6a488035
TO
2190 $this->createContactFromXML();
2191 $description = "This demonstrates use of the 'format.is_success' param.
2192 This param causes only the success or otherwise of the function to be returned as BOOLEAN";
2193 $subfile = "FormatIsSuccess_True";
5896d037
TO
2194 $params = array('id' => 17, 'format.is_success' => 1);
2195 $result = $this->callAPIAndDocument('Contact', 'Get', $params, __FUNCTION__, __FILE__, $description, $subfile);
6a488035 2196 $this->assertEquals(1, $result);
f6722559 2197 $this->callAPISuccess('Contact', 'Delete', $params);
6a488035 2198 }
5896d037 2199
d424ffde 2200 /**
fe482240 2201 * Test TrueFalse format.
6a488035 2202 */
00be9182 2203 public function testContactCreateFormatIsSuccessFalse() {
6a488035
TO
2204
2205 $description = "This demonstrates use of the 'format.is_success' param.
2206 This param causes only the success or otherwise of the function to be returned as BOOLEAN";
2207 $subfile = "FormatIsSuccess_Fail";
5896d037
TO
2208 $params = array('id' => 500, 'format.is_success' => 1);
2209 $result = $this->callAPIAndDocument('Contact', 'Create', $params, __FUNCTION__, __FILE__, $description, $subfile);
6a488035
TO
2210 $this->assertEquals(0, $result);
2211 }
5896d037 2212
d424ffde 2213 /**
fe482240 2214 * Test Single Entity format.
6a488035 2215 */
fe482240 2216 public function testContactGetSingleEntityArray() {
6a488035
TO
2217 $this->createContactFromXML();
2218 $description = "This demonstrates use of the 'format.single_entity_array' param.
5c49fee0
CW
2219 This param causes the only contact to be returned as an array without the other levels.
2220 It will be ignored if there is not exactly 1 result";
6a488035 2221 $subfile = "GetSingleContact";
5896d037
TO
2222 $params = array('id' => 17);
2223 $result = $this->callAPIAndDocument('Contact', 'GetSingle', $params, __FUNCTION__, __FILE__, $description, $subfile);
4b58ed3b 2224 $this->assertEquals('Test Contact', $result['display_name']);
f6722559 2225 $this->callAPISuccess('Contact', 'Delete', $params);
6a488035
TO
2226 }
2227
d424ffde 2228 /**
381fa321 2229 * Test Single Entity format.
6a488035 2230 */
fe482240 2231 public function testContactGetFormatCountOnly() {
6a488035 2232 $this->createContactFromXML();
5c49fee0
CW
2233 $description = "This demonstrates use of the 'getCount' action.
2234 This param causes the count of the only function to be returned as an integer.";
5896d037 2235 $params = array('id' => 17);
381fa321 2236 $result = $this->callAPIAndDocument('Contact', 'GetCount', $params, __FUNCTION__, __FILE__, $description,
84b51197 2237 'GetCountContact');
4b58ed3b 2238 $this->assertEquals('1', $result);
f6722559 2239 $this->callAPISuccess('Contact', 'Delete', $params);
6a488035 2240 }
5896d037 2241
d424ffde 2242 /**
381fa321 2243 * Test id only format.
408b79bf 2244 */
fe482240 2245 public function testContactGetFormatIDOnly() {
6a488035 2246 $this->createContactFromXML();
5c49fee0
CW
2247 $description = "This demonstrates use of the 'format.id_only' param.
2248 This param causes the id of the only entity to be returned as an integer.
2249 It will be ignored if there is not exactly 1 result";
6a488035 2250 $subfile = "FormatOnlyID";
5896d037
TO
2251 $params = array('id' => 17, 'format.only_id' => 1);
2252 $result = $this->callAPIAndDocument('Contact', 'Get', $params, __FUNCTION__, __FILE__, $description, $subfile);
4b58ed3b 2253 $this->assertEquals('17', $result);
f6722559 2254 $this->callAPISuccess('Contact', 'Delete', $params);
6a488035
TO
2255 }
2256
d424ffde 2257 /**
381fa321 2258 * Test id only format.
408b79bf 2259 */
00be9182 2260 public function testContactGetFormatSingleValue() {
6a488035
TO
2261 $this->createContactFromXML();
2262 $description = "This demonstrates use of the 'format.single_value' param.
5c49fee0
CW
2263 This param causes only a single value of the only entity to be returned as an string.
2264 It will be ignored if there is not exactly 1 result";
4b58ed3b 2265 $subFile = "FormatSingleValue";
5896d037 2266 $params = array('id' => 17, 'return' => 'display_name');
a828d7b8 2267 $result = $this->callAPIAndDocument('Contact', 'getvalue', $params, __FUNCTION__, __FILE__, $description, $subFile);
4b58ed3b 2268 $this->assertEquals('Test Contact', $result);
f6722559 2269 $this->callAPISuccess('Contact', 'Delete', $params);
6a488035
TO
2270 }
2271
b2130237 2272 /**
381fa321 2273 * Test that permissions are respected when creating contacts.
b2130237 2274 */
00be9182 2275 public function testContactCreationPermissions() {
6a488035 2276 $params = array(
6c6e6187 2277 'contact_type' => 'Individual',
5896d037 2278 'first_name' => 'Foo',
6a488035
TO
2279 'last_name' => 'Bear',
2280 'check_permissions' => TRUE,
6a488035
TO
2281 );
2282 $config = CRM_Core_Config::singleton();
2283 $config->userPermissionClass->permissions = array('access CiviCRM');
d0e1eff2 2284 $result = $this->callAPIFailure('contact', 'create', $params);
1644b908 2285 $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
2286
2287 $config->userPermissionClass->permissions = array('access CiviCRM', 'add contacts', 'import contacts');
701a69da 2288 $this->callAPISuccess('contact', 'create', $params);
6a488035
TO
2289 }
2290
fa6448fa
EM
2291 /**
2292 * Test that delete with skip undelete respects permissions.
2293 */
2294 public function testContactDeletePermissions() {
2295 $contactID = $this->individualCreate();
2296 CRM_Core_Config::singleton()->userPermissionClass->permissions = array('access CiviCRM');
2297 $this->callAPIFailure('Contact', 'delete', array(
2298 'id' => $contactID,
2299 'check_permissions' => 1,
2300 'skip_undelete' => 1,
2301 ));
2302 $this->callAPISuccess('Contact', 'delete', array(
2303 'id' => $contactID,
2304 'check_permissions' => 0,
2305 'skip_undelete' => 1,
2306 ));
2307 }
2308
381fa321 2309 /**
2310 * Test update with check permissions set.
2311 */
00be9182 2312 public function testContactUpdatePermissions() {
5896d037
TO
2313 $params = array(
2314 'contact_type' => 'Individual',
2315 'first_name' => 'Foo',
2316 'last_name' => 'Bear',
21dfd5f5 2317 'check_permissions' => TRUE,
5896d037 2318 );
f6722559 2319 $result = $this->callAPISuccess('contact', 'create', $params);
6a488035 2320 $config = CRM_Core_Config::singleton();
5896d037
TO
2321 $params = array(
2322 'id' => $result['id'],
2323 'contact_type' => 'Individual',
2324 'last_name' => 'Bar',
21dfd5f5 2325 'check_permissions' => TRUE,
5896d037 2326 );
6a488035
TO
2327
2328 $config->userPermissionClass->permissions = array('access CiviCRM');
d0e1eff2 2329 $result = $this->callAPIFailure('contact', 'update', $params);
0a61b6e2 2330 $this->assertEquals('Permission denied to modify contact record', $result['error_message']);
6a488035 2331
5896d037
TO
2332 $config->userPermissionClass->permissions = array(
2333 'access CiviCRM',
2334 'add contacts',
2335 'view all contacts',
2336 'edit all contacts',
21dfd5f5 2337 'import contacts',
5896d037 2338 );
701a69da 2339 $this->callAPISuccess('contact', 'update', $params);
6a488035
TO
2340 }
2341
381fa321 2342 /**
2343 * Set up helper to create a contact.
2344 */
00be9182 2345 public function createContactFromXML() {
381fa321 2346 // Insert a row in civicrm_contact creating contact 17.
6a488035
TO
2347 $op = new PHPUnit_Extensions_Database_Operation_Insert();
2348 $op->execute($this->_dbconn,
bbfd46a5 2349 $this->createXMLDataSet(
6a488035
TO
2350 dirname(__FILE__) . '/dataset/contact_17.xml'
2351 )
2352 );
2353 }
2354
381fa321 2355 /**
2356 * Test contact proximity api.
2357 */
00be9182 2358 public function testContactProximity() {
6a488035
TO
2359 // first create a contact with a SF location with a specific
2360 // geocode
2361 $contactID = $this->organizationCreate();
2362
2363 // now create the address
2364 $params = array(
2365 'street_address' => '123 Main Street',
2366 'city' => 'San Francisco',
2367 'is_primary' => 1,
2368 'country_id' => 1228,
2369 'state_province_id' => 1004,
2370 'geo_code_1' => '37.79',
2371 'geo_code_2' => '-122.40',
2372 'location_type_id' => 1,
2373 'contact_id' => $contactID,
6a488035
TO
2374 );
2375
f6722559 2376 $result = $this->callAPISuccess('address', 'create', $params);
ba4a1892 2377 $this->assertEquals(1, $result['count']);
6a488035
TO
2378
2379 // now do a proximity search with a close enough geocode and hope to match
2380 // that specific contact only!
2381 $proxParams = array(
2382 'latitude' => 37.7,
2383 'longitude' => -122.3,
2384 'unit' => 'mile',
2385 'distance' => 10,
6a488035 2386 );
f6722559 2387 $result = $this->callAPISuccess('contact', 'proximity', $proxParams);
ba4a1892 2388 $this->assertEquals(1, $result['count']);
6a488035 2389 }
60ec9f43
E
2390
2391 /**
381fa321 2392 * Test that Ajax API permission is sufficient to access getquick api.
2393 *
1d6020f1 2394 * (note that getquick api is required for autocomplete & has ACL permissions applied)
60ec9f43 2395 */
fe482240 2396 public function testGetquickPermissionCRM13744() {
60ec9f43 2397 CRM_Core_Config::singleton()->userPermissionClass->permissions = array('access CiviEvent');
4b58ed3b 2398 $this->callAPIFailure('contact', 'getquick', array('name' => 'b', 'check_permissions' => TRUE));
60ec9f43 2399 CRM_Core_Config::singleton()->userPermissionClass->permissions = array('access CiviCRM');
4b58ed3b 2400 $this->callAPISuccess('contact', 'getquick', array('name' => 'b', 'check_permissions' => TRUE));
60ec9f43 2401 CRM_Core_Config::singleton()->userPermissionClass->permissions = array('access AJAX API');
4b58ed3b 2402 $this->callAPISuccess('contact', 'getquick', array('name' => 'b', 'check_permissions' => TRUE));
60ec9f43 2403 }
9c8096cb 2404
08f4ab8d 2405 /**
2406 * Test that getquick returns contacts with an exact first name match first.
2baa1e00 2407 *
2408 * The search string 'b' & 'bob' both return ordered by sort_name if includeOrderByClause
2409 * is true (default) but if it is false then matches are returned in ID order.
08f4ab8d 2410 */
2411 public function testGetQuickExactFirst() {
2412 $this->getQuickSearchSampleData();
2413 $result = $this->callAPISuccess('contact', 'getquick', array('name' => 'b'));
2414 $this->assertEquals('A Bobby, Bobby', $result['values'][0]['sort_name']);
2baa1e00 2415 $this->assertEquals('B Bobby, Bobby', $result['values'][1]['sort_name']);
08f4ab8d 2416 $result = $this->callAPISuccess('contact', 'getquick', array('name' => 'bob'));
2417 $this->assertEquals('A Bobby, Bobby', $result['values'][0]['sort_name']);
2baa1e00 2418 $this->assertEquals('B Bobby, Bobby', $result['values'][1]['sort_name']);
2419 $this->callAPISuccess('Setting', 'create', array('includeOrderByClause' => FALSE));
2420 $result = $this->callAPISuccess('contact', 'getquick', array('name' => 'bob'));
2421 $this->assertEquals('Bob, Bob', $result['values'][0]['sort_name']);
2422 $this->assertEquals('A Bobby, Bobby', $result['values'][1]['sort_name']);
2423 }
2424
e9e27a80 2425 /**
2426 * Test that getquick returns contacts with an exact first name match first.
2427 */
2428 public function testGetQuickEmail() {
2429 $this->getQuickSearchSampleData();
1ca22999 2430 $loggedInContactID = $this->createLoggedInUser();
e9e27a80 2431 $result = $this->callAPISuccess('contact', 'getquick', array(
2432 'name' => 'c',
2433 ));
2434 $expectedData = array(
2435 'Bob, Bob :: bob@bob.com',
2436 'C Bobby, Bobby',
2437 'E Bobby, Bobby :: bob@bobby.com',
2438 'H Bobby, Bobby :: bob@h.com',
1ca22999 2439 'Second Domain',
2440 $this->callAPISuccessGetValue('Contact', array('id' => $loggedInContactID, 'return' => 'last_name')) . ', Logged In :: anthony_anderson@civicrm.org',
e9e27a80 2441 );
1ca22999 2442 $this->assertEquals(6, $result['count']);
e9e27a80 2443 foreach ($expectedData as $index => $value) {
2444 $this->assertEquals($value, $result['values'][$index]['data']);
2445 }
7f6f3df1 2446 $result = $this->callAPISuccess('contact', 'getquick', array(
2447 'name' => 'h.',
2448 ));
2449 $expectedData = array(
2450 'H Bobby, Bobby :: bob@h.com',
2451 );
2452 foreach ($expectedData as $index => $value) {
2453 $this->assertEquals($value, $result['values'][$index]['data']);
2454 }
2455 $this->callAPISuccess('Setting', 'create', array('includeWildCardInName' => FALSE));
2456 $result = $this->callAPISuccess('contact', 'getquick', array(
2457 'name' => 'h.',
2458 ));
2459 $this->callAPISuccess('Setting', 'create', array('includeWildCardInName' => TRUE));
2460 $this->assertEquals(0, $result['count']);
e9e27a80 2461 }
2462
c37a2d66 2463 /**
2464 * Test that getquick returns contacts with an exact first name match first.
2465 */
2466 public function testGetQuickEmailACL() {
2467 $this->getQuickSearchSampleData();
1ca22999 2468 $loggedInContactID = $this->createLoggedInUser();
c37a2d66 2469 CRM_Core_Config::singleton()->userPermissionClass->permissions = array();
2470 $result = $this->callAPISuccess('contact', 'getquick', array(
2471 'name' => 'c',
2472 ));
2473 $this->assertEquals(0, $result['count']);
2474
2475 $this->hookClass->setHook('civicrm_aclWhereClause', array($this, 'aclWhereNoBobH'));
1ca22999 2476 CRM_Contact_BAO_Contact_Permission::cache($loggedInContactID, CRM_Core_Permission::VIEW, TRUE);
c37a2d66 2477 $result = $this->callAPISuccess('contact', 'getquick', array(
2478 'name' => 'c',
2479 ));
1ca22999 2480
2481 // Without the acl it would be 6 like the previous email getquick test.
2482 $this->assertEquals(5, $result['count']);
c37a2d66 2483 $expectedData = array(
2484 'Bob, Bob :: bob@bob.com',
2485 'C Bobby, Bobby',
2486 'E Bobby, Bobby :: bob@bobby.com',
1ca22999 2487 'Second Domain',
2488 $this->callAPISuccessGetValue('Contact', array('id' => $loggedInContactID, 'return' => 'last_name')) . ', Logged In :: anthony_anderson@civicrm.org',
c37a2d66 2489 );
2490 foreach ($expectedData as $index => $value) {
2491 $this->assertEquals($value, $result['values'][$index]['data']);
2492 }
2493 }
2494
2baa1e00 2495 /**
2496 * Test that getquick returns contacts with an exact first name match first.
2497 */
2498 public function testGetQuickExternalID() {
2499 $this->getQuickSearchSampleData();
2500 $result = $this->callAPISuccess('contact', 'getquick', array(
2501 'name' => 'b',
2502 'field_name' => 'external_identifier',
2503 'table_name' => 'cc',
2504 ));
2505 $this->assertEquals(0, $result['count']);
2506 $result = $this->callAPISuccess('contact', 'getquick', array(
2507 'name' => 'abc',
2508 'field_name' => 'external_identifier',
2509 'table_name' => 'cc',
2510 ));
2511 $this->assertEquals(1, $result['count']);
2512 $this->assertEquals('Bob, Bob', $result['values'][0]['sort_name']);
2513 }
2514
2515 /**
2516 * Test that getquick returns contacts with an exact first name match first.
2517 */
2518 public function testGetQuickID() {
1ca22999 2519 $max = CRM_Core_DAO::singleValueQuery("SELECT max(id) FROM civicrm_contact");
2baa1e00 2520 $this->getQuickSearchSampleData();
2521 $result = $this->callAPISuccess('contact', 'getquick', array(
1ca22999 2522 'name' => $max + 2,
2baa1e00 2523 'field_name' => 'id',
2524 'table_name' => 'cc',
2525 ));
2526 $this->assertEquals(1, $result['count']);
2527 $this->assertEquals('A Bobby, Bobby', $result['values'][0]['sort_name']);
2528 $result = $this->callAPISuccess('contact', 'getquick', array(
1ca22999 2529 'name' => $max + 2,
2baa1e00 2530 'field_name' => 'contact_id',
2531 'table_name' => 'cc',
2532 ));
2533 $this->assertEquals(1, $result['count']);
2534 $this->assertEquals('A Bobby, Bobby', $result['values'][0]['sort_name']);
2535 }
2536
2537 /**
2538 * Test that getquick returns contacts with an exact first name match first.
ef3fd279 2539 *
2540 * Depending on the setting the sort name sort might click in next or not - test!
2baa1e00 2541 */
2542 public function testGetQuickFirstName() {
2543 $this->getQuickSearchSampleData();
ef3fd279 2544 $this->callAPISuccess('Setting', 'create', array('includeOrderByClause' => TRUE));
2baa1e00 2545 $result = $this->callAPISuccess('contact', 'getquick', array(
2546 'name' => 'Bob',
2547 'field_name' => 'first_name',
2548 'table_name' => 'cc',
2549 ));
e9e27a80 2550 $expected = array(
2551 'Bob, Bob',
2552 'K Bobby, Bob',
2553 'A Bobby, Bobby',
2554 );
2555
2556 foreach ($expected as $index => $value) {
2557 $this->assertEquals($value, $result['values'][$index]['sort_name']);
2558 }
08f4ab8d 2559 $this->callAPISuccess('Setting', 'create', array('includeOrderByClause' => FALSE));
2560 $result = $this->callAPISuccess('contact', 'getquick', array('name' => 'bob'));
2561 $this->assertEquals('Bob, Bob', $result['values'][0]['sort_name']);
ef3fd279 2562 $this->assertEquals('A Bobby, Bobby', $result['values'][1]['sort_name']);
08f4ab8d 2563 }
2564
1b9c2802 2565 /**
2566 * Test that getquick applies ACLs.
2567 */
2568 public function testGetQuickFirstNameACLs() {
2569 $this->getQuickSearchSampleData();
2570 $userID = $this->createLoggedInUser();
c37a2d66 2571 $this->callAPISuccess('Setting', 'create', array('includeOrderByClause' => TRUE));
1b9c2802 2572 CRM_Core_Config::singleton()->userPermissionClass->permissions = array();
2573 $result = $this->callAPISuccess('contact', 'getquick', array(
2574 'name' => 'Bob',
2575 'field_name' => 'first_name',
2576 'table_name' => 'cc',
2577 ));
2578 $this->assertEquals(0, $result['count']);
2579
2580 $this->hookClass->setHook('civicrm_aclWhereClause', array($this, 'aclWhereNoBobH'));
2581 CRM_Contact_BAO_Contact_Permission::cache($userID, CRM_Core_Permission::VIEW, TRUE);
2582 $result = $this->callAPISuccess('contact', 'getquick', array(
2583 'name' => 'Bob',
2584 'field_name' => 'first_name',
2585 'table_name' => 'cc',
2586 ));
2587 $this->assertEquals('K Bobby, Bob', $result['values'][1]['sort_name']);
2588 // Without the ACL 9 would be bob@h.com.
2589 $this->assertEquals('I Bobby, Bobby', $result['values'][9]['sort_name']);
1b9c2802 2590 }
2591
2592 /**
2593 * Full results returned.
2594 * @implements CRM_Utils_Hook::aclWhereClause
2595 *
2596 * @param string $type
2597 * @param array $tables
2598 * @param array $whereTables
2599 * @param int $contactID
2600 * @param string $where
2601 */
2602 public function aclWhereNoBobH($type, &$tables, &$whereTables, &$contactID, &$where) {
c37a2d66 2603 $where = " (email <> 'bob@h.com' OR email IS NULL) ";
1b9c2802 2604 $whereTables['civicrm_email'] = "LEFT JOIN civicrm_email e ON contact_a.id = e.contact_id";
2605 }
2606
e9e27a80 2607 /**
2608 * Test that getquick returns contacts with an exact last name match first.
2609 */
2610 public function testGetQuickLastName() {
2611 $this->getQuickSearchSampleData();
2612 $this->callAPISuccess('Setting', 'create', array('includeOrderByClause' => TRUE));
2613 $result = $this->callAPISuccess('contact', 'getquick', array(
2614 'name' => 'Bob',
2615 'field_name' => 'last_name',
2616 'table_name' => 'cc',
2617 ));
2618 $expected = array(
2619 'Bob, Bob',
2620 'A Bobby, Bobby',
36575b09 2621 'B Bobby, Bobby',
e9e27a80 2622 );
2623
2624 foreach ($expected as $index => $value) {
2625 $this->assertEquals($value, $result['values'][$index]['sort_name']);
2626 }
2627 $this->callAPISuccess('Setting', 'create', array('includeOrderByClause' => FALSE));
2628 $result = $this->callAPISuccess('contact', 'getquick', array('name' => 'bob'));
2629 $this->assertEquals('Bob, Bob :: bob@bob.com', $result['values'][0]['data']);
2630 }
2631
2632 /**
2633 * Test that getquick returns contacts by city.
2634 */
2635 public function testGetQuickCity() {
2636 $this->getQuickSearchSampleData();
2637 $result = $this->callAPISuccess('contact', 'getquick', array(
2638 'name' => 'o',
2639 'field_name' => 'city',
2640 'table_name' => 'sts',
2641 ));
2642 $this->assertEquals('B Bobby, Bobby :: Toronto', $result['values'][0]['data']);
2643 $result = $this->callAPISuccess('contact', 'getquick', array(
2644 'name' => 'n',
2645 'field_name' => 'city',
2646 'table_name' => 'sts',
2647 ));
2648 $this->assertEquals('B Bobby, Bobby :: Toronto', $result['values'][0]['data']);
2649 $this->assertEquals('C Bobby, Bobby :: Whanganui', $result['values'][1]['data']);
2650 }
2651
08f4ab8d 2652 /**
2653 * Set up some sample data for testing quicksearch.
2654 */
2655 public function getQuickSearchSampleData() {
2656 $contacts = array(
e9e27a80 2657 array('first_name' => 'Bob', 'last_name' => 'Bob', 'external_identifier' => 'abc', 'email' => 'bob@bob.com'),
2baa1e00 2658 array('first_name' => 'Bobby', 'last_name' => 'A Bobby', 'external_identifier' => 'abcd'),
36575b09 2659 array(
2660 'first_name' => 'Bobby',
2661 'last_name' => 'B Bobby',
2662 'external_identifier' => 'bcd',
2663 'api.address.create' => array(
2664 'street_address' => 'Sesame Street',
2665 'city' => 'Toronto',
2666 'location_type_id' => 1,
2667 ),
2668 ),
2669 array(
2670 'first_name' => 'Bobby',
2671 'last_name' => 'C Bobby',
2672 'external_identifier' => 'bcde',
2673 'api.address.create' => array(
2674 'street_address' => 'Te huarahi',
2675 'city' => 'Whanganui',
2676 'location_type_id' => 1,
2677 ),
2678 ),
2baa1e00 2679 array('first_name' => 'Bobby', 'last_name' => 'D Bobby', 'external_identifier' => 'efg'),
e9e27a80 2680 array('first_name' => 'Bobby', 'last_name' => 'E Bobby', 'external_identifier' => 'hij', 'email' => 'bob@bobby.com'),
2baa1e00 2681 array('first_name' => 'Bobby', 'last_name' => 'F Bobby', 'external_identifier' => 'klm'),
2682 array('first_name' => 'Bobby', 'last_name' => 'G Bobby', 'external_identifier' => 'nop'),
e9e27a80 2683 array('first_name' => 'Bobby', 'last_name' => 'H Bobby', 'external_identifier' => 'qrs', 'email' => 'bob@h.com'),
2baa1e00 2684 array('first_name' => 'Bobby', 'last_name' => 'I Bobby'),
2685 array('first_name' => 'Bobby', 'last_name' => 'J Bobby'),
2686 array('first_name' => 'Bob', 'last_name' => 'K Bobby', 'external_identifier' => 'bcdef'),
08f4ab8d 2687 );
2688 foreach ($contacts as $type => $contact) {
2689 $contact['contact_type'] = 'Individual';
2690 $this->callAPISuccess('Contact', 'create', $contact);
2691 }
2692 }
2693
b2130237 2694 /**
381fa321 2695 * Test get ref api - gets a list of references to an entity.
b2130237 2696 */
00be9182 2697 public function testGetReferenceCounts() {
9c8096cb
TO
2698 $result = $this->callAPISuccess('Contact', 'create', array(
2699 'first_name' => 'Testily',
2700 'last_name' => 'McHaste',
2701 'contact_type' => 'Individual',
2702 'api.Address.replace' => array(
2703 'values' => array(),
2704 ),
2705 'api.Email.replace' => array(
2706 'values' => array(
2707 array(
2708 'email' => 'spam@dev.null',
2709 'is_primary' => 0,
2710 'location_type_id' => 1,
21dfd5f5 2711 ),
9c8096cb
TO
2712 ),
2713 ),
2714 'api.Phone.replace' => array(
2715 'values' => array(
2716 array(
2717 'phone' => '234-567-0001',
2718 'is_primary' => 1,
2719 'location_type_id' => 1,
2720 ),
2721 array(
2722 'phone' => '234-567-0002',
2723 'is_primary' => 0,
2724 'location_type_id' => 1,
2725 ),
2726 ),
2727 ),
2728 ));
2729
2730 //$dao = new CRM_Contact_BAO_Contact();
2731 //$dao->id = $result['id'];
2732 //$this->assertTrue((bool) $dao->find(TRUE));
2733 //
2734 //$refCounts = $dao->getReferenceCounts();
2735 //$this->assertTrue(is_array($refCounts));
2736 //$refCountsIdx = CRM_Utils_Array::index(array('name'), $refCounts);
2737
2738 $refCounts = $this->callAPISuccess('Contact', 'getrefcount', array(
21dfd5f5 2739 'id' => $result['id'],
9c8096cb
TO
2740 ));
2741 $refCountsIdx = CRM_Utils_Array::index(array('name'), $refCounts['values']);
2742
2743 $this->assertEquals(1, $refCountsIdx['sql:civicrm_email:contact_id']['count']);
2744 $this->assertEquals('civicrm_email', $refCountsIdx['sql:civicrm_email:contact_id']['table']);
2745 $this->assertEquals(2, $refCountsIdx['sql:civicrm_phone:contact_id']['count']);
2746 $this->assertEquals('civicrm_phone', $refCountsIdx['sql:civicrm_phone:contact_id']['table']);
2747 $this->assertTrue(!isset($refCountsIdx['sql:civicrm_address:contact_id']));
2748 }
2749
701a69da 2750 /**
2751 * Test the use of sql operators.
2752 */
00be9182 2753 public function testSQLOperatorsOnContactAPI() {
a75c13cc
EM
2754 $this->individualCreate();
2755 $this->organizationCreate();
2756 $this->householdCreate();
2757 $contacts = $this->callAPISuccess('contact', 'get', array('legal_name' => array('IS NOT NULL' => TRUE)));
2758 $this->assertEquals($contacts['count'], CRM_Core_DAO::singleValueQuery('select count(*) FROM civicrm_contact WHERE legal_name IS NOT NULL'));
2759 $contacts = $this->callAPISuccess('contact', 'get', array('legal_name' => array('IS NULL' => TRUE)));
2760 $this->assertEquals($contacts['count'], CRM_Core_DAO::singleValueQuery('select count(*) FROM civicrm_contact WHERE legal_name IS NULL'));
2761 }
9bee5ea2 2762
9bee5ea2 2763 /**
fe482240 2764 * CRM-14743 - test api respects search operators.
9bee5ea2 2765 */
00be9182 2766 public function testGetModifiedDateByOperators() {
9bee5ea2
EM
2767 $preExistingContactCount = CRM_Core_DAO::singleValueQuery('select count(*) FROM civicrm_contact');
2768 $contact1 = $this->individualCreate();
2769 $sql = "UPDATE civicrm_contact SET created_date = '2012-01-01', modified_date = '2013-01-01' WHERE id = " . $contact1;
2770 CRM_Core_DAO::executeQuery($sql);
2771 $contact2 = $this->individualCreate();
2772 $sql = "UPDATE civicrm_contact SET created_date = '2012-02-01', modified_date = '2013-02-01' WHERE id = " . $contact2;
2773 CRM_Core_DAO::executeQuery($sql);
2774 $contact3 = $this->householdCreate();
2775 $sql = "UPDATE civicrm_contact SET created_date = '2012-03-01', modified_date = '2013-03-01' WHERE id = " . $contact3;
2776 CRM_Core_DAO::executeQuery($sql);
2777 $contacts = $this->callAPISuccess('contact', 'get', array('modified_date' => array('<' => '2014-01-01')));
2778 $this->assertEquals($contacts['count'], 3);
2779 $contacts = $this->callAPISuccess('contact', 'get', array('modified_date' => array('>' => '2014-01-01')));
2780 $this->assertEquals($contacts['count'], $preExistingContactCount);
2781 }
2134e310 2782
2134e310 2783 /**
fe482240 2784 * CRM-14743 - test api respects search operators.
2134e310 2785 */
00be9182 2786 public function testGetCreatedDateByOperators() {
2134e310
EM
2787 $preExistingContactCount = CRM_Core_DAO::singleValueQuery('select count(*) FROM civicrm_contact');
2788 $contact1 = $this->individualCreate();
2789 $sql = "UPDATE civicrm_contact SET created_date = '2012-01-01' WHERE id = " . $contact1;
2790 CRM_Core_DAO::executeQuery($sql);
2791 $contact2 = $this->individualCreate();
2792 $sql = "UPDATE civicrm_contact SET created_date = '2012-02-01' WHERE id = " . $contact2;
2793 CRM_Core_DAO::executeQuery($sql);
2794 $contact3 = $this->householdCreate();
2795 $sql = "UPDATE civicrm_contact SET created_date = '2012-03-01' WHERE id = " . $contact3;
2796 CRM_Core_DAO::executeQuery($sql);
2797 $contacts = $this->callAPISuccess('contact', 'get', array('created_date' => array('<' => '2014-01-01')));
2798 $this->assertEquals($contacts['count'], 3);
2799 $contacts = $this->callAPISuccess('contact', 'get', array('created_date' => array('>' => '2014-01-01')));
2800 $this->assertEquals($contacts['count'], $preExistingContactCount);
2801 }
e5fccefb
EM
2802
2803 /**
fe482240 2804 * CRM-14263 check that API is not affected by search profile related bug.
e5fccefb 2805 */
5896d037 2806 public function testReturnCityProfile() {
e5fccefb
EM
2807 $contactID = $this->individualCreate();
2808 CRM_Core_Config::singleton()->defaultSearchProfileID = 1;
5896d037 2809 $this->callAPISuccess('address', 'create', array(
92915c55
TO
2810 'contact_id' => $contactID,
2811 'city' => 'Cool City',
2812 'location_type_id' => 1,
2813 ));
e5fccefb
EM
2814 $result = $this->callAPISuccess('contact', 'get', array('city' => 'Cool City', 'return' => 'contact_type'));
2815 $this->assertEquals(1, $result['count']);
2816 }
eaa112a5 2817
eaa112a5 2818 /**
701a69da 2819 * CRM-15443 - ensure getlist api does not return deleted contacts.
eaa112a5 2820 */
00be9182 2821 public function testGetlistExcludeConditions() {
eaa112a5 2822 $name = md5(time());
45fcf8b7 2823 $contact = $this->individualCreate(array('last_name' => $name));
381fa321 2824 $this->individualCreate(array('last_name' => $name, 'is_deceased' => 1));
2825 $this->individualCreate(array('last_name' => $name, 'is_deleted' => 1));
2826 // We should get all but the deleted contact.
eaa112a5 2827 $result = $this->callAPISuccess('contact', 'getlist', array('input' => $name));
ba4a1892 2828 $this->assertEquals(2, $result['count']);
381fa321 2829 // Force-exclude the deceased contact.
5896d037 2830 $result = $this->callAPISuccess('contact', 'getlist', array(
92915c55
TO
2831 'input' => $name,
2832 'params' => array('is_deceased' => 0),
2833 ));
ba4a1892
TM
2834 $this->assertEquals(1, $result['count']);
2835 $this->assertEquals($contact, $result['values'][0]['id']);
eaa112a5 2836 }
92776611
CW
2837
2838 /**
fe482240 2839 * Test contact getactions.
92776611 2840 */
00be9182 2841 public function testGetActions() {
92776611
CW
2842 $description = "Getting the available actions for an entity.";
2843 $result = $this->callAPIAndDocument($this->_entity, 'getactions', array(), __FUNCTION__, __FILE__, $description);
2844 $expected = array(
2845 'create',
2846 'delete',
2847 'get',
2848 'getactions',
2849 'getcount',
2850 'getfields',
2851 'getlist',
2852 'getoptions',
2853 'getquick',
2854 'getrefcount',
2855 'getsingle',
2856 'getvalue',
2857 'merge',
2858 'proximity',
2859 'replace',
2860 'setvalue',
2861 'update',
2862 );
2863 $deprecated = array(
2864 'update',
2865 'getquick',
2866 );
2867 foreach ($expected as $action) {
2868 $this->assertTrue(in_array($action, $result['values']), "Expected action $action");
2869 }
2870 foreach ($deprecated as $action) {
2871 $this->assertArrayKeyExists($action, $result['deprecated']);
2872 }
2873 }
96025800 2874
ffe87781 2875 /**
2876 * Test the duplicate check function.
2877 */
2878 public function testDuplicateCheck() {
2879 $this->callAPISuccess('Contact', 'create', array(
2880 'first_name' => 'Harry',
2881 'last_name' => 'Potter',
2882 'email' => 'harry@hogwarts.edu',
2883 'contact_type' => 'Individual',
2884 ));
2885 $result = $this->callAPISuccess('Contact', 'duplicatecheck', array(
2886 'match' => array(
2887 'first_name' => 'Harry',
2888 'last_name' => 'Potter',
2889 'email' => 'harry@hogwarts.edu',
2890 'contact_type' => 'Individual',
2891 ),
2892 ));
2893
2894 $this->assertEquals(1, $result['count']);
2895 $result = $this->callAPISuccess('Contact', 'duplicatecheck', array(
2896 'match' => array(
2897 'first_name' => 'Harry',
2898 'last_name' => 'Potter',
2899 'email' => 'no5@privet.drive',
2900 'contact_type' => 'Individual',
2901 ),
2902 ));
2903 $this->assertEquals(0, $result['count']);
2904 }
2905
46b3417a
CW
2906 public function testGetByContactType() {
2907 $individual = $this->callAPISuccess('Contact', 'create', array(
2908 'email' => 'individual@test.com',
2909 'contact_type' => 'Individual',
2910 ));
2911 $household = $this->callAPISuccess('Contact', 'create', array(
2912 'household_name' => 'household@test.com',
2913 'contact_type' => 'Household',
2914 ));
2915 $organization = $this->callAPISuccess('Contact', 'create', array(
2916 'organization_name' => 'organization@test.com',
2917 'contact_type' => 'Organization',
2918 ));
2919 // Test with id - getsingle will throw an exception if not found
2920 $this->callAPISuccess('Contact', 'getsingle', array(
2921 'id' => $individual['id'],
2922 'contact_type' => 'Individual',
2923 ));
2924 $this->callAPISuccess('Contact', 'getsingle', array(
2925 'id' => $individual['id'],
2926 'contact_type' => array('IN' => array('Individual')),
2927 'return' => 'id',
2928 ));
2929 $this->callAPISuccess('Contact', 'getsingle', array(
2930 'id' => $organization['id'],
2931 'contact_type' => array('IN' => array('Individual', 'Organization')),
2932 ));
2933 // Test as array
2934 $result = $this->callAPISuccess('Contact', 'get', array(
2935 'contact_type' => array('IN' => array('Individual', 'Organization')),
2936 'options' => array('limit' => 0),
2937 'return' => 'id',
2938 ));
2939 $this->assertContains($organization['id'], array_keys($result['values']));
2940 $this->assertContains($individual['id'], array_keys($result['values']));
2941 $this->assertNotContains($household['id'], array_keys($result['values']));
2942 // Test as string
2943 $result = $this->callAPISuccess('Contact', 'get', array(
2944 'contact_type' => 'Household',
2945 'options' => array('limit' => 0),
2946 'return' => 'id',
2947 ));
2948 $this->assertNotContains($organization['id'], array_keys($result['values']));
2949 $this->assertNotContains($individual['id'], array_keys($result['values']));
2950 $this->assertContains($household['id'], array_keys($result['values']));
2951 }
2952
12d73bba 2953 /**
2954 * Test merging 2 contacts.
5ea06a7b 2955 *
2956 * Someone kindly bequethed us the legacy of mixed up use of main_id & other_id
2957 * in the params for contact.merge api.
2958 *
2959 * This test protects that legacy.
12d73bba 2960 */
5ea06a7b 2961 public function testMergeBizzareOldParams() {
2962 $this->createLoggedInUser();
12d73bba 2963 $otherContact = $this->callAPISuccess('contact', 'create', $this->_params);
2964 $mainContact = $this->callAPISuccess('contact', 'create', $this->_params);
5ea06a7b 2965 $this->callAPISuccess('contact', 'merge', array(
2966 'main_id' => $mainContact['id'],
2967 'other_id' => $otherContact['id'],
2968 ));
12d73bba 2969 $contacts = $this->callAPISuccess('contact', 'get', $this->_params);
2970 $this->assertEquals($otherContact['id'], $contacts['id']);
5ea06a7b 2971 }
2972
2973 /**
2974 * Test merging 2 contacts.
2975 */
2976 public function testMerge() {
2977 $this->createLoggedInUser();
2978 $otherContact = $this->callAPISuccess('contact', 'create', $this->_params);
2979 $retainedContact = $this->callAPISuccess('contact', 'create', $this->_params);
2980 $this->callAPISuccess('contact', 'merge', array(
2981 'to_keep_id' => $retainedContact['id'],
2982 'to_remove_id' => $otherContact['id'],
2983 'auto_flip' => FALSE,
2984 ));
2985
2986 $contacts = $this->callAPISuccess('contact', 'get', $this->_params);
2987 $this->assertEquals($retainedContact['id'], $contacts['id']);
2988 $activity = $this->callAPISuccess('Activity', 'getsingle', array(
2989 'target_contact_id' => $retainedContact['id'],
2990 'activity_type_id' => 'Contact Merged',
2991 ));
2992 $this->assertEquals(date('Y-m-d'), date('Y-m-d', strtotime($activity['activity_date_time'])));
f00283b5 2993 $activity2 = $this->callAPISuccess('Activity', 'getsingle', array(
2994 'target_contact_id' => $otherContact['id'],
2995 'activity_type_id' => 'Contact Deleted by Merge',
2996 ));
2997 $this->assertEquals($activity['id'], $activity2['parent_id']);
2998 $this->assertEquals('Normal', civicrm_api3('option_value', 'getvalue', array(
2999 'value' => $activity['priority_id'],
3000 'return' => 'label',
3001 'option_group_id' => 'priority',
3002 )));
12d73bba 3003
3004 }
3005
4d834a99 3006 /**
3007 * Test merging 2 contacts with delete to trash off.
3008 *
3009 * We are checking that there is no error due to attempting to add an activity for the
3010 * deleted contact.
3011 *
3012 * CRM-18307
3013 */
3014 public function testMergeNoTrash() {
3015 $this->createLoggedInUser();
3016 $this->callAPISuccess('Setting', 'create', array('contact_undelete' => FALSE));
3017 $otherContact = $this->callAPISuccess('contact', 'create', $this->_params);
3018 $retainedContact = $this->callAPISuccess('contact', 'create', $this->_params);
3019 $this->callAPISuccess('contact', 'merge', array(
3020 'to_keep_id' => $retainedContact['id'],
3021 'to_remove_id' => $otherContact['id'],
3022 'auto_flip' => FALSE,
3023 ));
3024 $this->callAPISuccess('Setting', 'create', array('contact_undelete' => TRUE));
3025 }
3026
00ed3e04
CB
3027 /**
3028 * Ensure format with return=group shows comma-separated group IDs.
3029 *
3030 * CRM-19426
3031 */
3032 public function testContactGetReturnGroup() {
3033 // Set up a contact, asser that they were created.
3034 $contact_params = array(
3035 'contact_type' => 'Individual',
3036 'first_name' => 'Test',
3037 'last_name' => 'Groupmember',
3038 'email' => 'test@example.org',
3039 );
3040 $create_contact = $this->callApiSuccess('Contact', 'create', $contact_params);
3041 $this->assertEquals(0, $create_contact['is_error']);
3042 $this->assertInternalType('int', $create_contact['id']);
3043
3044 $created_contact_id = $create_contact['id'];
3045
3046 // Set up multiple groups, add the contact to the groups.
3047 $test_groups = array('Test group A', 'Test group B');
3048 foreach ($test_groups as $title) {
3049 // Use this contact as group owner, since we know they exist.
3050 $group_params = array(
3051 'title' => $title,
3052 'created_id' => $created_contact_id,
3053 );
3054 $create_group = $this->callApiSuccess('Group', 'create', $group_params);
3055 $this->assertEquals(0, $create_group['is_error']);
3056 $this->assertInternalType('int', $create_group['id']);
3057
3058 $created_group_ids[] = $create_group['id'];
3059
3060 // Add contact to the new group.
3061 $group_contact_params = array(
3062 'contact_id' => $created_contact_id,
3063 'group_id' => $create_group['id'],
3064 );
3065 $create_group_contact = $this->callApiSuccess('GroupContact', 'create', $group_contact_params);
3066 $this->assertEquals(0, $create_group_contact['is_error']);
3067 $this->assertInternalType('int', $create_group_contact['added']);
3068 }
3069
3070 // Use the Contact,get API to retrieve the contact
3071 $contact_get_params = array(
3072 'id' => $created_contact_id,
3073 'return' => 'group',
3074 );
3075 $contact_get = $this->callApiSuccess('Contact', 'get', $contact_get_params);
3076 $this->assertInternalType('array', $contact_get['values'][$created_contact_id]);
3077 $this->assertInternalType('string', $contact_get['values'][$created_contact_id]['groups']);
3078
3079 // Ensure they are shown as being in each created group.
3080 $contact_group_ids = explode(',', $contact_get['values'][$created_contact_id]['groups']);
3081 foreach ($created_group_ids as $created_group_id) {
3082 $this->assertContains($created_group_id, $contact_group_ids);
3083 }
3084 }
3085
6a488035 3086}