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