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