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