CRM 19474 - additional test (#9208)
[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
381fa321 2291 /**
2292 * Test update with check permissions set.
2293 */
00be9182 2294 public function testContactUpdatePermissions() {
5896d037
TO
2295 $params = array(
2296 'contact_type' => 'Individual',
2297 'first_name' => 'Foo',
2298 'last_name' => 'Bear',
21dfd5f5 2299 'check_permissions' => TRUE,
5896d037 2300 );
f6722559 2301 $result = $this->callAPISuccess('contact', 'create', $params);
6a488035 2302 $config = CRM_Core_Config::singleton();
5896d037
TO
2303 $params = array(
2304 'id' => $result['id'],
2305 'contact_type' => 'Individual',
2306 'last_name' => 'Bar',
21dfd5f5 2307 'check_permissions' => TRUE,
5896d037 2308 );
6a488035
TO
2309
2310 $config->userPermissionClass->permissions = array('access CiviCRM');
d0e1eff2 2311 $result = $this->callAPIFailure('contact', 'update', $params);
0a61b6e2 2312 $this->assertEquals('Permission denied to modify contact record', $result['error_message']);
6a488035 2313
5896d037
TO
2314 $config->userPermissionClass->permissions = array(
2315 'access CiviCRM',
2316 'add contacts',
2317 'view all contacts',
2318 'edit all contacts',
21dfd5f5 2319 'import contacts',
5896d037 2320 );
701a69da 2321 $this->callAPISuccess('contact', 'update', $params);
6a488035
TO
2322 }
2323
381fa321 2324 /**
2325 * Set up helper to create a contact.
2326 */
00be9182 2327 public function createContactFromXML() {
381fa321 2328 // Insert a row in civicrm_contact creating contact 17.
6a488035
TO
2329 $op = new PHPUnit_Extensions_Database_Operation_Insert();
2330 $op->execute($this->_dbconn,
bbfd46a5 2331 $this->createXMLDataSet(
6a488035
TO
2332 dirname(__FILE__) . '/dataset/contact_17.xml'
2333 )
2334 );
2335 }
2336
381fa321 2337 /**
2338 * Test contact proximity api.
2339 */
00be9182 2340 public function testContactProximity() {
6a488035
TO
2341 // first create a contact with a SF location with a specific
2342 // geocode
2343 $contactID = $this->organizationCreate();
2344
2345 // now create the address
2346 $params = array(
2347 'street_address' => '123 Main Street',
2348 'city' => 'San Francisco',
2349 'is_primary' => 1,
2350 'country_id' => 1228,
2351 'state_province_id' => 1004,
2352 'geo_code_1' => '37.79',
2353 'geo_code_2' => '-122.40',
2354 'location_type_id' => 1,
2355 'contact_id' => $contactID,
6a488035
TO
2356 );
2357
f6722559 2358 $result = $this->callAPISuccess('address', 'create', $params);
ba4a1892 2359 $this->assertEquals(1, $result['count']);
6a488035
TO
2360
2361 // now do a proximity search with a close enough geocode and hope to match
2362 // that specific contact only!
2363 $proxParams = array(
2364 'latitude' => 37.7,
2365 'longitude' => -122.3,
2366 'unit' => 'mile',
2367 'distance' => 10,
6a488035 2368 );
f6722559 2369 $result = $this->callAPISuccess('contact', 'proximity', $proxParams);
ba4a1892 2370 $this->assertEquals(1, $result['count']);
6a488035 2371 }
60ec9f43
E
2372
2373 /**
381fa321 2374 * Test that Ajax API permission is sufficient to access getquick api.
2375 *
1d6020f1 2376 * (note that getquick api is required for autocomplete & has ACL permissions applied)
60ec9f43 2377 */
fe482240 2378 public function testGetquickPermissionCRM13744() {
60ec9f43 2379 CRM_Core_Config::singleton()->userPermissionClass->permissions = array('access CiviEvent');
4b58ed3b 2380 $this->callAPIFailure('contact', 'getquick', array('name' => 'b', 'check_permissions' => TRUE));
60ec9f43 2381 CRM_Core_Config::singleton()->userPermissionClass->permissions = array('access CiviCRM');
4b58ed3b 2382 $this->callAPISuccess('contact', 'getquick', array('name' => 'b', 'check_permissions' => TRUE));
60ec9f43 2383 CRM_Core_Config::singleton()->userPermissionClass->permissions = array('access AJAX API');
4b58ed3b 2384 $this->callAPISuccess('contact', 'getquick', array('name' => 'b', 'check_permissions' => TRUE));
60ec9f43 2385 }
9c8096cb 2386
08f4ab8d 2387 /**
2388 * Test that getquick returns contacts with an exact first name match first.
2baa1e00 2389 *
2390 * The search string 'b' & 'bob' both return ordered by sort_name if includeOrderByClause
2391 * is true (default) but if it is false then matches are returned in ID order.
08f4ab8d 2392 */
2393 public function testGetQuickExactFirst() {
2394 $this->getQuickSearchSampleData();
2395 $result = $this->callAPISuccess('contact', 'getquick', array('name' => 'b'));
2396 $this->assertEquals('A Bobby, Bobby', $result['values'][0]['sort_name']);
2baa1e00 2397 $this->assertEquals('B Bobby, Bobby', $result['values'][1]['sort_name']);
08f4ab8d 2398 $result = $this->callAPISuccess('contact', 'getquick', array('name' => 'bob'));
2399 $this->assertEquals('A Bobby, Bobby', $result['values'][0]['sort_name']);
2baa1e00 2400 $this->assertEquals('B Bobby, Bobby', $result['values'][1]['sort_name']);
2401 $this->callAPISuccess('Setting', 'create', array('includeOrderByClause' => FALSE));
2402 $result = $this->callAPISuccess('contact', 'getquick', array('name' => 'bob'));
2403 $this->assertEquals('Bob, Bob', $result['values'][0]['sort_name']);
2404 $this->assertEquals('A Bobby, Bobby', $result['values'][1]['sort_name']);
2405 }
2406
e9e27a80 2407 /**
2408 * Test that getquick returns contacts with an exact first name match first.
2409 */
2410 public function testGetQuickEmail() {
2411 $this->getQuickSearchSampleData();
1ca22999 2412 $loggedInContactID = $this->createLoggedInUser();
e9e27a80 2413 $result = $this->callAPISuccess('contact', 'getquick', array(
2414 'name' => 'c',
2415 ));
2416 $expectedData = array(
2417 'Bob, Bob :: bob@bob.com',
2418 'C Bobby, Bobby',
2419 'E Bobby, Bobby :: bob@bobby.com',
2420 'H Bobby, Bobby :: bob@h.com',
1ca22999 2421 'Second Domain',
2422 $this->callAPISuccessGetValue('Contact', array('id' => $loggedInContactID, 'return' => 'last_name')) . ', Logged In :: anthony_anderson@civicrm.org',
e9e27a80 2423 );
1ca22999 2424 $this->assertEquals(6, $result['count']);
e9e27a80 2425 foreach ($expectedData as $index => $value) {
2426 $this->assertEquals($value, $result['values'][$index]['data']);
2427 }
7f6f3df1 2428 $result = $this->callAPISuccess('contact', 'getquick', array(
2429 'name' => 'h.',
2430 ));
2431 $expectedData = array(
2432 'H Bobby, Bobby :: bob@h.com',
2433 );
2434 foreach ($expectedData as $index => $value) {
2435 $this->assertEquals($value, $result['values'][$index]['data']);
2436 }
2437 $this->callAPISuccess('Setting', 'create', array('includeWildCardInName' => FALSE));
2438 $result = $this->callAPISuccess('contact', 'getquick', array(
2439 'name' => 'h.',
2440 ));
2441 $this->callAPISuccess('Setting', 'create', array('includeWildCardInName' => TRUE));
2442 $this->assertEquals(0, $result['count']);
e9e27a80 2443 }
2444
c37a2d66 2445 /**
2446 * Test that getquick returns contacts with an exact first name match first.
2447 */
2448 public function testGetQuickEmailACL() {
2449 $this->getQuickSearchSampleData();
1ca22999 2450 $loggedInContactID = $this->createLoggedInUser();
c37a2d66 2451 CRM_Core_Config::singleton()->userPermissionClass->permissions = array();
2452 $result = $this->callAPISuccess('contact', 'getquick', array(
2453 'name' => 'c',
2454 ));
2455 $this->assertEquals(0, $result['count']);
2456
2457 $this->hookClass->setHook('civicrm_aclWhereClause', array($this, 'aclWhereNoBobH'));
1ca22999 2458 CRM_Contact_BAO_Contact_Permission::cache($loggedInContactID, CRM_Core_Permission::VIEW, TRUE);
c37a2d66 2459 $result = $this->callAPISuccess('contact', 'getquick', array(
2460 'name' => 'c',
2461 ));
1ca22999 2462
2463 // Without the acl it would be 6 like the previous email getquick test.
2464 $this->assertEquals(5, $result['count']);
c37a2d66 2465 $expectedData = array(
2466 'Bob, Bob :: bob@bob.com',
2467 'C Bobby, Bobby',
2468 'E Bobby, Bobby :: bob@bobby.com',
1ca22999 2469 'Second Domain',
2470 $this->callAPISuccessGetValue('Contact', array('id' => $loggedInContactID, 'return' => 'last_name')) . ', Logged In :: anthony_anderson@civicrm.org',
c37a2d66 2471 );
2472 foreach ($expectedData as $index => $value) {
2473 $this->assertEquals($value, $result['values'][$index]['data']);
2474 }
2475 }
2476
2baa1e00 2477 /**
2478 * Test that getquick returns contacts with an exact first name match first.
2479 */
2480 public function testGetQuickExternalID() {
2481 $this->getQuickSearchSampleData();
2482 $result = $this->callAPISuccess('contact', 'getquick', array(
2483 'name' => 'b',
2484 'field_name' => 'external_identifier',
2485 'table_name' => 'cc',
2486 ));
2487 $this->assertEquals(0, $result['count']);
2488 $result = $this->callAPISuccess('contact', 'getquick', array(
2489 'name' => 'abc',
2490 'field_name' => 'external_identifier',
2491 'table_name' => 'cc',
2492 ));
2493 $this->assertEquals(1, $result['count']);
2494 $this->assertEquals('Bob, Bob', $result['values'][0]['sort_name']);
2495 }
2496
2497 /**
2498 * Test that getquick returns contacts with an exact first name match first.
2499 */
2500 public function testGetQuickID() {
1ca22999 2501 $max = CRM_Core_DAO::singleValueQuery("SELECT max(id) FROM civicrm_contact");
2baa1e00 2502 $this->getQuickSearchSampleData();
2503 $result = $this->callAPISuccess('contact', 'getquick', array(
1ca22999 2504 'name' => $max + 2,
2baa1e00 2505 'field_name' => 'id',
2506 'table_name' => 'cc',
2507 ));
2508 $this->assertEquals(1, $result['count']);
2509 $this->assertEquals('A Bobby, Bobby', $result['values'][0]['sort_name']);
2510 $result = $this->callAPISuccess('contact', 'getquick', array(
1ca22999 2511 'name' => $max + 2,
2baa1e00 2512 'field_name' => 'contact_id',
2513 'table_name' => 'cc',
2514 ));
2515 $this->assertEquals(1, $result['count']);
2516 $this->assertEquals('A Bobby, Bobby', $result['values'][0]['sort_name']);
2517 }
2518
2519 /**
2520 * Test that getquick returns contacts with an exact first name match first.
ef3fd279 2521 *
2522 * Depending on the setting the sort name sort might click in next or not - test!
2baa1e00 2523 */
2524 public function testGetQuickFirstName() {
2525 $this->getQuickSearchSampleData();
ef3fd279 2526 $this->callAPISuccess('Setting', 'create', array('includeOrderByClause' => TRUE));
2baa1e00 2527 $result = $this->callAPISuccess('contact', 'getquick', array(
2528 'name' => 'Bob',
2529 'field_name' => 'first_name',
2530 'table_name' => 'cc',
2531 ));
e9e27a80 2532 $expected = array(
2533 'Bob, Bob',
2534 'K Bobby, Bob',
2535 'A Bobby, Bobby',
2536 );
2537
2538 foreach ($expected as $index => $value) {
2539 $this->assertEquals($value, $result['values'][$index]['sort_name']);
2540 }
08f4ab8d 2541 $this->callAPISuccess('Setting', 'create', array('includeOrderByClause' => FALSE));
2542 $result = $this->callAPISuccess('contact', 'getquick', array('name' => 'bob'));
2543 $this->assertEquals('Bob, Bob', $result['values'][0]['sort_name']);
ef3fd279 2544 $this->assertEquals('A Bobby, Bobby', $result['values'][1]['sort_name']);
08f4ab8d 2545 }
2546
1b9c2802 2547 /**
2548 * Test that getquick applies ACLs.
2549 */
2550 public function testGetQuickFirstNameACLs() {
2551 $this->getQuickSearchSampleData();
2552 $userID = $this->createLoggedInUser();
c37a2d66 2553 $this->callAPISuccess('Setting', 'create', array('includeOrderByClause' => TRUE));
1b9c2802 2554 CRM_Core_Config::singleton()->userPermissionClass->permissions = array();
2555 $result = $this->callAPISuccess('contact', 'getquick', array(
2556 'name' => 'Bob',
2557 'field_name' => 'first_name',
2558 'table_name' => 'cc',
2559 ));
2560 $this->assertEquals(0, $result['count']);
2561
2562 $this->hookClass->setHook('civicrm_aclWhereClause', array($this, 'aclWhereNoBobH'));
2563 CRM_Contact_BAO_Contact_Permission::cache($userID, CRM_Core_Permission::VIEW, TRUE);
2564 $result = $this->callAPISuccess('contact', 'getquick', array(
2565 'name' => 'Bob',
2566 'field_name' => 'first_name',
2567 'table_name' => 'cc',
2568 ));
2569 $this->assertEquals('K Bobby, Bob', $result['values'][1]['sort_name']);
2570 // Without the ACL 9 would be bob@h.com.
2571 $this->assertEquals('I Bobby, Bobby', $result['values'][9]['sort_name']);
1b9c2802 2572 }
2573
2574 /**
2575 * Full results returned.
2576 * @implements CRM_Utils_Hook::aclWhereClause
2577 *
2578 * @param string $type
2579 * @param array $tables
2580 * @param array $whereTables
2581 * @param int $contactID
2582 * @param string $where
2583 */
2584 public function aclWhereNoBobH($type, &$tables, &$whereTables, &$contactID, &$where) {
c37a2d66 2585 $where = " (email <> 'bob@h.com' OR email IS NULL) ";
1b9c2802 2586 $whereTables['civicrm_email'] = "LEFT JOIN civicrm_email e ON contact_a.id = e.contact_id";
2587 }
2588
e9e27a80 2589 /**
2590 * Test that getquick returns contacts with an exact last name match first.
2591 */
2592 public function testGetQuickLastName() {
2593 $this->getQuickSearchSampleData();
2594 $this->callAPISuccess('Setting', 'create', array('includeOrderByClause' => TRUE));
2595 $result = $this->callAPISuccess('contact', 'getquick', array(
2596 'name' => 'Bob',
2597 'field_name' => 'last_name',
2598 'table_name' => 'cc',
2599 ));
2600 $expected = array(
2601 'Bob, Bob',
2602 'A Bobby, Bobby',
36575b09 2603 'B Bobby, Bobby',
e9e27a80 2604 );
2605
2606 foreach ($expected as $index => $value) {
2607 $this->assertEquals($value, $result['values'][$index]['sort_name']);
2608 }
2609 $this->callAPISuccess('Setting', 'create', array('includeOrderByClause' => FALSE));
2610 $result = $this->callAPISuccess('contact', 'getquick', array('name' => 'bob'));
2611 $this->assertEquals('Bob, Bob :: bob@bob.com', $result['values'][0]['data']);
2612 }
2613
2614 /**
2615 * Test that getquick returns contacts by city.
2616 */
2617 public function testGetQuickCity() {
2618 $this->getQuickSearchSampleData();
2619 $result = $this->callAPISuccess('contact', 'getquick', array(
2620 'name' => 'o',
2621 'field_name' => 'city',
2622 'table_name' => 'sts',
2623 ));
2624 $this->assertEquals('B Bobby, Bobby :: Toronto', $result['values'][0]['data']);
2625 $result = $this->callAPISuccess('contact', 'getquick', array(
2626 'name' => 'n',
2627 'field_name' => 'city',
2628 'table_name' => 'sts',
2629 ));
2630 $this->assertEquals('B Bobby, Bobby :: Toronto', $result['values'][0]['data']);
2631 $this->assertEquals('C Bobby, Bobby :: Whanganui', $result['values'][1]['data']);
2632 }
2633
08f4ab8d 2634 /**
2635 * Set up some sample data for testing quicksearch.
2636 */
2637 public function getQuickSearchSampleData() {
2638 $contacts = array(
e9e27a80 2639 array('first_name' => 'Bob', 'last_name' => 'Bob', 'external_identifier' => 'abc', 'email' => 'bob@bob.com'),
2baa1e00 2640 array('first_name' => 'Bobby', 'last_name' => 'A Bobby', 'external_identifier' => 'abcd'),
36575b09 2641 array(
2642 'first_name' => 'Bobby',
2643 'last_name' => 'B Bobby',
2644 'external_identifier' => 'bcd',
2645 'api.address.create' => array(
2646 'street_address' => 'Sesame Street',
2647 'city' => 'Toronto',
2648 'location_type_id' => 1,
2649 ),
2650 ),
2651 array(
2652 'first_name' => 'Bobby',
2653 'last_name' => 'C Bobby',
2654 'external_identifier' => 'bcde',
2655 'api.address.create' => array(
2656 'street_address' => 'Te huarahi',
2657 'city' => 'Whanganui',
2658 'location_type_id' => 1,
2659 ),
2660 ),
2baa1e00 2661 array('first_name' => 'Bobby', 'last_name' => 'D Bobby', 'external_identifier' => 'efg'),
e9e27a80 2662 array('first_name' => 'Bobby', 'last_name' => 'E Bobby', 'external_identifier' => 'hij', 'email' => 'bob@bobby.com'),
2baa1e00 2663 array('first_name' => 'Bobby', 'last_name' => 'F Bobby', 'external_identifier' => 'klm'),
2664 array('first_name' => 'Bobby', 'last_name' => 'G Bobby', 'external_identifier' => 'nop'),
e9e27a80 2665 array('first_name' => 'Bobby', 'last_name' => 'H Bobby', 'external_identifier' => 'qrs', 'email' => 'bob@h.com'),
2baa1e00 2666 array('first_name' => 'Bobby', 'last_name' => 'I Bobby'),
2667 array('first_name' => 'Bobby', 'last_name' => 'J Bobby'),
2668 array('first_name' => 'Bob', 'last_name' => 'K Bobby', 'external_identifier' => 'bcdef'),
08f4ab8d 2669 );
2670 foreach ($contacts as $type => $contact) {
2671 $contact['contact_type'] = 'Individual';
2672 $this->callAPISuccess('Contact', 'create', $contact);
2673 }
2674 }
2675
b2130237 2676 /**
381fa321 2677 * Test get ref api - gets a list of references to an entity.
b2130237 2678 */
00be9182 2679 public function testGetReferenceCounts() {
9c8096cb
TO
2680 $result = $this->callAPISuccess('Contact', 'create', array(
2681 'first_name' => 'Testily',
2682 'last_name' => 'McHaste',
2683 'contact_type' => 'Individual',
2684 'api.Address.replace' => array(
2685 'values' => array(),
2686 ),
2687 'api.Email.replace' => array(
2688 'values' => array(
2689 array(
2690 'email' => 'spam@dev.null',
2691 'is_primary' => 0,
2692 'location_type_id' => 1,
21dfd5f5 2693 ),
9c8096cb
TO
2694 ),
2695 ),
2696 'api.Phone.replace' => array(
2697 'values' => array(
2698 array(
2699 'phone' => '234-567-0001',
2700 'is_primary' => 1,
2701 'location_type_id' => 1,
2702 ),
2703 array(
2704 'phone' => '234-567-0002',
2705 'is_primary' => 0,
2706 'location_type_id' => 1,
2707 ),
2708 ),
2709 ),
2710 ));
2711
2712 //$dao = new CRM_Contact_BAO_Contact();
2713 //$dao->id = $result['id'];
2714 //$this->assertTrue((bool) $dao->find(TRUE));
2715 //
2716 //$refCounts = $dao->getReferenceCounts();
2717 //$this->assertTrue(is_array($refCounts));
2718 //$refCountsIdx = CRM_Utils_Array::index(array('name'), $refCounts);
2719
2720 $refCounts = $this->callAPISuccess('Contact', 'getrefcount', array(
21dfd5f5 2721 'id' => $result['id'],
9c8096cb
TO
2722 ));
2723 $refCountsIdx = CRM_Utils_Array::index(array('name'), $refCounts['values']);
2724
2725 $this->assertEquals(1, $refCountsIdx['sql:civicrm_email:contact_id']['count']);
2726 $this->assertEquals('civicrm_email', $refCountsIdx['sql:civicrm_email:contact_id']['table']);
2727 $this->assertEquals(2, $refCountsIdx['sql:civicrm_phone:contact_id']['count']);
2728 $this->assertEquals('civicrm_phone', $refCountsIdx['sql:civicrm_phone:contact_id']['table']);
2729 $this->assertTrue(!isset($refCountsIdx['sql:civicrm_address:contact_id']));
2730 }
2731
701a69da 2732 /**
2733 * Test the use of sql operators.
2734 */
00be9182 2735 public function testSQLOperatorsOnContactAPI() {
a75c13cc
EM
2736 $this->individualCreate();
2737 $this->organizationCreate();
2738 $this->householdCreate();
2739 $contacts = $this->callAPISuccess('contact', 'get', array('legal_name' => array('IS NOT NULL' => TRUE)));
2740 $this->assertEquals($contacts['count'], CRM_Core_DAO::singleValueQuery('select count(*) FROM civicrm_contact WHERE legal_name IS NOT NULL'));
2741 $contacts = $this->callAPISuccess('contact', 'get', array('legal_name' => array('IS NULL' => TRUE)));
2742 $this->assertEquals($contacts['count'], CRM_Core_DAO::singleValueQuery('select count(*) FROM civicrm_contact WHERE legal_name IS NULL'));
2743 }
9bee5ea2 2744
9bee5ea2 2745 /**
fe482240 2746 * CRM-14743 - test api respects search operators.
9bee5ea2 2747 */
00be9182 2748 public function testGetModifiedDateByOperators() {
9bee5ea2
EM
2749 $preExistingContactCount = CRM_Core_DAO::singleValueQuery('select count(*) FROM civicrm_contact');
2750 $contact1 = $this->individualCreate();
2751 $sql = "UPDATE civicrm_contact SET created_date = '2012-01-01', modified_date = '2013-01-01' WHERE id = " . $contact1;
2752 CRM_Core_DAO::executeQuery($sql);
2753 $contact2 = $this->individualCreate();
2754 $sql = "UPDATE civicrm_contact SET created_date = '2012-02-01', modified_date = '2013-02-01' WHERE id = " . $contact2;
2755 CRM_Core_DAO::executeQuery($sql);
2756 $contact3 = $this->householdCreate();
2757 $sql = "UPDATE civicrm_contact SET created_date = '2012-03-01', modified_date = '2013-03-01' WHERE id = " . $contact3;
2758 CRM_Core_DAO::executeQuery($sql);
2759 $contacts = $this->callAPISuccess('contact', 'get', array('modified_date' => array('<' => '2014-01-01')));
2760 $this->assertEquals($contacts['count'], 3);
2761 $contacts = $this->callAPISuccess('contact', 'get', array('modified_date' => array('>' => '2014-01-01')));
2762 $this->assertEquals($contacts['count'], $preExistingContactCount);
2763 }
2134e310 2764
2134e310 2765 /**
fe482240 2766 * CRM-14743 - test api respects search operators.
2134e310 2767 */
00be9182 2768 public function testGetCreatedDateByOperators() {
2134e310
EM
2769 $preExistingContactCount = CRM_Core_DAO::singleValueQuery('select count(*) FROM civicrm_contact');
2770 $contact1 = $this->individualCreate();
2771 $sql = "UPDATE civicrm_contact SET created_date = '2012-01-01' WHERE id = " . $contact1;
2772 CRM_Core_DAO::executeQuery($sql);
2773 $contact2 = $this->individualCreate();
2774 $sql = "UPDATE civicrm_contact SET created_date = '2012-02-01' WHERE id = " . $contact2;
2775 CRM_Core_DAO::executeQuery($sql);
2776 $contact3 = $this->householdCreate();
2777 $sql = "UPDATE civicrm_contact SET created_date = '2012-03-01' WHERE id = " . $contact3;
2778 CRM_Core_DAO::executeQuery($sql);
2779 $contacts = $this->callAPISuccess('contact', 'get', array('created_date' => array('<' => '2014-01-01')));
2780 $this->assertEquals($contacts['count'], 3);
2781 $contacts = $this->callAPISuccess('contact', 'get', array('created_date' => array('>' => '2014-01-01')));
2782 $this->assertEquals($contacts['count'], $preExistingContactCount);
2783 }
e5fccefb
EM
2784
2785 /**
fe482240 2786 * CRM-14263 check that API is not affected by search profile related bug.
e5fccefb 2787 */
5896d037 2788 public function testReturnCityProfile() {
e5fccefb
EM
2789 $contactID = $this->individualCreate();
2790 CRM_Core_Config::singleton()->defaultSearchProfileID = 1;
5896d037 2791 $this->callAPISuccess('address', 'create', array(
92915c55
TO
2792 'contact_id' => $contactID,
2793 'city' => 'Cool City',
2794 'location_type_id' => 1,
2795 ));
e5fccefb
EM
2796 $result = $this->callAPISuccess('contact', 'get', array('city' => 'Cool City', 'return' => 'contact_type'));
2797 $this->assertEquals(1, $result['count']);
2798 }
eaa112a5 2799
eaa112a5 2800 /**
701a69da 2801 * CRM-15443 - ensure getlist api does not return deleted contacts.
eaa112a5 2802 */
00be9182 2803 public function testGetlistExcludeConditions() {
eaa112a5 2804 $name = md5(time());
45fcf8b7 2805 $contact = $this->individualCreate(array('last_name' => $name));
381fa321 2806 $this->individualCreate(array('last_name' => $name, 'is_deceased' => 1));
2807 $this->individualCreate(array('last_name' => $name, 'is_deleted' => 1));
2808 // We should get all but the deleted contact.
eaa112a5 2809 $result = $this->callAPISuccess('contact', 'getlist', array('input' => $name));
ba4a1892 2810 $this->assertEquals(2, $result['count']);
381fa321 2811 // Force-exclude the deceased contact.
5896d037 2812 $result = $this->callAPISuccess('contact', 'getlist', array(
92915c55
TO
2813 'input' => $name,
2814 'params' => array('is_deceased' => 0),
2815 ));
ba4a1892
TM
2816 $this->assertEquals(1, $result['count']);
2817 $this->assertEquals($contact, $result['values'][0]['id']);
eaa112a5 2818 }
92776611
CW
2819
2820 /**
fe482240 2821 * Test contact getactions.
92776611 2822 */
00be9182 2823 public function testGetActions() {
92776611
CW
2824 $description = "Getting the available actions for an entity.";
2825 $result = $this->callAPIAndDocument($this->_entity, 'getactions', array(), __FUNCTION__, __FILE__, $description);
2826 $expected = array(
2827 'create',
2828 'delete',
2829 'get',
2830 'getactions',
2831 'getcount',
2832 'getfields',
2833 'getlist',
2834 'getoptions',
2835 'getquick',
2836 'getrefcount',
2837 'getsingle',
2838 'getvalue',
2839 'merge',
2840 'proximity',
2841 'replace',
2842 'setvalue',
2843 'update',
2844 );
2845 $deprecated = array(
2846 'update',
2847 'getquick',
2848 );
2849 foreach ($expected as $action) {
2850 $this->assertTrue(in_array($action, $result['values']), "Expected action $action");
2851 }
2852 foreach ($deprecated as $action) {
2853 $this->assertArrayKeyExists($action, $result['deprecated']);
2854 }
2855 }
96025800 2856
ffe87781 2857 /**
2858 * Test the duplicate check function.
2859 */
2860 public function testDuplicateCheck() {
2861 $this->callAPISuccess('Contact', 'create', array(
2862 'first_name' => 'Harry',
2863 'last_name' => 'Potter',
2864 'email' => 'harry@hogwarts.edu',
2865 'contact_type' => 'Individual',
2866 ));
2867 $result = $this->callAPISuccess('Contact', 'duplicatecheck', array(
2868 'match' => array(
2869 'first_name' => 'Harry',
2870 'last_name' => 'Potter',
2871 'email' => 'harry@hogwarts.edu',
2872 'contact_type' => 'Individual',
2873 ),
2874 ));
2875
2876 $this->assertEquals(1, $result['count']);
2877 $result = $this->callAPISuccess('Contact', 'duplicatecheck', array(
2878 'match' => array(
2879 'first_name' => 'Harry',
2880 'last_name' => 'Potter',
2881 'email' => 'no5@privet.drive',
2882 'contact_type' => 'Individual',
2883 ),
2884 ));
2885 $this->assertEquals(0, $result['count']);
2886 }
2887
46b3417a
CW
2888 public function testGetByContactType() {
2889 $individual = $this->callAPISuccess('Contact', 'create', array(
2890 'email' => 'individual@test.com',
2891 'contact_type' => 'Individual',
2892 ));
2893 $household = $this->callAPISuccess('Contact', 'create', array(
2894 'household_name' => 'household@test.com',
2895 'contact_type' => 'Household',
2896 ));
2897 $organization = $this->callAPISuccess('Contact', 'create', array(
2898 'organization_name' => 'organization@test.com',
2899 'contact_type' => 'Organization',
2900 ));
2901 // Test with id - getsingle will throw an exception if not found
2902 $this->callAPISuccess('Contact', 'getsingle', array(
2903 'id' => $individual['id'],
2904 'contact_type' => 'Individual',
2905 ));
2906 $this->callAPISuccess('Contact', 'getsingle', array(
2907 'id' => $individual['id'],
2908 'contact_type' => array('IN' => array('Individual')),
2909 'return' => 'id',
2910 ));
2911 $this->callAPISuccess('Contact', 'getsingle', array(
2912 'id' => $organization['id'],
2913 'contact_type' => array('IN' => array('Individual', 'Organization')),
2914 ));
2915 // Test as array
2916 $result = $this->callAPISuccess('Contact', 'get', array(
2917 'contact_type' => array('IN' => array('Individual', 'Organization')),
2918 'options' => array('limit' => 0),
2919 'return' => 'id',
2920 ));
2921 $this->assertContains($organization['id'], array_keys($result['values']));
2922 $this->assertContains($individual['id'], array_keys($result['values']));
2923 $this->assertNotContains($household['id'], array_keys($result['values']));
2924 // Test as string
2925 $result = $this->callAPISuccess('Contact', 'get', array(
2926 'contact_type' => 'Household',
2927 'options' => array('limit' => 0),
2928 'return' => 'id',
2929 ));
2930 $this->assertNotContains($organization['id'], array_keys($result['values']));
2931 $this->assertNotContains($individual['id'], array_keys($result['values']));
2932 $this->assertContains($household['id'], array_keys($result['values']));
2933 }
2934
12d73bba 2935 /**
2936 * Test merging 2 contacts.
5ea06a7b 2937 *
2938 * Someone kindly bequethed us the legacy of mixed up use of main_id & other_id
2939 * in the params for contact.merge api.
2940 *
2941 * This test protects that legacy.
12d73bba 2942 */
5ea06a7b 2943 public function testMergeBizzareOldParams() {
2944 $this->createLoggedInUser();
12d73bba 2945 $otherContact = $this->callAPISuccess('contact', 'create', $this->_params);
2946 $mainContact = $this->callAPISuccess('contact', 'create', $this->_params);
5ea06a7b 2947 $this->callAPISuccess('contact', 'merge', array(
2948 'main_id' => $mainContact['id'],
2949 'other_id' => $otherContact['id'],
2950 ));
12d73bba 2951 $contacts = $this->callAPISuccess('contact', 'get', $this->_params);
2952 $this->assertEquals($otherContact['id'], $contacts['id']);
5ea06a7b 2953 }
2954
2955 /**
2956 * Test merging 2 contacts.
2957 */
2958 public function testMerge() {
2959 $this->createLoggedInUser();
2960 $otherContact = $this->callAPISuccess('contact', 'create', $this->_params);
2961 $retainedContact = $this->callAPISuccess('contact', 'create', $this->_params);
2962 $this->callAPISuccess('contact', 'merge', array(
2963 'to_keep_id' => $retainedContact['id'],
2964 'to_remove_id' => $otherContact['id'],
2965 'auto_flip' => FALSE,
2966 ));
2967
2968 $contacts = $this->callAPISuccess('contact', 'get', $this->_params);
2969 $this->assertEquals($retainedContact['id'], $contacts['id']);
2970 $activity = $this->callAPISuccess('Activity', 'getsingle', array(
2971 'target_contact_id' => $retainedContact['id'],
2972 'activity_type_id' => 'Contact Merged',
2973 ));
2974 $this->assertEquals(date('Y-m-d'), date('Y-m-d', strtotime($activity['activity_date_time'])));
f00283b5 2975 $activity2 = $this->callAPISuccess('Activity', 'getsingle', array(
2976 'target_contact_id' => $otherContact['id'],
2977 'activity_type_id' => 'Contact Deleted by Merge',
2978 ));
2979 $this->assertEquals($activity['id'], $activity2['parent_id']);
2980 $this->assertEquals('Normal', civicrm_api3('option_value', 'getvalue', array(
2981 'value' => $activity['priority_id'],
2982 'return' => 'label',
2983 'option_group_id' => 'priority',
2984 )));
12d73bba 2985
2986 }
2987
4d834a99 2988 /**
2989 * Test merging 2 contacts with delete to trash off.
2990 *
2991 * We are checking that there is no error due to attempting to add an activity for the
2992 * deleted contact.
2993 *
2994 * CRM-18307
2995 */
2996 public function testMergeNoTrash() {
2997 $this->createLoggedInUser();
2998 $this->callAPISuccess('Setting', 'create', array('contact_undelete' => FALSE));
2999 $otherContact = $this->callAPISuccess('contact', 'create', $this->_params);
3000 $retainedContact = $this->callAPISuccess('contact', 'create', $this->_params);
3001 $this->callAPISuccess('contact', 'merge', array(
3002 'to_keep_id' => $retainedContact['id'],
3003 'to_remove_id' => $otherContact['id'],
3004 'auto_flip' => FALSE,
3005 ));
3006 $this->callAPISuccess('Setting', 'create', array('contact_undelete' => TRUE));
3007 }
3008
00ed3e04
CB
3009 /**
3010 * Ensure format with return=group shows comma-separated group IDs.
3011 *
3012 * CRM-19426
3013 */
3014 public function testContactGetReturnGroup() {
3015 // Set up a contact, asser that they were created.
3016 $contact_params = array(
3017 'contact_type' => 'Individual',
3018 'first_name' => 'Test',
3019 'last_name' => 'Groupmember',
3020 'email' => 'test@example.org',
3021 );
3022 $create_contact = $this->callApiSuccess('Contact', 'create', $contact_params);
3023 $this->assertEquals(0, $create_contact['is_error']);
3024 $this->assertInternalType('int', $create_contact['id']);
3025
3026 $created_contact_id = $create_contact['id'];
3027
3028 // Set up multiple groups, add the contact to the groups.
3029 $test_groups = array('Test group A', 'Test group B');
3030 foreach ($test_groups as $title) {
3031 // Use this contact as group owner, since we know they exist.
3032 $group_params = array(
3033 'title' => $title,
3034 'created_id' => $created_contact_id,
3035 );
3036 $create_group = $this->callApiSuccess('Group', 'create', $group_params);
3037 $this->assertEquals(0, $create_group['is_error']);
3038 $this->assertInternalType('int', $create_group['id']);
3039
3040 $created_group_ids[] = $create_group['id'];
3041
3042 // Add contact to the new group.
3043 $group_contact_params = array(
3044 'contact_id' => $created_contact_id,
3045 'group_id' => $create_group['id'],
3046 );
3047 $create_group_contact = $this->callApiSuccess('GroupContact', 'create', $group_contact_params);
3048 $this->assertEquals(0, $create_group_contact['is_error']);
3049 $this->assertInternalType('int', $create_group_contact['added']);
3050 }
3051
3052 // Use the Contact,get API to retrieve the contact
3053 $contact_get_params = array(
3054 'id' => $created_contact_id,
3055 'return' => 'group',
3056 );
3057 $contact_get = $this->callApiSuccess('Contact', 'get', $contact_get_params);
3058 $this->assertInternalType('array', $contact_get['values'][$created_contact_id]);
3059 $this->assertInternalType('string', $contact_get['values'][$created_contact_id]['groups']);
3060
3061 // Ensure they are shown as being in each created group.
3062 $contact_group_ids = explode(',', $contact_get['values'][$created_contact_id]['groups']);
3063 foreach ($created_group_ids as $created_group_id) {
3064 $this->assertContains($created_group_id, $contact_group_ids);
3065 }
3066 }
3067
6a488035 3068}