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