Merge pull request #5060 from eileenmcnaughton/api-comment-fixes
[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
32/**
33 * Include class definitions
34 */
35require_once 'CiviTest/CiviUnitTestCase.php';
36
37
38/**
39 * Test APIv3 civicrm_contact* functions
40 *
6c6e6187
TO
41 * @package CiviCRM_APIv3
42 * @subpackage API_Contact
6a488035 43 */
6a488035
TO
44class api_v3_ContactTest extends CiviUnitTestCase {
45 public $DBResetRequired = FALSE;
46 protected $_apiversion;
47 protected $_entity;
48 protected $_params;
b7c9bc4c 49
f6722559 50 protected $_contactID;
6c6e6187 51 protected $_financialTypeId = 1;
6a488035 52
6a488035 53 /**
381fa321 54 * Test setup for every test.
6a488035
TO
55 *
56 * Connect to the database, truncate the tables that will be used
57 * and redirect stdin to a temporary file
58 */
59 public function setUp() {
381fa321 60 // Connect to the database.
6a488035
TO
61 parent::setUp();
62 $this->_apiversion = 3;
f6722559 63 $this->_entity = 'contact';
64 $this->_params = array(
6a488035
TO
65 'first_name' => 'abc1',
66 'contact_type' => 'Individual',
67 'last_name' => 'xyz1',
6a488035 68 );
6a488035
TO
69 }
70
00be9182 71 public function tearDown() {
6a488035
TO
72 // truncate a few tables
73 $tablesToTruncate = array(
74 'civicrm_contact',
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',
6a488035
TO
82 );
83
f6722559 84 $this->quickCleanup($tablesToTruncate, TRUE);
6a488035
TO
85 }
86
87 /**
381fa321 88 * Test civicrm_contact_create.
6a488035 89 *
381fa321 90 * Verify that attempt to create individual contact with only
91 * first and last names succeeds
6a488035 92 */
00be9182 93 public function testAddCreateIndividual() {
6a488035
TO
94 $oldCount = CRM_Core_DAO::singleValueQuery('select count(*) from civicrm_contact');
95 $params = array(
96 'first_name' => 'abc1',
97 'contact_type' => 'Individual',
98 'last_name' => 'xyz1',
6a488035
TO
99 );
100
f6722559 101 $contact = $this->callAPISuccess('contact', 'create', $params);
6a488035
TO
102 $this->assertTrue(is_numeric($contact['id']), "In line " . __LINE__);
103 $this->assertTrue($contact['id'] > 0, "In line " . __LINE__);
104 $newCount = CRM_Core_DAO::singleValueQuery('select count(*) from civicrm_contact');
6c6e6187 105 $this->assertEquals($oldCount + 1, $newCount);
6a488035 106
6a488035
TO
107 $this->assertDBState('CRM_Contact_DAO_Contact',
108 $contact['id'],
109 $params
110 );
111 }
112
113 /**
381fa321 114 * Test civicrm_contact_create with sub-types.
6a488035 115 *
381fa321 116 * Verify that sub-types are created successfully and not deleted by subsequent updates.
6a488035 117 */
00be9182 118 public function testIndividualSubType() {
6a488035
TO
119 $params = array(
120 'first_name' => 'test abc',
121 'contact_type' => 'Individual',
122 'last_name' => 'test xyz',
123 'contact_sub_type' => array('Student', 'Staff'),
5896d037 124 );
f6722559 125 $contact = $this->callAPISuccess('contact', 'create', $params);
6a488035
TO
126 $cid = $contact['id'];
127
128 $params = array(
129 'id' => $cid,
130 'middle_name' => 'foo',
6a488035 131 );
f6722559 132 $this->callAPISuccess('contact', 'create', $params);
6a488035
TO
133 unset($params['middle_name']);
134
f6722559 135 $contact = $this->callAPISuccess('contact', 'get', $params);
6a488035
TO
136
137 $this->assertEquals(array('Student', 'Staff'), $contact['values'][$cid]['contact_sub_type'], "In line " . __LINE__);
138 }
139
140 /**
381fa321 141 * Verify that attempt to create contact with empty params fails.
6a488035 142 */
00be9182 143 public function testCreateEmptyContact() {
f6722559 144 $this->callAPIFailure('contact', 'create', array());
6a488035
TO
145 }
146
147 /**
381fa321 148 * Verify that attempt to create contact with bad contact type fails.
6a488035 149 */
00be9182 150 public function testCreateBadTypeContact() {
6a488035
TO
151 $params = array(
152 'email' => 'man1@yahoo.com',
153 'contact_type' => 'Does not Exist',
6a488035 154 );
6c6e6187 155 $this->callAPIFailure('contact', 'create', $params, "'Does not Exist' is not a valid option for field contact_type");
6a488035
TO
156 }
157
158 /**
381fa321 159 * Verify that attempt to create individual contact without required fields fails.
6a488035 160 */
00be9182 161 public function testCreateBadRequiredFieldsIndividual() {
6a488035
TO
162 $params = array(
163 'middle_name' => 'This field is not required',
164 'contact_type' => 'Individual',
165 );
4b58ed3b 166 $this->callAPIFailure('contact', 'create', $params);
6a488035
TO
167 }
168
169 /**
381fa321 170 * Verify that attempt to create household contact without required fields fails.
6a488035 171 */
00be9182 172 public function testCreateBadRequiredFieldsHousehold() {
6a488035
TO
173 $params = array(
174 'middle_name' => 'This field is not required',
175 'contact_type' => 'Household',
176 );
4b58ed3b 177 $this->callAPIFailure('contact', 'create', $params);
6a488035
TO
178 }
179
180 /**
381fa321 181 * Test required field check.
182 *
183 * Verify that attempt to create organization contact without required fields fails.
6a488035 184 */
00be9182 185 public function testCreateBadRequiredFieldsOrganization() {
6a488035
TO
186 $params = array(
187 'middle_name' => 'This field is not required',
188 'contact_type' => 'Organization',
189 );
190
4b58ed3b 191 $this->callAPIFailure('contact', 'create', $params);
6a488035
TO
192 }
193
194 /**
381fa321 195 * Verify that attempt to create individual contact with only an email succeeds.
6a488035 196 */
00be9182 197 public function testCreateEmailIndividual() {
6a488035
TO
198
199 $params = array(
200 'email' => 'man3@yahoo.com',
201 'contact_type' => 'Individual',
202 'location_type_id' => 1,
6a488035
TO
203 );
204
f6722559 205 $contact = $this->callAPISuccess('contact', 'create', $params);
206
6a488035 207 $this->assertEquals(1, $contact['id'], "In line " . __LINE__);
f6722559 208 $email = $this->callAPISuccess('email', 'get', array('contact_id' => $contact['id']));
209 $this->assertEquals(1, $email['count']);
210 $this->assertEquals('man3@yahoo.com', $email['values'][$email['id']]['email']);
6a488035 211
f6722559 212 $this->callAPISuccess('contact', 'delete', $contact);
6a488035
TO
213 }
214
215 /**
381fa321 216 * Test creating individual by name.
217 *
218 * Verify create individual contact with only first and last names succeeds.
6a488035 219 */
00be9182 220 public function testCreateNameIndividual() {
6a488035
TO
221 $params = array(
222 'first_name' => 'abc1',
223 'contact_type' => 'Individual',
224 'last_name' => 'xyz1',
6a488035 225 );
6a488035 226
f6722559 227 $contact = $this->callAPISuccess('contact', 'create', $params);
228 $this->assertEquals(1, $contact['id']);
6a488035
TO
229 }
230
231 /**
381fa321 232 * Test old keys still work.
233 *
234 * Verify that attempt to create individual contact with
6a488035
TO
235 * first and last names and old key values works
236 */
00be9182 237 public function testCreateNameIndividualOldKeys() {
6a488035
TO
238 $params = array(
239 'individual_prefix' => 'Dr.',
240 'first_name' => 'abc1',
241 'contact_type' => 'Individual',
242 'last_name' => 'xyz1',
243 'individual_suffix' => 'Jr.',
6a488035
TO
244 );
245
f6722559 246 $contact = $this->callAPISuccess('contact', 'create', $params);
6ecbca5b 247 $result = $this->callAPISuccess('contact', 'getsingle', array('id' => $contact['id']));
fd651abc 248
a1255c80
CW
249 $this->assertArrayKeyExists('prefix_id', $result);
250 $this->assertArrayKeyExists('suffix_id', $result);
251 $this->assertArrayKeyExists('gender_id', $result);
252 $this->assertEquals(4, $result['prefix_id']);
253 $this->assertEquals(1, $result['suffix_id']);
6a488035
TO
254 }
255
256 /**
381fa321 257 * Test preferred keys work.
258 *
259 * Verify that attempt to create individual contact with
6a488035
TO
260 * first and last names and old key values works
261 */
381fa321 262 public function testCreateNameIndividualRecommendedKeys2() {
6a488035
TO
263 $params = array(
264 'prefix_id' => 'Dr.',
265 'first_name' => 'abc1',
266 'contact_type' => 'Individual',
267 'last_name' => 'xyz1',
268 'suffix_id' => 'Jr.',
269 'gender_id' => 'Male',
6a488035
TO
270 );
271
f6722559 272 $contact = $this->callAPISuccess('contact', 'create', $params);
6ecbca5b 273 $result = $this->callAPISuccess('contact', 'getsingle', array('id' => $contact['id']));
fd651abc 274
a1255c80
CW
275 $this->assertArrayKeyExists('prefix_id', $result);
276 $this->assertArrayKeyExists('suffix_id', $result);
277 $this->assertArrayKeyExists('gender_id', $result);
278 $this->assertEquals(4, $result['prefix_id']);
279 $this->assertEquals(1, $result['suffix_id']);
6a488035
TO
280 }
281
282 /**
381fa321 283 * Test household name is sufficient for create.
284 *
285 * Verify that attempt to create household contact with only
6a488035
TO
286 * household name succeeds
287 */
00be9182 288 public function testCreateNameHousehold() {
6a488035
TO
289 $params = array(
290 'household_name' => 'The abc Household',
291 'contact_type' => 'Household',
6a488035 292 );
f6722559 293 $contact = $this->callAPISuccess('contact', 'create', $params);
6a488035 294 $this->assertEquals(1, $contact['id'], "In line " . __LINE__);
6a488035
TO
295 }
296
297 /**
381fa321 298 * Test organization name is sufficient for create.
299 *
300 * Verify that attempt to create organization contact with only
301 * organization name succeeds.
6a488035 302 */
00be9182 303 public function testCreateNameOrganization() {
6a488035
TO
304 $params = array(
305 'organization_name' => 'The abc Organization',
306 'contact_type' => 'Organization',
6a488035 307 );
f6722559 308 $contact = $this->callAPISuccess('contact', 'create', $params);
309 $this->assertEquals(1, $contact['id']);
6a488035 310 }
5896d037 311
6a488035 312 /**
381fa321 313 * Verify that attempt to create organization contact without organization name fails.
6a488035 314 */
00be9182 315 public function testCreateNoNameOrganization() {
6a488035
TO
316 $params = array(
317 'first_name' => 'The abc Organization',
318 'contact_type' => 'Organization',
6a488035 319 );
4b58ed3b 320 $this->callAPIFailure('contact', 'create', $params);
6a488035 321 }
5896d037 322
6a488035 323 /**
381fa321 324 * Check with complete array + custom field.
325 *
6a488035
TO
326 * Note that the test is written on purpose without any
327 * variables specific to participant so it can be replicated into other entities
328 * and / or moved to the automated test suite
329 */
00be9182 330 public function testCreateWithCustom() {
6a488035
TO
331 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__, __FILE__);
332
333 $params = $this->_params;
334 $params['custom_' . $ids['custom_field_id']] = "custom string";
335 $description = "/*this demonstrates setting a custom field through the API ";
fb32de45 336 $result = $this->callAPIAndDocument($this->_entity, 'create', $params, __FUNCTION__, __FILE__, $description);
6a488035 337
5896d037 338 $check = $this->callAPISuccess($this->_entity, 'get', array(
92915c55
TO
339 'return.custom_' . $ids['custom_field_id'] => 1,
340 'id' => $result['id'],
341 ));
4b58ed3b 342 $this->assertEquals("custom string", $check['values'][$check['id']]['custom_' . $ids['custom_field_id']]);
6a488035
TO
343
344 $this->customFieldDelete($ids['custom_field_id']);
345 $this->customGroupDelete($ids['custom_group_id']);
346 }
347
fe6daa04 348 /**
381fa321 349 * CRM-12773 - expectation is that civicrm quietly ignores fields without values.
fe6daa04 350 */
00be9182 351 public function testCreateWithNULLCustomCRM12773() {
fe6daa04 352 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__, __FILE__);
353 $params = $this->_params;
354 $params['custom_' . $ids['custom_field_id']] = NULL;
4b58ed3b 355 $this->callAPISuccess('contact', 'create', $params);
fe6daa04 356 $this->customFieldDelete($ids['custom_field_id']);
357 $this->customGroupDelete($ids['custom_group_id']);
358 }
359
360
d424ffde 361 /**
381fa321 362 * Test creating a current employer through API.
6a488035 363 */
5896d037 364 public function testContactCreateCurrentEmployer() {
381fa321 365 // Here we will just do the get for set-up purposes.
f6722559 366 $count = $this->callAPISuccess('contact', 'getcount', array(
6a488035 367 'organization_name' => 'new employer org',
21dfd5f5 368 'contact_type' => 'Organization',
6a488035
TO
369 ));
370 $this->assertEquals(0, $count);
f6722559 371 $employerResult = $this->callAPISuccess('contact', 'create', array_merge($this->_params, array(
5896d037
TO
372 'current_employer' => 'new employer org',
373 )
6a488035 374 ));
bb043d6f
E
375 // do it again as an update to check it doesn't cause an error
376 $employerResult = $this->callAPISuccess('contact', 'create', array_merge($this->_params, array(
6c6e6187 377 'current_employer' => 'new employer org',
21dfd5f5 378 'id' => $employerResult['id'],
5896d037 379 )
bb043d6f 380 ));
f6722559 381 $expectedCount = 1;
4b58ed3b 382 $this->callAPISuccess('contact', 'getcount', array(
5896d037 383 'organization_name' => 'new employer org',
21dfd5f5 384 'contact_type' => 'Organization',
5896d037
TO
385 ),
386 $expectedCount);
6a488035 387
f6722559 388 $result = $this->callAPISuccess('contact', 'getsingle', array(
6a488035
TO
389 'id' => $employerResult['id'],
390 ));
391
392 $this->assertEquals('new employer org', $result['current_employer']);
393
394 }
5896d037 395
d424ffde 396 /**
381fa321 397 * Test creating a current employer through API.
398 *
399 * Check it will re-activate a de-activated employer
d424ffde 400 */
5896d037 401 public function testContactCreateDuplicateCurrentEmployerEnables() {
381fa321 402 // Set up - create employer relationship.
bb043d6f 403 $employerResult = $this->callAPISuccess('contact', 'create', array_merge($this->_params, array(
5896d037
TO
404 'current_employer' => 'new employer org',
405 )
bb043d6f 406 ));
6c6e6187 407 $relationship = $this->callAPISuccess('relationship', 'get', array(
bb043d6f 408 'contact_id_a' => $employerResult['id'],
6c6e6187 409 ));
bb043d6f
E
410
411 //disable & check it is disabled
412 $this->callAPISuccess('relationship', 'create', array('id' => $relationship['id'], 'is_active' => 0));
6c6e6187 413 $this->callAPISuccess('relationship', 'getvalue', array(
bb043d6f 414 'id' => $relationship['id'],
21dfd5f5 415 'return' => 'is_active',
bb043d6f
E
416 ), 0);
417
381fa321 418 // Re-set the current employer - thus enabling the relationship.
4b58ed3b 419 $this->callAPISuccess('contact', 'create', array_merge($this->_params, array(
6c6e6187 420 'current_employer' => 'new employer org',
21dfd5f5 421 'id' => $employerResult['id'],
5896d037 422 )
bb043d6f
E
423 ));
424 //check is_active is now 1
6c6e6187 425 $relationship = $this->callAPISuccess('relationship', 'getsingle', array(
5896d037
TO
426 'return' => 'is_active',
427 ));
6c6e6187 428 $this->assertEquals(1, $relationship['is_active']);
bb043d6f
E
429 }
430
8f32b005 431 /**
381fa321 432 * Check deceased contacts are not retrieved.
433 *
434 * Note at time of writing the default is to return default. This should possibly be changed & test added.
8f32b005 435 */
00be9182 436 public function testGetDeceasedRetrieved() {
4b58ed3b 437 $this->callAPISuccess($this->_entity, 'create', $this->_params);
5896d037 438 $c2 = $this->callAPISuccess($this->_entity, 'create', array(
92915c55
TO
439 'first_name' => 'bb',
440 'last_name' => 'ccc',
441 'contact_type' => 'Individual',
442 'is_deceased' => 1,
443 ));
8f32b005 444 $result = $this->callAPISuccess($this->_entity, 'get', array('is_deceased' => 0));
445 $this->assertFalse(array_key_exists($c2['id'], $result['values']));
446 }
6a488035 447
c490a46a 448 /**
381fa321 449 * Test that sort works - old syntax.
c490a46a 450 */
00be9182 451 public function testGetSort() {
f6722559 452 $c1 = $this->callAPISuccess($this->_entity, 'create', $this->_params);
5896d037 453 $c2 = $this->callAPISuccess($this->_entity, 'create', array(
92915c55
TO
454 'first_name' => 'bb',
455 'last_name' => 'ccc',
456 'contact_type' => 'Individual',
457 ));
5896d037
TO
458 $result = $this->callAPISuccess($this->_entity, 'get', array(
459 'sort' => 'first_name ASC',
460 'return.first_name' => 1,
461 'sequential' => 1,
462 'rowCount' => 1,
463 ));
6a488035
TO
464
465 $this->assertEquals('abc1', $result['values'][0]['first_name']);
f6722559 466 $result = $this->callAPISuccess($this->_entity, 'get', array(
467 'sort' => 'first_name DESC',
468 'return.first_name' => 1,
469 'sequential' => 1,
470 'rowCount' => 1,
471 ));
6a488035
TO
472 $this->assertEquals('bb', $result['values'][0]['first_name']);
473
f6722559 474 $this->callAPISuccess($this->_entity, 'delete', array('id' => $c1['id']));
475 $this->callAPISuccess($this->_entity, 'delete', array('id' => $c2['id']));
6a488035 476 }
5896d037 477
d424ffde 478 /**
381fa321 479 * Test that we can retrieve contacts using array syntax.
480 *
481 * I.e 'id' => array('IN' => array('3,4')).
d424ffde 482 */
00be9182 483 public function testGetINIDArray() {
78c0bfc0 484 $c1 = $this->callAPISuccess($this->_entity, 'create', $this->_params);
5896d037 485 $c2 = $this->callAPISuccess($this->_entity, 'create', array(
92915c55
TO
486 'first_name' => 'bb',
487 'last_name' => 'ccc',
488 'contact_type' => 'Individual',
489 ));
5896d037 490 $c3 = $this->callAPISuccess($this->_entity, 'create', array(
92915c55
TO
491 'first_name' => 'hh',
492 'last_name' => 'll',
493 'contact_type' => 'Individual',
494 ));
78c0bfc0 495 $result = $this->callAPISuccess($this->_entity, 'get', array('id' => array('IN' => array($c1['id'], $c3['id']))));
496 $this->assertEquals(2, $result['count']);
497 $this->assertEquals(array($c1['id'], $c3['id']), array_keys($result['values']));
498 $this->callAPISuccess($this->_entity, 'delete', array('id' => $c1['id']));
499 $this->callAPISuccess($this->_entity, 'delete', array('id' => $c2['id']));
500 $this->callAPISuccess($this->_entity, 'delete', array('id' => $c3['id']));
501 }
5896d037 502
d424ffde 503 /**
381fa321 504 * Test variants on deleted behaviour.
6a488035 505 */
00be9182 506 public function testGetDeleted() {
6a488035 507 $params = $this->_params;
f6722559 508 $contact1 = $this->callAPISuccess('contact', 'create', $params);
6a488035
TO
509 $params['is_deleted'] = 1;
510 $params['last_name'] = 'bcd';
f6722559 511 $contact2 = $this->callAPISuccess('contact', 'create', $params);
512 $countActive = $this->callAPISuccess('contact', 'getcount', array('showAll' => 'active'));
513 $countAll = $this->callAPISuccess('contact', 'getcount', array('showAll' => 'all'));
514 $countTrash = $this->callAPISuccess('contact', 'getcount', array('showAll' => 'trash'));
515 $countDefault = $this->callAPISuccess('contact', 'getcount', array());
516 $countDeleted = $this->callAPISuccess('contact', 'getcount', array(
517 'contact_is_deleted' => 1,
5896d037 518 ));
f6722559 519 $countNotDeleted = $this->callAPISuccess('contact', 'getcount', array(
520 'contact_is_deleted' => 0,
5896d037 521 ));
f6722559 522 $this->callAPISuccess('contact', 'delete', array('id' => $contact1['id']));
523 $this->callAPISuccess('contact', 'delete', array('id' => $contact2['id']));
6a488035
TO
524 $this->assertEquals(1, $countNotDeleted, 'contact_is_deleted => 0 is respected in line ' . __LINE__);
525 $this->assertEquals(1, $countActive, 'in line ' . __LINE__);
526 $this->assertEquals(1, $countTrash, 'in line ' . __LINE__);
527 $this->assertEquals(2, $countAll, 'in line ' . __LINE__);
528 $this->assertEquals(1, $countDeleted, 'in line ' . __LINE__);
529 $this->assertEquals(1, $countDefault, 'Only active by default in line ' . __LINE__);
530 }
c490a46a
CW
531
532 /**
381fa321 533 * Test that sort works - new syntax.
c490a46a 534 */
381fa321 535 public function testGetSortNewSyntax() {
5896d037
TO
536 $c1 = $this->callAPISuccess($this->_entity, 'create', $this->_params);
537 $c2 = $this->callAPISuccess($this->_entity, 'create', array(
92915c55
TO
538 'first_name' => 'bb',
539 'last_name' => 'ccc',
540 'contact_type' => 'Individual',
541 ));
f6722559 542 $result = $this->callAPISuccess($this->_entity, 'getvalue', array(
6a488035 543 'return' => 'first_name',
5896d037
TO
544 'options' => array(
545 'limit' => 1,
546 'sort' => 'first_name',
547 ),
548 ));
6a488035
TO
549 $this->assertEquals('abc1', $result, 'in line' . __LINE__);
550
f6722559 551 $result = $this->callAPISuccess($this->_entity, 'getvalue', array(
5896d037
TO
552 'return' => 'first_name',
553 'options' => array(
554 'limit' => 1,
555 'sort' => 'first_name DESC',
556 ),
557 ));
6a488035
TO
558 $this->assertEquals('bb', $result);
559
f6722559 560 $this->callAPISuccess($this->_entity, 'delete', array('id' => $c1['id']));
561 $this->callAPISuccess($this->_entity, 'delete', array('id' => $c2['id']));
6a488035 562 }
c490a46a
CW
563
564 /**
381fa321 565 * Test apostrophe works in get & create.
6a488035 566 */
00be9182 567 public function testGetApostropheCRM10857() {
6a488035 568 $params = array_merge($this->_params, array('last_name' => "O'Connor"));
4b58ed3b 569 $this->callAPISuccess($this->_entity, 'create', $params);
f6722559 570 $result = $this->callAPISuccess($this->_entity, 'getsingle', array(
6a488035
TO
571 'last_name' => "O'Connor",
572 'sequential' => 1,
573 ));
574 $this->assertEquals("O'Connor", $result['last_name'], 'in line' . __LINE__);
575 }
576
577 /**
381fa321 578 * Check with complete array + custom field.
579 *
6a488035
TO
580 * Note that the test is written on purpose without any
581 * variables specific to participant so it can be replicated into other entities
582 * and / or moved to the automated test suite
583 */
00be9182 584 public function testGetWithCustom() {
6a488035
TO
585 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__, __FILE__);
586
587 $params = $this->_params;
588 $params['custom_' . $ids['custom_field_id']] = "custom string";
589 $description = "/*this demonstrates setting a custom field through the API ";
590 $subfile = "CustomFieldGet";
f6722559 591 $result = $this->callAPISuccess($this->_entity, 'create', $params);
6a488035 592
5896d037 593 $check = $this->callAPIAndDocument($this->_entity, 'get', array(
92915c55
TO
594 'return.custom_' . $ids['custom_field_id'] => 1,
595 'id' => $result['id'],
596 ), __FUNCTION__, __FILE__, $description, $subfile);
6a488035 597
4b58ed3b 598 $this->assertEquals("custom string", $check['values'][$check['id']]['custom_' . $ids['custom_field_id']]);
f6722559 599 $fields = ($this->callAPISuccess('contact', 'getfields', $params));
6a488035
TO
600 $this->assertTrue(is_array($fields['values']['custom_' . $ids['custom_field_id']]));
601 $this->customFieldDelete($ids['custom_field_id']);
602 $this->customGroupDelete($ids['custom_group_id']);
603 }
c490a46a
CW
604
605 /**
381fa321 606 * Check with complete array + custom field.
607 *
c490a46a
CW
608 * Note that the test is written on purpose without any
609 * variables specific to participant so it can be replicated into other entities
610 * and / or moved to the automated test suite
611 */
00be9182 612 public function testGetWithCustomReturnSyntax() {
6a488035
TO
613 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__, __FILE__);
614
615 $params = $this->_params;
616 $params['custom_' . $ids['custom_field_id']] = "custom string";
617 $description = "/*this demonstrates setting a custom field through the API ";
618 $subfile = "CustomFieldGetReturnSyntaxVariation";
f6722559 619 $result = $this->callAPISuccess($this->_entity, 'create', $params);
620 $params = array('return' => 'custom_' . $ids['custom_field_id'], 'id' => $result['id']);
621 $check = $this->callAPIAndDocument($this->_entity, 'get', $params, __FUNCTION__, __FILE__, $description, $subfile);
6a488035 622
43ef1263 623 $this->assertEquals("custom string", $check['values'][$check['id']]['custom_' . $ids['custom_field_id']]);
6a488035
TO
624 $this->customFieldDelete($ids['custom_field_id']);
625 $this->customGroupDelete($ids['custom_group_id']);
626 }
627
43ef1263 628 /**
381fa321 629 * Check that address name is returned if required.
43ef1263 630 */
5896d037 631 public function testGetReturnAddressName() {
43ef1263 632 $contactID = $this->individualCreate();
5896d037 633 $this->callAPISuccess('address', 'create', array(
92915c55
TO
634 'contact_id' => $contactID,
635 'address_name' => 'My house',
636 'location_type_id' => 'Home',
637 'street_address' => '1 my road',
638 ));
5896d037 639 $result = $this->callAPISuccessGetSingle('contact', array(
92915c55
TO
640 'return' => 'address_name, street_address',
641 'id' => $contactID,
642 ));
43ef1263
EM
643 $this->assertEquals('1 my road', $result['street_address']);
644 $this->assertEquals('My house', $result['address_name']);
645
646 }
647
00be9182 648 public function testGetGroupIDFromContact() {
5896d037 649 $groupId = $this->groupCreate();
6a488035 650 $description = "Get all from group and display contacts";
5896d037
TO
651 $subFile = "GroupFilterUsingContactAPI";
652 $params = array(
6a488035
TO
653 'email' => 'man2@yahoo.com',
654 'contact_type' => 'Individual',
655 'location_type_id' => 1,
6a488035
TO
656 'api.group_contact.create' => array('group_id' => $groupId),
657 );
658
4b58ed3b 659 $this->callAPISuccess('contact', 'create', $params);
6a488035
TO
660 // testing as integer
661 $params = array(
662 'filter.group_id' => $groupId,
6a488035
TO
663 'contact_type' => 'Individual',
664 );
4b58ed3b 665 $result = $this->callAPIAndDocument('contact', 'get', $params, __FUNCTION__, __FILE__, $description, $subFile);
6a488035
TO
666 $this->assertEquals(1, $result['count']);
667 // group 26 doesn't exist, but we can still search contacts in it.
668 $params = array(
669 'filter.group_id' => 26,
6a488035
TO
670 'contact_type' => 'Individual',
671 );
4b58ed3b 672 $this->callAPISuccess('contact', 'get', $params);
6a488035
TO
673 // testing as string
674 $params = array(
f6722559 675 'filter.group_id' => "$groupId, 26",
6a488035
TO
676 'contact_type' => 'Individual',
677 );
4b58ed3b 678 $result = $this->callAPIAndDocument('contact', 'get', $params, __FUNCTION__, __FILE__, $description, $subFile);
6a488035
TO
679 $this->assertEquals(1, $result['count']);
680 $params = array(
681 'filter.group_id' => "26,27",
6a488035
TO
682 'contact_type' => 'Individual',
683 );
4b58ed3b 684 $this->callAPISuccess('contact', 'get', $params);
6a488035
TO
685
686 // testing as string
6c6e6187 687 $params = array(
5896d037 688 'filter.group_id' => array($groupId, 26),
6a488035
TO
689 'contact_type' => 'Individual',
690 );
4b58ed3b 691 $result = $this->callAPIAndDocument('contact', 'get', $params, __FUNCTION__, __FILE__, $description, $subFile);
6a488035
TO
692 $this->assertEquals(1, $result['count']);
693
694 //test in conjunction with other criteria
6c6e6187 695 $params = array(
5896d037 696 'filter.group_id' => array($groupId, 26),
6a488035
TO
697 'contact_type' => 'Organization',
698 );
6c6e6187
TO
699 $this->callAPISuccess('contact', 'get', $params);
700 $params = array(
5896d037 701 'filter.group_id' => array(26, 27),
6a488035
TO
702 'contact_type' => 'Individual',
703 );
f6722559 704 $result = $this->callAPISuccess('contact', 'get', $params);
4b58ed3b 705 $this->assertEquals(0, $result['count']);
6a488035
TO
706 }
707
708 /**
381fa321 709 * Verify that attempt to create individual contact with two chained websites succeeds.
6a488035 710 */
00be9182 711 public function testCreateIndividualWithContributionDottedSyntax() {
6a488035 712 $description = "test demonstrates the syntax to create 2 chained entities";
5896d037
TO
713 $subFile = "ChainTwoWebsites";
714 $params = array(
6a488035
TO
715 'first_name' => 'abc3',
716 'last_name' => 'xyz3',
717 'contact_type' => 'Individual',
718 'email' => 'man3@yahoo.com',
6a488035
TO
719 'api.contribution.create' => array(
720 'receive_date' => '2010-01-01',
721 'total_amount' => 100.00,
5896d037 722 'financial_type_id' => $this->_financialTypeId,
6a488035
TO
723 'payment_instrument_id' => 1,
724 'non_deductible_amount' => 10.00,
725 'fee_amount' => 50.00,
726 'net_amount' => 90.00,
727 'trxn_id' => 15345,
728 'invoice_id' => 67990,
729 'source' => 'SSF',
730 'contribution_status_id' => 1,
731 ),
732 'api.website.create' => array(
733 'url' => "http://civicrm.org",
734 ),
735 'api.website.create.2' => array(
736 'url' => "http://chained.org",
737 ),
738 );
739
4b58ed3b 740 $result = $this->callAPIAndDocument('Contact', 'create', $params, __FUNCTION__, __FILE__, $description, $subFile);
6a488035 741
381fa321 742 $this->assertEquals(1, $result['id']);
f6722559 743 // checking child function result not covered in callAPIAndDocument
744 $this->assertAPISuccess($result['values'][$result['id']]['api.website.create']);
6a488035
TO
745 $this->assertEquals("http://chained.org", $result['values'][$result['id']]['api.website.create.2']['values'][0]['url'], "In line " . __LINE__);
746 $this->assertEquals("http://civicrm.org", $result['values'][$result['id']]['api.website.create']['values'][0]['url'], "In line " . __LINE__);
747
748 // delete the contact
f6722559 749 $this->callAPISuccess('contact', 'delete', $result);
6a488035
TO
750 }
751
752 /**
381fa321 753 * Verify that attempt to create individual contact with chained contribution and website succeeds.
6a488035 754 */
00be9182 755 public function testCreateIndividualWithContributionChainedArrays() {
6a488035
TO
756 $params = array(
757 'first_name' => 'abc3',
758 'last_name' => 'xyz3',
759 'contact_type' => 'Individual',
760 'email' => 'man3@yahoo.com',
6a488035
TO
761 'api.contribution.create' => array(
762 'receive_date' => '2010-01-01',
763 'total_amount' => 100.00,
5896d037 764 'financial_type_id' => $this->_financialTypeId,
6a488035
TO
765 'payment_instrument_id' => 1,
766 'non_deductible_amount' => 10.00,
767 'fee_amount' => 50.00,
768 'net_amount' => 90.00,
769 'trxn_id' => 12345,
770 'invoice_id' => 67890,
771 'source' => 'SSF',
772 'contribution_status_id' => 1,
773 ),
774 'api.website.create' => array(
775 array(
776 'url' => "http://civicrm.org",
777 ),
778 array(
779 'url' => "http://chained.org",
780 'website_type_id' => 2,
781 ),
782 ),
783 );
784
785 $description = "demonstrates creating two websites as an array";
5896d037
TO
786 $subfile = "ChainTwoWebsitesSyntax2";
787 $result = $this->callAPIAndDocument('Contact', 'create', $params, __FUNCTION__, __FILE__, $description, $subfile);
f6722559 788
789 $this->assertEquals(1, $result['id']);
790 // the callAndDocument doesn't check the chained call
6a488035
TO
791 $this->assertEquals(0, $result['values'][$result['id']]['api.website.create'][0]['is_error'], "In line " . __LINE__);
792 $this->assertEquals("http://chained.org", $result['values'][$result['id']]['api.website.create'][1]['values'][0]['url'], "In line " . __LINE__);
793 $this->assertEquals("http://civicrm.org", $result['values'][$result['id']]['api.website.create'][0]['values'][0]['url'], "In line " . __LINE__);
794
f6722559 795 $this->callAPISuccess('contact', 'delete', $result);
6a488035
TO
796 }
797
798 /**
381fa321 799 * Verify that attempt to create individual contact with first
6a488035
TO
800 * and last names and email succeeds
801 */
00be9182 802 public function testCreateIndividualWithNameEmail() {
6a488035
TO
803 $params = array(
804 'first_name' => 'abc3',
805 'last_name' => 'xyz3',
806 'contact_type' => 'Individual',
807 'email' => 'man3@yahoo.com',
6a488035
TO
808 );
809
f6722559 810 $contact = $this->callAPISuccess('contact', 'create', $params);
6a488035
TO
811 $this->assertEquals(1, $contact['id'], "In line " . __LINE__);
812
813 // delete the contact
f6722559 814 $this->callAPISuccess('contact', 'delete', $contact);
6a488035 815 }
5896d037 816
6a488035 817 /**
381fa321 818 * Verify that attempt to create individual contact with no data fails
6a488035 819 */
00be9182 820 public function testCreateIndividualWithOutNameEmail() {
6a488035
TO
821 $params = array(
822 'contact_type' => 'Individual',
6a488035 823 );
4b58ed3b 824 $this->callAPIFailure('contact', 'create', $params);
6a488035 825 }
5896d037 826
6a488035 827 /**
381fa321 828 * Verify that attempt to create individual contact with first
6a488035
TO
829 * and last names, email and location type succeeds
830 */
00be9182 831 public function testCreateIndividualWithNameEmailLocationType() {
6a488035
TO
832 $params = array(
833 'first_name' => 'abc4',
834 'last_name' => 'xyz4',
835 'email' => 'man4@yahoo.com',
836 'contact_type' => 'Individual',
837 'location_type_id' => 1,
6a488035 838 );
f6722559 839 $result = $this->callAPISuccess('contact', 'create', $params);
6a488035 840
6a488035
TO
841 $this->assertEquals(1, $result['id'], "In line " . __LINE__);
842
f6722559 843 $this->callAPISuccess('contact', 'delete', array('id' => $result['id']));
6a488035
TO
844 }
845
846 /**
847 * Verify that when changing employers
848 * the old employer relationship becomes inactive
849 */
00be9182 850 public function testCreateIndividualWithEmployer() {
6a488035
TO
851 $employer = $this->organizationCreate();
852 $employer2 = $this->organizationCreate();
853
854 $params = array(
5896d037
TO
855 'email' => 'man4@yahoo.com',
856 'contact_type' => 'Individual',
857 'employer_id' => $employer,
6a488035
TO
858 );
859
f6722559 860 $result = $this->callAPISuccess('contact', 'create', $params);
861 $relationships = $this->callAPISuccess('relationship', 'get', array(
6a488035
TO
862 'contact_id_a' => $result['id'],
863 'sequential' => 1,
864 ));
865
866 $this->assertEquals($employer, $relationships['values'][0]['contact_id_b']);
867
868 // Add more random relationships to make the test more realistic
4b58ed3b
EM
869 foreach (array('Employee of', 'Volunteer for') as $relationshipType) {
870 $relTypeId = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_RelationshipType', $relationshipType, 'id', 'name_a_b');
871 $this->callAPISuccess('relationship', 'create', array(
6a488035
TO
872 'contact_id_a' => $result['id'],
873 'contact_id_b' => $this->organizationCreate(),
874 'is_active' => 1,
875 'relationship_type_id' => $relTypeId,
876 ));
6c6e6187 877 }
6a488035
TO
878
879 // Add second employer
880 $params['employer_id'] = $employer2;
881 $params['id'] = $result['id'];
f6722559 882 $result = $this->callAPISuccess('contact', 'create', $params);
6a488035 883
f6722559 884 $relationships = $this->callAPISuccess('relationship', 'get', array(
6a488035
TO
885 'contact_id_a' => $result['id'],
886 'sequential' => 1,
887 'is_active' => 0,
888 ));
889
890 $this->assertEquals($employer, $relationships['values'][0]['contact_id_b']);
891 }
892
893 /**
381fa321 894 * Verify that attempt to create household contact with details
6a488035
TO
895 * succeeds
896 */
00be9182 897 public function testCreateHouseholdDetails() {
6a488035
TO
898 $params = array(
899 'household_name' => 'abc8\'s House',
900 'nick_name' => 'x House',
901 'email' => 'man8@yahoo.com',
902 'contact_type' => 'Household',
6a488035
TO
903 );
904
f6722559 905 $contact = $this->callAPISuccess('contact', 'create', $params);
906
6a488035
TO
907 $this->assertEquals(1, $contact['id'], "In line " . __LINE__);
908
f6722559 909 $this->callAPISuccess('contact', 'delete', $contact);
6a488035 910 }
5896d037 911
6a488035 912 /**
381fa321 913 * Verify that attempt to create household contact with inadequate details fails.
6a488035 914 */
00be9182 915 public function testCreateHouseholdInadequateDetails() {
6a488035
TO
916 $params = array(
917 'nick_name' => 'x House',
918 'email' => 'man8@yahoo.com',
919 'contact_type' => 'Household',
6a488035 920 );
4b58ed3b 921 $this->callAPIFailure('contact', 'create', $params);
6a488035
TO
922 }
923
6a488035 924 /**
381fa321 925 * Verify successful update of individual contact.
6a488035 926 */
00be9182 927 public function testUpdateIndividualWithAll() {
381fa321 928 // Insert a row in civicrm_contact creating individual contact.
6a488035
TO
929 $op = new PHPUnit_Extensions_Database_Operation_Insert();
930 $op->execute($this->_dbconn,
bbfd46a5 931 $this->createXMLDataSet(
6a488035
TO
932 dirname(__FILE__) . '/dataset/contact_ind.xml'
933 )
934 );
935
936 $params = array(
937 'id' => 23,
938 'first_name' => 'abcd',
939 'contact_type' => 'Individual',
940 'nick_name' => 'This is nickname first',
941 'do_not_email' => '1',
942 'do_not_phone' => '1',
943 'do_not_mail' => '1',
944 'do_not_trade' => '1',
945 'legal_identifier' => 'ABC23853ZZ2235',
946 'external_identifier' => '1928837465',
947 'image_URL' => 'http://some.url.com/image.jpg',
948 'home_url' => 'http://www.example.org',
f6722559 949
950 );
43ef1263 951
4b58ed3b 952 $this->callAPISuccess('Contact', 'Update', $params);
f6722559 953 $getResult = $this->callAPISuccess('Contact', 'Get', $params);
6a488035
TO
954 unset($params['contact_id']);
955 //Todo - neither API v2 or V3 are testing for home_url - not sure if it is being set.
4b58ed3b 956 //reducing this test partially back to api v2 level to get it through
6a488035
TO
957 unset($params['home_url']);
958 foreach ($params as $key => $value) {
4b58ed3b 959 $this->assertEquals($value, $getResult['values'][23][$key]);
6a488035 960 }
381fa321 961 // Check updated civicrm_contact against expected.
bbfd46a5 962 $expected = $this->createXMLDataSet(
6a488035
TO
963 dirname(__FILE__) . '/dataset/contact_ind_upd.xml'
964 );
bbfd46a5 965 $actual = new PHPUnit_Extensions_Database_DataSet_QueryDataSet(
6a488035
TO
966 $this->_dbconn
967 );
968 $actual->addTable('civicrm_contact');
969 $expected->matches($actual);
970 }
971
972 /**
381fa321 973 * Verify successful update of organization contact
6a488035 974 */
00be9182 975 public function testUpdateOrganizationWithAll() {
381fa321 976 // Insert a row in civicrm_contact creating organization contact
6a488035
TO
977 $op = new PHPUnit_Extensions_Database_Operation_Insert();
978 $op->execute($this->_dbconn,
bbfd46a5 979 $this->createXMLDataSet(
6a488035
TO
980 dirname(__FILE__) . '/dataset/contact_org.xml'
981 )
982 );
983
984 $params = array(
985 'id' => 24,
986 'organization_name' => 'WebAccess India Pvt Ltd',
987 'legal_name' => 'WebAccess',
988 'sic_code' => 'ABC12DEF',
989 'contact_type' => 'Organization',
6a488035
TO
990 );
991
4b58ed3b 992 $this->callAPISuccess('Contact', 'Update', $params);
6a488035 993
381fa321 994 // Check updated civicrm_contact against expected.
bbfd46a5 995 $expected = $this->createXMLDataSet(
6a488035
TO
996 dirname(__FILE__) . '/dataset/contact_org_upd.xml'
997 );
bbfd46a5 998 $actual = new PHPUnit_Extensions_Database_DataSet_QueryDataSet(
6a488035
TO
999 $this->_dbconn
1000 );
1001 $actual->addTable('civicrm_contact');
1002 $expected->matches($actual);
1003 }
1004
1005 /**
381fa321 1006 * Verify successful update of household contact.
6a488035 1007 */
381fa321 1008 public function testUpdateHouseholdWithAll() {
1009 // Insert a row in civicrm_contact creating household contact
6a488035
TO
1010 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1011 $op->execute($this->_dbconn,
bbfd46a5 1012 $this->createXMLDataSet(
6a488035
TO
1013 dirname(__FILE__) . '/dataset/contact_hld.xml'
1014 )
1015 );
1016
1017 $params = array(
1018 'id' => 25,
1019 'household_name' => 'ABC household',
1020 'nick_name' => 'ABC House',
1021 'contact_type' => 'Household',
6a488035
TO
1022 );
1023
f6722559 1024 $result = $this->callAPISuccess('Contact', 'Update', $params);
6a488035 1025
43ef1263
EM
1026 $expected = array(
1027 'contact_type' => 'Household',
1028 'is_opt_out' => 0,
1029 'sort_name' => 'ABC household',
1030 'display_name' => 'ABC household',
1031 'nick_name' => 'ABC House',
6a488035 1032 );
43ef1263 1033 $this->getAndCheck($expected, $result['id'], 'contact');
6a488035
TO
1034 }
1035
1036 /**
381fa321 1037 * Test civicrm_update() without contact type.
1038 *
1039 * Deliberately exclude contact_type as it should still cope using civicrm_api.
1040 *
1041 * CRM-7645.
6a488035 1042 */
6a488035 1043 public function testUpdateCreateWithID() {
381fa321 1044 // Insert a row in civicrm_contact creating individual contact.
6a488035
TO
1045 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1046 $op->execute($this->_dbconn,
bbfd46a5 1047 $this->createXMLDataSet(
6a488035
TO
1048 dirname(__FILE__) . '/dataset/contact_ind.xml'
1049 )
1050 );
1051
6a488035
TO
1052 $params = array(
1053 'id' => 23,
1054 'first_name' => 'abcd',
1055 'last_name' => 'wxyz',
6a488035 1056 );
4b58ed3b 1057 $this->callAPISuccess('Contact', 'Update', $params);
6a488035
TO
1058 }
1059
1060 /**
381fa321 1061 * Test civicrm_contact_delete() with no contact ID.
6a488035 1062 */
00be9182 1063 public function testContactDeleteNoID() {
6a488035
TO
1064 $params = array(
1065 'foo' => 'bar',
6a488035 1066 );
4b58ed3b 1067 $this->callAPIFailure('contact', 'delete', $params);
6a488035
TO
1068 }
1069
1070 /**
381fa321 1071 * Test civicrm_contact_delete() with error.
6a488035 1072 */
00be9182 1073 public function testContactDeleteError() {
f6722559 1074 $params = array('contact_id' => 999);
4b58ed3b 1075 $this->callAPIFailure('contact', 'delete', $params);
6a488035
TO
1076 }
1077
1078 /**
381fa321 1079 * Test civicrm_contact_delete().
6a488035 1080 */
00be9182 1081 public function testContactDelete() {
f6722559 1082 $contactID = $this->individualCreate();
6a488035 1083 $params = array(
5896d037 1084 'id' => $contactID,
6a488035 1085 );
4b58ed3b 1086 $this->callAPIAndDocument('contact', 'delete', $params, __FUNCTION__, __FILE__);
6a488035
TO
1087 }
1088
1089 /**
381fa321 1090 * Test civicrm_contact_get() return only first name.
6a488035
TO
1091 */
1092 public function testContactGetRetFirst() {
f6722559 1093 $contact = $this->callAPISuccess('contact', 'create', $this->_params);
6a488035
TO
1094 $params = array(
1095 'contact_id' => $contact['id'],
1096 'return_first_name' => TRUE,
1097 'sort' => 'first_name',
6a488035 1098 );
f6722559 1099 $result = $this->callAPISuccess('contact', 'get', $params);
4b58ed3b
EM
1100 $this->assertEquals(1, $result['count']);
1101 $this->assertEquals($contact['id'], $result['id']);
1102 $this->assertEquals('abc1', $result['values'][$contact['id']]['first_name']);
6a488035
TO
1103 }
1104
1105 /**
381fa321 1106 * Test civicrm_contact_get() return only first name & last name.
1107 *
1108 * Use comma separated string return with a space.
6a488035 1109 */
381fa321 1110 public function testContactGetReturnFirstLast() {
f6722559 1111 $contact = $this->callAPISuccess('contact', 'create', $this->_params);
6a488035
TO
1112 $params = array(
1113 'contact_id' => $contact['id'],
1114 'return' => 'first_name, last_name',
6a488035 1115 );
f6722559 1116 $result = $this->callAPISuccess('contact', 'getsingle', $params);
4b58ed3b
EM
1117 $this->assertEquals('abc1', $result['first_name']);
1118 $this->assertEquals('xyz1', $result['last_name']);
6a488035
TO
1119 //check that other defaults not returns
1120 $this->assertArrayNotHasKey('sort_name', $result);
1121 $params = array(
1122 'contact_id' => $contact['id'],
1123 'return' => 'first_name,last_name',
6a488035 1124 );
f6722559 1125 $result = $this->callAPISuccess('contact', 'getsingle', $params);
4b58ed3b
EM
1126 $this->assertEquals('abc1', $result['first_name']);
1127 $this->assertEquals('xyz1', $result['last_name']);
6a488035
TO
1128 //check that other defaults not returns
1129 $this->assertArrayNotHasKey('sort_name', $result);
1130 }
1131
1132 /**
381fa321 1133 * Test civicrm_contact_get() return only first name & last name.
1134 *
6a488035
TO
1135 * Use comma separated string return without a space
1136 */
381fa321 1137 public function testContactGetReturnFirstLastNoComma() {
f6722559 1138 $contact = $this->callAPISuccess('contact', 'create', $this->_params);
6a488035
TO
1139 $params = array(
1140 'contact_id' => $contact['id'],
1141 'return' => 'first_name,last_name',
6a488035 1142 );
f6722559 1143 $result = $this->callAPISuccess('contact', 'getsingle', $params);
4b58ed3b
EM
1144 $this->assertEquals('abc1', $result['first_name']);
1145 $this->assertEquals('xyz1', $result['last_name']);
6a488035
TO
1146 //check that other defaults not returns
1147 $this->assertArrayNotHasKey('sort_name', $result);
1148 }
1149
1150 /**
381fa321 1151 * Test civicrm_contact_get() with default return properties.
6a488035
TO
1152 */
1153 public function testContactGetRetDefault() {
43ef1263 1154 $contactID = $this->individualCreate();
6a488035 1155 $params = array(
43ef1263 1156 'contact_id' => $contactID,
6a488035 1157 'sort' => 'first_name',
6a488035 1158 );
f6722559 1159 $result = $this->callAPISuccess('contact', 'get', $params);
43ef1263
EM
1160 $this->assertEquals($contactID, $result['values'][$contactID]['contact_id']);
1161 $this->assertEquals('Anthony', $result['values'][$contactID]['first_name']);
6a488035
TO
1162 }
1163
1164 /**
381fa321 1165 * Test civicrm_contact_getquick() with empty name param.
6a488035
TO
1166 */
1167 public function testContactGetQuick() {
1168 // Insert a row in civicrm_contact creating individual contact
1169 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1170 $op->execute($this->_dbconn,
bbfd46a5 1171 $this->createXMLDataSet(
6a488035
TO
1172 dirname(__FILE__) . '/dataset/contact_17.xml'
1173 )
1174 );
1175 $op->execute($this->_dbconn,
bbfd46a5 1176 $this->createXMLDataSet(
6a488035
TO
1177 dirname(__FILE__) . '/dataset/email_contact_17.xml'
1178 )
1179 );
1180 $params = array(
1181 'name' => "T",
6a488035
TO
1182 );
1183
1d6020f1 1184 $result = $this->callAPISuccess('contact', 'getquick', $params);
6a488035
TO
1185 $this->assertEquals(17, $result['values'][0]['id'], 'in line ' . __LINE__);
1186 }
1187
1188 /**
381fa321 1189 * Test civicrm_contact_get) with empty params
6a488035
TO
1190 */
1191 public function testContactGetEmptyParams() {
4b58ed3b 1192 $this->callAPISuccess('contact', 'get', array());
6a488035
TO
1193 }
1194
1195 /**
381fa321 1196 * Test civicrm_contact_get(,true) with no matches
6a488035
TO
1197 */
1198 public function testContactGetOldParamsNoMatches() {
1199 // Insert a row in civicrm_contact creating contact 17
1200 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1201 $op->execute($this->_dbconn,
bbfd46a5 1202 $this->createXMLDataSet(
6a488035
TO
1203 dirname(__FILE__) . '/dataset/contact_17.xml'
1204 )
1205 );
1206
1207 $params = array(
1208 'first_name' => 'Fred',
6a488035 1209 );
f6722559 1210 $result = $this->callAPISuccess('contact', 'get', $params);
6a488035
TO
1211 $this->assertEquals(0, $result['count'], 'in line ' . __LINE__);
1212 }
1213
1214 /**
381fa321 1215 * Test civicrm_contact_get(,true) with one match
6a488035
TO
1216 */
1217 public function testContactGetOldParamsOneMatch() {
1218 // Insert a row in civicrm_contact creating contact 17
1219 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1220 $op->execute($this->_dbconn,
bbfd46a5 1221 $this->createXMLDataSet(dirname(__FILE__) . '/dataset/contact_17.xml'
6a488035
TO
1222 )
1223 );
1224
1225 $params = array(
1226 'first_name' => 'Test',
6a488035 1227 );
f6722559 1228 $result = $this->callAPISuccess('contact', 'get', $params);
6a488035
TO
1229 $this->assertEquals(17, $result['values'][17]['contact_id'], 'in line ' . __LINE__);
1230 $this->assertEquals(17, $result['id'], 'in line ' . __LINE__);
1231 }
6a488035
TO
1232
1233 /**
381fa321 1234 * Test civicrm_contact_search_count()
6a488035
TO
1235 */
1236 public function testContactGetEmail() {
1237 $params = array(
1238 'email' => 'man2@yahoo.com',
1239 'contact_type' => 'Individual',
1240 'location_type_id' => 1,
6a488035
TO
1241 );
1242
f6722559 1243 $contact = $this->callAPISuccess('contact', 'create', $params);
1244
4b58ed3b 1245 $this->assertEquals(1, $contact['id']);
6a488035
TO
1246
1247 $params = array(
1248 'email' => 'man2@yahoo.com',
6a488035 1249 );
f6722559 1250 $result = $this->callAPIAndDocument('contact', 'get', $params, __FUNCTION__, __FILE__);
4b58ed3b
EM
1251 $this->assertEquals(1, $result['values'][1]['contact_id']);
1252 $this->assertEquals('man2@yahoo.com', $result['values'][1]['email']);
6a488035
TO
1253
1254 // delete the contact
f6722559 1255 $this->callAPISuccess('contact', 'delete', $contact);
6a488035
TO
1256 }
1257
b1f09bea 1258 /**
381fa321 1259 * Test birth date params incl value, array & birth_date_high, birth_date_low
b1f09bea
E
1260 * && deceased
1261 */
4b58ed3b 1262 public function testContactGetBirthDate() {
b1f09bea
E
1263 $contact1 = $this->callAPISuccess('contact', 'create', array_merge($this->_params, array('birth_date' => 'first day of next month - 2 years')));
1264 $contact2 = $this->callAPISuccess('contact', 'create', array_merge($this->_params, array('birth_date' => 'first day of next month - 5 years')));
1265 $contact3 = $this->callAPISuccess('contact', 'create', array_merge($this->_params, array('birth_date' => 'first day of next month -20 years')));
1266
1267 $result = $this->callAPISuccess('contact', 'get', array());
1268 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -2 years')), $result['values'][$contact1['id']]['birth_date']);
1269 $result = $this->callAPISuccess('contact', 'get', array('birth_date' => 'first day of next month -5 years'));
1270 $this->assertEquals(1, $result['count']);
1271 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -5 years')), $result['values'][$contact2['id']]['birth_date']);
1272 $result = $this->callAPISuccess('contact', 'get', array('birth_date_high' => date('Y-m-d', strtotime('-6 years'))));
1273 $this->assertEquals(1, $result['count']);
1274 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -20 years')), $result['values'][$contact3['id']]['birth_date']);
5896d037 1275 $result = $this->callAPISuccess('contact', 'get', array(
92915c55
TO
1276 'birth_date_low' => date('Y-m-d', strtotime('-6 years')),
1277 'birth_date_high' => date('Y-m-d', strtotime('- 3 years')),
1278 ));
b1f09bea
E
1279 $this->assertEquals(1, $result['count']);
1280 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -5 years')), $result['values'][$contact2['id']]['birth_date']);
5896d037 1281 $result = $this->callAPISuccess('contact', 'get', array(
92915c55
TO
1282 'birth_date_low' => '-6 years',
1283 'birth_date_high' => '- 3 years',
1284 ));
9f60788a
EM
1285 $this->assertEquals(1, $result['count']);
1286 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -5 years')), $result['values'][$contact2['id']]['birth_date']);
b1f09bea
E
1287 }
1288
1289 /**
381fa321 1290 * Test Deceased date params incl value, array & Deceased_date_high, Deceased date_low
1291 * && deceased.
b1f09bea 1292 */
4b58ed3b 1293 public function testContactGetDeceasedDate() {
b1f09bea
E
1294 $contact1 = $this->callAPISuccess('contact', 'create', array_merge($this->_params, array('deceased_date' => 'first day of next month - 2 years')));
1295 $contact2 = $this->callAPISuccess('contact', 'create', array_merge($this->_params, array('deceased_date' => 'first day of next month - 5 years')));
1296 $contact3 = $this->callAPISuccess('contact', 'create', array_merge($this->_params, array('deceased_date' => 'first day of next month -20 years')));
1297
1298 $result = $this->callAPISuccess('contact', 'get', array());
1299 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -2 years')), $result['values'][$contact1['id']]['deceased_date']);
1300 $result = $this->callAPISuccess('contact', 'get', array('deceased_date' => 'first day of next month -5 years'));
1301 $this->assertEquals(1, $result['count']);
1302 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -5 years')), $result['values'][$contact2['id']]['deceased_date']);
1303 $result = $this->callAPISuccess('contact', 'get', array('deceased_date_high' => date('Y-m-d', strtotime('-6 years'))));
1304 $this->assertEquals(1, $result['count']);
1305 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -20 years')), $result['values'][$contact3['id']]['deceased_date']);
5896d037 1306 $result = $this->callAPISuccess('contact', 'get', array(
92915c55
TO
1307 'deceased_date_low' => '-6 years',
1308 'deceased_date_high' => date('Y-m-d', strtotime('- 3 years')),
1309 ));
b1f09bea
E
1310 $this->assertEquals(1, $result['count']);
1311 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -5 years')), $result['values'][$contact2['id']]['deceased_date']);
1312 }
1313
e635f9d4
TO
1314 /**
1315 * Test for Contact.get id=@user:username
1316 */
00be9182 1317 public function testContactGetByUsername() {
e635f9d4
TO
1318 // setup - create contact with a uf-match
1319 $cid = $this->individualCreate(array(
1320 'contact_type' => 'Individual',
1321 'first_name' => 'testGetByUsername',
1322 'last_name' => 'testGetByUsername',
1323 ));
1324
1325 $ufMatchParams = array(
1326 'domain_id' => CRM_Core_Config::domainID(),
1327 'uf_id' => 99,
1328 'uf_name' => 'the-email-matching-key-is-not-really-the-username',
1329 'contact_id' => $cid,
1330 );
1331 $ufMatch = CRM_Core_BAO_UFMatch::create($ufMatchParams);
1332 $this->assertTrue(is_numeric($ufMatch->id));
1333
1334 // setup - mock the calls to CRM_Utils_System_*::getUfId
1335 $userSystem = $this->getMock('CRM_Utils_System_UnitTests', array('getUfId'));
1336 $userSystem->expects($this->once())
1337 ->method('getUfId')
1338 ->with($this->equalTo('exampleUser'))
1339 ->will($this->returnValue(99));
1340 CRM_Core_Config::singleton()->userSystem = $userSystem;
1341
1342 // perform a lookup
1343 $result = $this->callAPISuccess('Contact', 'get', array(
e635f9d4
TO
1344 'id' => '@user:exampleUser',
1345 ));
1346 $this->assertEquals('testGetByUsername', $result['values'][$cid]['first_name']);
1347 }
1348
265cc07d 1349 /**
1350 * Test to check return works OK
1351 */
00be9182 1352 public function testContactGetReturnValues() {
265cc07d 1353 $extraParams = array('nick_name' => 'Bob', 'phone' => '456', 'email' => 'e@mail.com');
1354 $contactID = $this->individualCreate($extraParams);
1355 //actually it turns out the above doesn't create a phone
6c6e6187 1356 $this->callAPISuccess('phone', 'create', array('contact_id' => $contactID, 'phone' => '456'));
265cc07d 1357 $result = $this->callAPISuccess('contact', 'getsingle', array('id' => $contactID));
1358 foreach ($extraParams as $key => $value) {
1359 $this->assertEquals($result[$key], $value);
1360 }
1361 //now we check they are still returned with 'return' key
5896d037 1362 $result = $this->callAPISuccess('contact', 'getsingle', array(
92915c55
TO
1363 'id' => $contactID,
1364 'return' => array_keys($extraParams),
1365 ));
265cc07d 1366 foreach ($extraParams as $key => $value) {
1367 $this->assertEquals($result[$key], $value);
1368 }
1369 }
1370
00be9182 1371 public function testCRM13252MultipleChainedPhones() {
265cc07d 1372 $contactID = $this->householdCreate();
1373 $this->callAPISuccessGetCount('phone', array('contact_id' => $contactID), 0);
1374 $params = array(
5896d037
TO
1375 'contact_id' => $contactID,
1376 'household_name' => 'Household 1',
1377 'contact_type' => 'Household',
1378 'api.phone.create' => array(
265cc07d 1379 0 => array(
1380 'phone' => '111-111-1111',
1381 'location_type_id' => 1,
1382 'phone_type_id' => 1,
1383 ),
1384 1 => array(
1385 'phone' => '222-222-2222',
1386 'location_type_id' => 1,
1387 'phone_type_id' => 2,
21dfd5f5
TO
1388 ),
1389 ),
265cc07d 1390 );
4b58ed3b 1391 $this->callAPISuccess('contact', 'create', $params);
265cc07d 1392 $this->callAPISuccessGetCount('phone', array('contact_id' => $contactID), 2);
1393
1394 }
5896d037 1395
e635f9d4
TO
1396 /**
1397 * Test for Contact.get id=@user:username (with an invalid username)
1398 */
00be9182 1399 public function testContactGetByUnknownUsername() {
e635f9d4
TO
1400 // setup - mock the calls to CRM_Utils_System_*::getUfId
1401 $userSystem = $this->getMock('CRM_Utils_System_UnitTests', array('getUfId'));
1402 $userSystem->expects($this->once())
1403 ->method('getUfId')
1404 ->with($this->equalTo('exampleUser'))
1405 ->will($this->returnValue(NULL));
1406 CRM_Core_Config::singleton()->userSystem = $userSystem;
1407
1408 // perform a lookup
1409 $result = $this->callAPIFailure('Contact', 'get', array(
e635f9d4
TO
1410 'id' => '@user:exampleUser',
1411 ));
1412 $this->assertRegExp('/cannot be resolved to a contact ID/', $result['error_message']);
1413 }
1414
6a488035 1415 /**
381fa321 1416 * Verify attempt to create individual with chained arrays
6a488035 1417 */
00be9182 1418 public function testGetIndividualWithChainedArrays() {
6a488035
TO
1419 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__, __FILE__);
1420 $params['custom_' . $ids['custom_field_id']] = "custom string";
1421
381fa321 1422 $moreIDs = $this->CustomGroupMultipleCreateWithFields();
6a488035 1423 $description = "/*this demonstrates the usage of chained api functions. In this case no notes or custom fields have been created ";
5896d037
TO
1424 $subfile = "APIChainedArray";
1425 $params = array(
6a488035
TO
1426 'first_name' => 'abc3',
1427 'last_name' => 'xyz3',
1428 'contact_type' => 'Individual',
1429 'email' => 'man3@yahoo.com',
6a488035
TO
1430 'api.contribution.create' => array(
1431 'receive_date' => '2010-01-01',
1432 'total_amount' => 100.00,
1433 'financial_type_id' => 1,
1434 'payment_instrument_id' => 1,
1435 'non_deductible_amount' => 10.00,
1436 'fee_amount' => 50.00,
1437 'net_amount' => 90.00,
1438 'trxn_id' => 12345,
1439 'invoice_id' => 67890,
1440 'source' => 'SSF',
1441 'contribution_status_id' => 1,
1442 ),
1443 'api.contribution.create.1' => array(
1444 'receive_date' => '2011-01-01',
1445 'total_amount' => 120.00,
6c6e6187 1446 'financial_type_id' => $this->_financialTypeId = 1,
6a488035
TO
1447 'payment_instrument_id' => 1,
1448 'non_deductible_amount' => 10.00,
1449 'fee_amount' => 50.00,
1450 'net_amount' => 90.00,
1451 'trxn_id' => 12335,
1452 'invoice_id' => 67830,
1453 'source' => 'SSF',
1454 'contribution_status_id' => 1,
1455 ),
1456 'api.website.create' => array(
1457 array(
1458 'url' => "http://civicrm.org",
1459 ),
1460 ),
1461 );
1462
f6722559 1463 $result = $this->callAPISuccess('Contact', 'create', $params);
6a488035 1464 $params = array(
f6722559 1465 'id' => $result['id'],
6a488035
TO
1466 'api.website.get' => array(),
1467 'api.Contribution.get' => array(
1468 'total_amount' => '120.00',
5896d037
TO
1469 ),
1470 'api.CustomValue.get' => 1,
6a488035
TO
1471 'api.Note.get' => 1,
1472 );
f6722559 1473 $result = $this->callAPIAndDocument('Contact', 'Get', $params, __FUNCTION__, __FILE__, $description, $subfile);
6a488035 1474 // delete the contact
f6722559 1475 $this->callAPISuccess('contact', 'delete', $result);
6a488035 1476 $this->customGroupDelete($ids['custom_group_id']);
381fa321 1477 $this->customGroupDelete($moreIDs['custom_group_id']);
4b58ed3b
EM
1478 $this->assertEquals(1, $result['id']);
1479 $this->assertEquals(0, $result['values'][$result['id']]['api.website.get']['is_error']);
1480 $this->assertEquals("http://civicrm.org", $result['values'][$result['id']]['api.website.get']['values'][0]['url']);
6a488035
TO
1481 }
1482
00be9182 1483 public function testGetIndividualWithChainedArraysFormats() {
6a488035
TO
1484 $description = "/*this demonstrates the usage of chained api functions. A variety of return formats are used. Note that no notes
1485 *custom fields or memberships exist";
1486 $subfile = "APIChainedArrayFormats";
1487 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__, __FILE__);
1488 $params['custom_' . $ids['custom_field_id']] = "custom string";
1489
381fa321 1490 $moreIDs = $this->CustomGroupMultipleCreateWithFields();
6a488035
TO
1491 $params = array(
1492 'first_name' => 'abc3',
1493 'last_name' => 'xyz3',
1494 'contact_type' => 'Individual',
1495 'email' => 'man3@yahoo.com',
6a488035
TO
1496 'api.contribution.create' => array(
1497 'receive_date' => '2010-01-01',
1498 'total_amount' => 100.00,
f6722559 1499 'financial_type_id' => $this->_financialTypeId,
6a488035
TO
1500 'payment_instrument_id' => 1,
1501 'non_deductible_amount' => 10.00,
1502 'fee_amount' => 50.00,
1503 'net_amount' => 90.00,
1504 'source' => 'SSF',
1505 'contribution_status_id' => 1,
1506 ),
1507 'api.contribution.create.1' => array(
1508 'receive_date' => '2011-01-01',
1509 'total_amount' => 120.00,
f6722559 1510 'financial_type_id' => $this->_financialTypeId,
6a488035
TO
1511 'payment_instrument_id' => 1,
1512 'non_deductible_amount' => 10.00,
1513 'fee_amount' => 50.00,
1514 'net_amount' => 90.00,
1515 'source' => 'SSF',
1516 'contribution_status_id' => 1,
1517 ),
1518 'api.website.create' => array(
1519 array(
1520 'url' => "http://civicrm.org",
1521 ),
1522 ),
1523 );
1524
f6722559 1525 $result = $this->callAPISuccess('Contact', 'create', $params);
6a488035 1526 $params = array(
f6722559 1527 'id' => $result['id'],
6a488035
TO
1528 'api.website.getValue' => array('return' => 'url'),
1529 'api.Contribution.getCount' => array(),
1530 'api.CustomValue.get' => 1,
1531 'api.Note.get' => 1,
1532 'api.Membership.getCount' => array(),
1533 );
f6722559 1534 $result = $this->callAPIAndDocument('Contact', 'Get', $params, __FUNCTION__, __FILE__, $description, $subfile);
4b58ed3b
EM
1535 $this->assertEquals(1, $result['id']);
1536 $this->assertEquals(2, $result['values'][$result['id']]['api.Contribution.getCount']);
1537 $this->assertEquals(0, $result['values'][$result['id']]['api.Note.get']['is_error']);
1538 $this->assertEquals("http://civicrm.org", $result['values'][$result['id']]['api.website.getValue']);
6a488035 1539
f6722559 1540 $this->callAPISuccess('contact', 'delete', $result);
6a488035 1541 $this->customGroupDelete($ids['custom_group_id']);
381fa321 1542 $this->customGroupDelete($moreIDs['custom_group_id']);
6a488035
TO
1543 }
1544
381fa321 1545 /**
1546 * Test complex chaining.
1547 */
00be9182 1548 public function testGetIndividualWithChainedArraysAndMultipleCustom() {
6a488035
TO
1549 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__, __FILE__);
1550 $params['custom_' . $ids['custom_field_id']] = "custom string";
381fa321 1551 $moreIDs = $this->CustomGroupMultipleCreateWithFields();
1552 $andMoreIDs = $this->CustomGroupMultipleCreateWithFields(array(
92915c55
TO
1553 'title' => "another group",
1554 'name' => 'another name',
1555 ));
6a488035
TO
1556 $description = "/*this demonstrates the usage of chained api functions. A variety of techniques are used";
1557 $subfile = "APIChainedArrayMultipleCustom";
1558 $params = array(
1559 'first_name' => 'abc3',
1560 'last_name' => 'xyz3',
1561 'contact_type' => 'Individual',
1562 'email' => 'man3@yahoo.com',
6a488035
TO
1563 'api.contribution.create' => array(
1564 'receive_date' => '2010-01-01',
1565 'total_amount' => 100.00,
5896d037 1566 'financial_type_id' => 1,
6a488035
TO
1567 'payment_instrument_id' => 1,
1568 'non_deductible_amount' => 10.00,
1569 'fee_amount' => 50.00,
1570 'net_amount' => 90.00,
1571 'trxn_id' => 12345,
1572 'invoice_id' => 67890,
1573 'source' => 'SSF',
1574 'contribution_status_id' => 1,
1575 ),
1576 'api.contribution.create.1' => array(
1577 'receive_date' => '2011-01-01',
1578 'total_amount' => 120.00,
5896d037 1579 'financial_type_id' => 1,
6a488035
TO
1580 'payment_instrument_id' => 1,
1581 'non_deductible_amount' => 10.00,
1582 'fee_amount' => 50.00,
1583 'net_amount' => 90.00,
1584 'trxn_id' => 12335,
1585 'invoice_id' => 67830,
1586 'source' => 'SSF',
1587 'contribution_status_id' => 1,
1588 ),
1589 'api.website.create' => array(
1590 array(
1591 'url' => "http://civicrm.org",
1592 ),
1593 ),
1594 'custom_' . $ids['custom_field_id'] => "value 1",
381fa321 1595 'custom_' . $moreIDs['custom_field_id'][0] => "value 2",
1596 'custom_' . $moreIDs['custom_field_id'][1] => "warm beer",
1597 'custom_' . $andMoreIDs['custom_field_id'][1] => "vegemite",
6a488035
TO
1598 );
1599
f6722559 1600 $result = $this->callAPISuccess('Contact', 'create', $params);
1601 $result = $this->callAPISuccess('Contact', 'create', array(
6c6e6187 1602 'contact_type' => 'Individual',
5896d037
TO
1603 'id' => $result['id'],
1604 'custom_' .
381fa321 1605 $moreIDs['custom_field_id'][0] => "value 3",
5896d037
TO
1606 'custom_' .
1607 $ids['custom_field_id'] => "value 4",
1608 ));
6a488035
TO
1609
1610 $params = array(
f6722559 1611 'id' => $result['id'],
6a488035
TO
1612 'api.website.getValue' => array('return' => 'url'),
1613 'api.Contribution.getCount' => array(),
1614 'api.CustomValue.get' => 1,
1615 );
f6722559 1616 $result = $this->callAPIAndDocument('Contact', 'Get', $params, __FUNCTION__, __FILE__, $description, $subfile);
1617
6a488035 1618 $this->customGroupDelete($ids['custom_group_id']);
381fa321 1619 $this->customGroupDelete($moreIDs['custom_group_id']);
1620 $this->customGroupDelete($andMoreIDs['custom_group_id']);
4b58ed3b
EM
1621 $this->assertEquals(1, $result['id']);
1622 $this->assertEquals(0, $result['values'][$result['id']]['api.CustomValue.get']['is_error']);
1623 $this->assertEquals('http://civicrm.org', $result['values'][$result['id']]['api.website.getValue']);
6a488035 1624 }
5896d037 1625
d424ffde 1626 /**
381fa321 1627 * Test checks usage of $values to pick & choose inputs.
6a488035 1628 */
00be9182 1629 public function testChainingValuesCreate() {
6a488035
TO
1630 $description = "/*this demonstrates the usage of chained api functions. Specifically it has one 'parent function' &
1631 2 child functions - one receives values from the parent (Contact) and the other child (Tag). ";
1632 $subfile = "APIChainedArrayValuesFromSiblingFunction";
1633 $params = array(
6c6e6187 1634 'display_name' => 'batman',
5896d037 1635 'contact_type' => 'Individual',
6a488035
TO
1636 'api.tag.create' => array('name' => '$value.id', 'description' => '$value.display_name', 'format.only_id' => 1),
1637 'api.entity_tag.create' => array('tag_id' => '$value.api.tag.create'),
1638 );
f6722559 1639 $result = $this->callAPIAndDocument('Contact', 'Create', $params, __FUNCTION__, __FILE__, $description, $subfile);
6a488035 1640 $this->assertEquals(0, $result['values'][$result['id']]['api.entity_tag.create']['is_error']);
f6722559 1641
6a488035
TO
1642 $tablesToTruncate = array(
1643 'civicrm_contact',
1644 'civicrm_activity',
1645 'civicrm_entity_tag',
1646 'civicrm_tag',
1647 );
1648 $this->quickCleanup($tablesToTruncate, TRUE);
1649 }
1650
d424ffde 1651 /**
381fa321 1652 * Test TrueFalse format - I couldn't come up with an easy way to get an error on Get
6a488035 1653 */
00be9182 1654 public function testContactGetFormatIsSuccessTrue() {
6a488035
TO
1655 $this->createContactFromXML();
1656 $description = "This demonstrates use of the 'format.is_success' param.
1657 This param causes only the success or otherwise of the function to be returned as BOOLEAN";
1658 $subfile = "FormatIsSuccess_True";
5896d037
TO
1659 $params = array('id' => 17, 'format.is_success' => 1);
1660 $result = $this->callAPIAndDocument('Contact', 'Get', $params, __FUNCTION__, __FILE__, $description, $subfile);
6a488035 1661 $this->assertEquals(1, $result);
f6722559 1662 $this->callAPISuccess('Contact', 'Delete', $params);
6a488035 1663 }
5896d037 1664
d424ffde 1665 /**
6a488035
TO
1666 * test TrueFalse format
1667 */
00be9182 1668 public function testContactCreateFormatIsSuccessFalse() {
6a488035
TO
1669
1670 $description = "This demonstrates use of the 'format.is_success' param.
1671 This param causes only the success or otherwise of the function to be returned as BOOLEAN";
1672 $subfile = "FormatIsSuccess_Fail";
5896d037
TO
1673 $params = array('id' => 500, 'format.is_success' => 1);
1674 $result = $this->callAPIAndDocument('Contact', 'Create', $params, __FUNCTION__, __FILE__, $description, $subfile);
6a488035
TO
1675 $this->assertEquals(0, $result);
1676 }
5896d037 1677
d424ffde 1678 /**
6a488035
TO
1679 * test Single Entity format
1680 */
00be9182 1681 public function testContactGetSingle_entity_array() {
6a488035
TO
1682 $this->createContactFromXML();
1683 $description = "This demonstrates use of the 'format.single_entity_array' param.
1684 /* This param causes the only contact to be returned as an array without the other levels.
1685 /* it will be ignored if there is not exactly 1 result";
1686 $subfile = "GetSingleContact";
5896d037
TO
1687 $params = array('id' => 17);
1688 $result = $this->callAPIAndDocument('Contact', 'GetSingle', $params, __FUNCTION__, __FILE__, $description, $subfile);
4b58ed3b 1689 $this->assertEquals('Test Contact', $result['display_name']);
f6722559 1690 $this->callAPISuccess('Contact', 'Delete', $params);
6a488035
TO
1691 }
1692
d424ffde 1693 /**
381fa321 1694 * Test Single Entity format.
6a488035 1695 */
381fa321 1696 public function testContactGetFormatCount_only() {
6a488035 1697 $this->createContactFromXML();
381fa321 1698 $description = "This demonstrates use of the 'getCount' action.\n"
1699 . " *\n"
1700 . " * This param causes the count of the only function to be returned as an integer.";
6a488035 1701 $subfile = "GetCountContact";
5896d037 1702 $params = array('id' => 17);
381fa321 1703 $result = $this->callAPIAndDocument('Contact', 'GetCount', $params, __FUNCTION__, __FILE__, $description,
1704 $subfile, 'getcount');
4b58ed3b 1705 $this->assertEquals('1', $result);
f6722559 1706 $this->callAPISuccess('Contact', 'Delete', $params);
6a488035 1707 }
5896d037 1708
d424ffde 1709 /**
381fa321 1710 * Test id only format.
408b79bf 1711 */
00be9182 1712 public function testContactGetFormatID_only() {
6a488035
TO
1713 $this->createContactFromXML();
1714 $description = "This demonstrates use of the 'format.id_only' param.
1715 /* This param causes the id of the only entity to be returned as an integer.
1716 /* it will be ignored if there is not exactly 1 result";
1717 $subfile = "FormatOnlyID";
5896d037
TO
1718 $params = array('id' => 17, 'format.only_id' => 1);
1719 $result = $this->callAPIAndDocument('Contact', 'Get', $params, __FUNCTION__, __FILE__, $description, $subfile);
4b58ed3b 1720 $this->assertEquals('17', $result);
f6722559 1721 $this->callAPISuccess('Contact', 'Delete', $params);
6a488035
TO
1722 }
1723
d424ffde 1724 /**
381fa321 1725 * Test id only format.
408b79bf 1726 */
00be9182 1727 public function testContactGetFormatSingleValue() {
6a488035
TO
1728 $this->createContactFromXML();
1729 $description = "This demonstrates use of the 'format.single_value' param.
1730 /* This param causes only a single value of the only entity to be returned as an string.
1731 /* it will be ignored if there is not exactly 1 result";
4b58ed3b 1732 $subFile = "FormatSingleValue";
5896d037
TO
1733 $params = array('id' => 17, 'return' => 'display_name');
1734 $result = $this->callAPIAndDocument('Contact', 'getvalue', $params, __FUNCTION__, __FILE__, $description, $subFile, 'getvalue');
4b58ed3b 1735 $this->assertEquals('Test Contact', $result);
f6722559 1736 $this->callAPISuccess('Contact', 'Delete', $params);
6a488035
TO
1737 }
1738
b2130237 1739 /**
381fa321 1740 * Test that permissions are respected when creating contacts.
b2130237 1741 */
00be9182 1742 public function testContactCreationPermissions() {
6a488035 1743 $params = array(
6c6e6187 1744 'contact_type' => 'Individual',
5896d037 1745 'first_name' => 'Foo',
6a488035
TO
1746 'last_name' => 'Bear',
1747 'check_permissions' => TRUE,
6a488035
TO
1748 );
1749 $config = CRM_Core_Config::singleton();
1750 $config->userPermissionClass->permissions = array('access CiviCRM');
d0e1eff2 1751 $result = $this->callAPIFailure('contact', 'create', $params);
60ec9f43 1752 $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
1753
1754 $config->userPermissionClass->permissions = array('access CiviCRM', 'add contacts', 'import contacts');
dcbec360 1755 $this->callAPISuccess('contact', 'create', $params, NULL, 'overfluous permissions should be enough to create a contact');
6a488035
TO
1756 }
1757
381fa321 1758 /**
1759 * Test update with check permissions set.
1760 */
00be9182 1761 public function testContactUpdatePermissions() {
5896d037
TO
1762 $params = array(
1763 'contact_type' => 'Individual',
1764 'first_name' => 'Foo',
1765 'last_name' => 'Bear',
21dfd5f5 1766 'check_permissions' => TRUE,
5896d037 1767 );
f6722559 1768 $result = $this->callAPISuccess('contact', 'create', $params);
6a488035 1769 $config = CRM_Core_Config::singleton();
5896d037
TO
1770 $params = array(
1771 'id' => $result['id'],
1772 'contact_type' => 'Individual',
1773 'last_name' => 'Bar',
21dfd5f5 1774 'check_permissions' => TRUE,
5896d037 1775 );
6a488035
TO
1776
1777 $config->userPermissionClass->permissions = array('access CiviCRM');
d0e1eff2 1778 $result = $this->callAPIFailure('contact', 'update', $params);
60ec9f43 1779 $this->assertEquals('API permission check failed for contact/update call; insufficient permission: require access CiviCRM and edit all contacts', $result['error_message'], 'lacking permissions should not be enough to update a contact');
6a488035 1780
5896d037
TO
1781 $config->userPermissionClass->permissions = array(
1782 'access CiviCRM',
1783 'add contacts',
1784 'view all contacts',
1785 'edit all contacts',
21dfd5f5 1786 'import contacts',
5896d037 1787 );
dcbec360 1788 $this->callAPISuccess('contact', 'update', $params, NULL, 'overfluous permissions should be enough to update a contact');
6a488035
TO
1789 }
1790
381fa321 1791 /**
1792 * Set up helper to create a contact.
1793 */
00be9182 1794 public function createContactFromXML() {
381fa321 1795 // Insert a row in civicrm_contact creating contact 17.
6a488035
TO
1796 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1797 $op->execute($this->_dbconn,
bbfd46a5 1798 $this->createXMLDataSet(
6a488035
TO
1799 dirname(__FILE__) . '/dataset/contact_17.xml'
1800 )
1801 );
1802 }
1803
381fa321 1804 /**
1805 * Test contact proximity api.
1806 */
00be9182 1807 public function testContactProximity() {
6a488035
TO
1808 // first create a contact with a SF location with a specific
1809 // geocode
1810 $contactID = $this->organizationCreate();
1811
1812 // now create the address
1813 $params = array(
1814 'street_address' => '123 Main Street',
1815 'city' => 'San Francisco',
1816 'is_primary' => 1,
1817 'country_id' => 1228,
1818 'state_province_id' => 1004,
1819 'geo_code_1' => '37.79',
1820 'geo_code_2' => '-122.40',
1821 'location_type_id' => 1,
1822 'contact_id' => $contactID,
6a488035
TO
1823 );
1824
f6722559 1825 $result = $this->callAPISuccess('address', 'create', $params);
6a488035
TO
1826 $this->assertEquals(1, $result['count'], 'In line ' . __LINE__);
1827
1828 // now do a proximity search with a close enough geocode and hope to match
1829 // that specific contact only!
1830 $proxParams = array(
1831 'latitude' => 37.7,
1832 'longitude' => -122.3,
1833 'unit' => 'mile',
1834 'distance' => 10,
6a488035 1835 );
f6722559 1836 $result = $this->callAPISuccess('contact', 'proximity', $proxParams);
6a488035
TO
1837 $this->assertEquals(1, $result['count'], 'In line ' . __LINE__);
1838 }
60ec9f43
E
1839
1840 /**
381fa321 1841 * Test that Ajax API permission is sufficient to access getquick api.
1842 *
1d6020f1 1843 * (note that getquick api is required for autocomplete & has ACL permissions applied)
60ec9f43 1844 */
00be9182 1845 public function testGetquickPermission_CRM_13744() {
60ec9f43 1846 CRM_Core_Config::singleton()->userPermissionClass->permissions = array('access CiviEvent');
4b58ed3b 1847 $this->callAPIFailure('contact', 'getquick', array('name' => 'b', 'check_permissions' => TRUE));
60ec9f43 1848 CRM_Core_Config::singleton()->userPermissionClass->permissions = array('access CiviCRM');
4b58ed3b 1849 $this->callAPISuccess('contact', 'getquick', array('name' => 'b', 'check_permissions' => TRUE));
60ec9f43 1850 CRM_Core_Config::singleton()->userPermissionClass->permissions = array('access AJAX API');
4b58ed3b 1851 $this->callAPISuccess('contact', 'getquick', array('name' => 'b', 'check_permissions' => TRUE));
60ec9f43 1852 }
9c8096cb 1853
b2130237 1854 /**
381fa321 1855 * Test get ref api - gets a list of references to an entity.
b2130237 1856 */
00be9182 1857 public function testGetReferenceCounts() {
9c8096cb
TO
1858 $result = $this->callAPISuccess('Contact', 'create', array(
1859 'first_name' => 'Testily',
1860 'last_name' => 'McHaste',
1861 'contact_type' => 'Individual',
1862 'api.Address.replace' => array(
1863 'values' => array(),
1864 ),
1865 'api.Email.replace' => array(
1866 'values' => array(
1867 array(
1868 'email' => 'spam@dev.null',
1869 'is_primary' => 0,
1870 'location_type_id' => 1,
21dfd5f5 1871 ),
9c8096cb
TO
1872 ),
1873 ),
1874 'api.Phone.replace' => array(
1875 'values' => array(
1876 array(
1877 'phone' => '234-567-0001',
1878 'is_primary' => 1,
1879 'location_type_id' => 1,
1880 ),
1881 array(
1882 'phone' => '234-567-0002',
1883 'is_primary' => 0,
1884 'location_type_id' => 1,
1885 ),
1886 ),
1887 ),
1888 ));
1889
1890 //$dao = new CRM_Contact_BAO_Contact();
1891 //$dao->id = $result['id'];
1892 //$this->assertTrue((bool) $dao->find(TRUE));
1893 //
1894 //$refCounts = $dao->getReferenceCounts();
1895 //$this->assertTrue(is_array($refCounts));
1896 //$refCountsIdx = CRM_Utils_Array::index(array('name'), $refCounts);
1897
1898 $refCounts = $this->callAPISuccess('Contact', 'getrefcount', array(
21dfd5f5 1899 'id' => $result['id'],
9c8096cb
TO
1900 ));
1901 $refCountsIdx = CRM_Utils_Array::index(array('name'), $refCounts['values']);
1902
1903 $this->assertEquals(1, $refCountsIdx['sql:civicrm_email:contact_id']['count']);
1904 $this->assertEquals('civicrm_email', $refCountsIdx['sql:civicrm_email:contact_id']['table']);
1905 $this->assertEquals(2, $refCountsIdx['sql:civicrm_phone:contact_id']['count']);
1906 $this->assertEquals('civicrm_phone', $refCountsIdx['sql:civicrm_phone:contact_id']['table']);
1907 $this->assertTrue(!isset($refCountsIdx['sql:civicrm_address:contact_id']));
1908 }
1909
00be9182 1910 public function testSQLOperatorsOnContactAPI() {
a75c13cc
EM
1911 $this->individualCreate();
1912 $this->organizationCreate();
1913 $this->householdCreate();
1914 $contacts = $this->callAPISuccess('contact', 'get', array('legal_name' => array('IS NOT NULL' => TRUE)));
1915 $this->assertEquals($contacts['count'], CRM_Core_DAO::singleValueQuery('select count(*) FROM civicrm_contact WHERE legal_name IS NOT NULL'));
1916 $contacts = $this->callAPISuccess('contact', 'get', array('legal_name' => array('IS NULL' => TRUE)));
1917 $this->assertEquals($contacts['count'], CRM_Core_DAO::singleValueQuery('select count(*) FROM civicrm_contact WHERE legal_name IS NULL'));
1918 }
9bee5ea2 1919
9bee5ea2
EM
1920 /**
1921 * CRM-14743 - test api respects search operators
1922 */
00be9182 1923 public function testGetModifiedDateByOperators() {
9bee5ea2
EM
1924 $preExistingContactCount = CRM_Core_DAO::singleValueQuery('select count(*) FROM civicrm_contact');
1925 $contact1 = $this->individualCreate();
1926 $sql = "UPDATE civicrm_contact SET created_date = '2012-01-01', modified_date = '2013-01-01' WHERE id = " . $contact1;
1927 CRM_Core_DAO::executeQuery($sql);
1928 $contact2 = $this->individualCreate();
1929 $sql = "UPDATE civicrm_contact SET created_date = '2012-02-01', modified_date = '2013-02-01' WHERE id = " . $contact2;
1930 CRM_Core_DAO::executeQuery($sql);
1931 $contact3 = $this->householdCreate();
1932 $sql = "UPDATE civicrm_contact SET created_date = '2012-03-01', modified_date = '2013-03-01' WHERE id = " . $contact3;
1933 CRM_Core_DAO::executeQuery($sql);
1934 $contacts = $this->callAPISuccess('contact', 'get', array('modified_date' => array('<' => '2014-01-01')));
1935 $this->assertEquals($contacts['count'], 3);
1936 $contacts = $this->callAPISuccess('contact', 'get', array('modified_date' => array('>' => '2014-01-01')));
1937 $this->assertEquals($contacts['count'], $preExistingContactCount);
1938 }
2134e310 1939
2134e310
EM
1940 /**
1941 * CRM-14743 - test api respects search operators
1942 */
00be9182 1943 public function testGetCreatedDateByOperators() {
2134e310
EM
1944 $preExistingContactCount = CRM_Core_DAO::singleValueQuery('select count(*) FROM civicrm_contact');
1945 $contact1 = $this->individualCreate();
1946 $sql = "UPDATE civicrm_contact SET created_date = '2012-01-01' WHERE id = " . $contact1;
1947 CRM_Core_DAO::executeQuery($sql);
1948 $contact2 = $this->individualCreate();
1949 $sql = "UPDATE civicrm_contact SET created_date = '2012-02-01' WHERE id = " . $contact2;
1950 CRM_Core_DAO::executeQuery($sql);
1951 $contact3 = $this->householdCreate();
1952 $sql = "UPDATE civicrm_contact SET created_date = '2012-03-01' WHERE id = " . $contact3;
1953 CRM_Core_DAO::executeQuery($sql);
1954 $contacts = $this->callAPISuccess('contact', 'get', array('created_date' => array('<' => '2014-01-01')));
1955 $this->assertEquals($contacts['count'], 3);
1956 $contacts = $this->callAPISuccess('contact', 'get', array('created_date' => array('>' => '2014-01-01')));
1957 $this->assertEquals($contacts['count'], $preExistingContactCount);
1958 }
e5fccefb
EM
1959
1960 /**
1961 * CRM-14263 check that API is not affected by search profile related bug
1962 */
5896d037 1963 public function testReturnCityProfile() {
e5fccefb
EM
1964 $contactID = $this->individualCreate();
1965 CRM_Core_Config::singleton()->defaultSearchProfileID = 1;
5896d037 1966 $this->callAPISuccess('address', 'create', array(
92915c55
TO
1967 'contact_id' => $contactID,
1968 'city' => 'Cool City',
1969 'location_type_id' => 1,
1970 ));
e5fccefb
EM
1971 $result = $this->callAPISuccess('contact', 'get', array('city' => 'Cool City', 'return' => 'contact_type'));
1972 $this->assertEquals(1, $result['count']);
1973 }
eaa112a5 1974
eaa112a5 1975 /**
45fcf8b7 1976 * CRM-15443 - ensure getlist api does not return deleted contacts
eaa112a5 1977 */
00be9182 1978 public function testGetlistExcludeConditions() {
eaa112a5 1979 $name = md5(time());
45fcf8b7 1980 $contact = $this->individualCreate(array('last_name' => $name));
381fa321 1981 $this->individualCreate(array('last_name' => $name, 'is_deceased' => 1));
1982 $this->individualCreate(array('last_name' => $name, 'is_deleted' => 1));
1983 // We should get all but the deleted contact.
eaa112a5 1984 $result = $this->callAPISuccess('contact', 'getlist', array('input' => $name));
45fcf8b7 1985 $this->assertEquals(2, $result['count'], 'In line ' . __LINE__);
381fa321 1986 // Force-exclude the deceased contact.
5896d037 1987 $result = $this->callAPISuccess('contact', 'getlist', array(
92915c55
TO
1988 'input' => $name,
1989 'params' => array('is_deceased' => 0),
1990 ));
eaa112a5 1991 $this->assertEquals(1, $result['count'], 'In line ' . __LINE__);
45fcf8b7 1992 $this->assertEquals($contact, $result['values'][0]['id'], 'In line ' . __LINE__);
eaa112a5 1993 }
92776611
CW
1994
1995 /**
1996 * Test contact.getactions
1997 */
00be9182 1998 public function testGetActions() {
92776611
CW
1999 $description = "Getting the available actions for an entity.";
2000 $result = $this->callAPIAndDocument($this->_entity, 'getactions', array(), __FUNCTION__, __FILE__, $description);
2001 $expected = array(
2002 'create',
2003 'delete',
2004 'get',
2005 'getactions',
2006 'getcount',
2007 'getfields',
2008 'getlist',
2009 'getoptions',
2010 'getquick',
2011 'getrefcount',
2012 'getsingle',
2013 'getvalue',
2014 'merge',
2015 'proximity',
2016 'replace',
2017 'setvalue',
2018 'update',
2019 );
2020 $deprecated = array(
2021 'update',
2022 'getquick',
2023 );
2024 foreach ($expected as $action) {
2025 $this->assertTrue(in_array($action, $result['values']), "Expected action $action");
2026 }
2027 foreach ($deprecated as $action) {
2028 $this->assertArrayKeyExists($action, $result['deprecated']);
2029 }
2030 }
96025800 2031
6a488035 2032}