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