CRM-13072 upgrade Mailing Job test & api to pass
[civicrm-core.git] / tests / phpunit / api / v3 / SyntaxConformanceTest.php
1 <?php
2 /*
3 +--------------------------------------------------------------------+
4 | CiviCRM version 4.3 |
5 +--------------------------------------------------------------------+
6 | Copyright CiviCRM LLC (c) 2004-2013 |
7 +--------------------------------------------------------------------+
8 | This file is a part of CiviCRM. |
9 | |
10 | CiviCRM is free software; you can copy, modify, and distribute it |
11 | under the terms of the GNU Affero General Public License |
12 | Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
13 | |
14 | CiviCRM is distributed in the hope that it will be useful, but |
15 | WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
17 | See the GNU Affero General Public License for more details. |
18 | |
19 | You should have received a copy of the GNU Affero General Public |
20 | License and the CiviCRM Licensing Exception along |
21 | with this program; if not, contact CiviCRM LLC |
22 | at info[AT]civicrm[DOT]org. If you have questions about the |
23 | GNU Affero General Public License or the licensing of CiviCRM, |
24 | see the CiviCRM license FAQ at http://civicrm.org/licensing |
25 +--------------------------------------------------------------------+
26 */
27
28 require_once 'CiviTest/CiviUnitTestCase.php';
29
30
31 /**
32 * Test APIv3 civicrm_sytanc conformance* functions
33 *
34 * @package CiviCRM_APIv3
35 * @subpackage API_Core
36 */
37
38 class api_v3_SyntaxConformanceAllEntitiesTest extends CiviUnitTestCase {
39 protected $_apiversion;
40
41 /**
42 * @var array e.g. $this->deletes['CRM_Contact_DAO_Contact'][] = $contactID;
43 */
44 protected $deletableTestObjects;
45
46 /** This test case doesn't require DB reset */
47 public $DBResetRequired = FALSE;
48 public $_eNoticeCompliant = FALSE;
49 /* they are two types of missing APIs:
50 - Those that are to be implemented
51 (in some future version when someone steps in -hint hint-). List the entities in toBeImplemented[ {$action} ]
52 Those that don't exist
53 and that will never exist (eg an obsoleted Entity
54 they need to be returned by the function toBeSkipped_{$action} (because it has to be a static method and therefore couldn't access a this->toBeSkipped)
55 */ function setUp() {
56 parent::setUp();
57
58 $this->toBeImplemented['get'] = array('Profile', 'CustomValue', 'Constant', 'CustomSearch', 'Extension', 'ReportTemplate', 'System', 'Setting');
59 $this->toBeImplemented['create'] = array('SurveyRespondant', 'OptionGroup', 'MailingRecipients', 'UFMatch', 'LocationType', 'CustomSearch', 'Extension', 'ReportTemplate', 'System');
60 $this->toBeImplemented['delete'] = array('MembershipPayment', 'OptionGroup', 'SurveyRespondant', 'UFJoin', 'UFMatch', 'Extension', 'LocationType', 'System');
61 $this->onlyIDNonZeroCount['get'] = array('ActivityType', 'Entity', 'Domain','Setting');
62 $this->deprecatedAPI = array('Location', 'ActivityType', 'SurveyRespondant');
63 $this->deletableTestObjects = array();
64 }
65
66 function tearDown() {
67 foreach ($this->deletableTestObjects as $entityName => $entities) {
68 foreach ($entities as $entityID) {
69 CRM_Core_DAO::deleteTestObjects($entityName, array('id' => $entityID));
70 }
71 }
72 }
73
74
75 public static function entities($skip = NULL) {
76 // uncomment to make a quicker run when adding a test
77 //return array(array ('Tag'), array ('Activity') );
78 $tmp = civicrm_api('Entity', 'Get', array('version' => 3));
79 if (!is_array($skip)) {
80 $skip = array();
81 }
82 $tmp = array_diff($tmp['values'], $skip);
83 $entities = array();
84 foreach ($tmp as $e) {
85 $entities[] = array($e);
86 }
87 return $entities;
88 }
89
90 public static function entities_get() {
91 // all the entities, beside the ones flagged
92 return api_v3_SyntaxConformanceAllEntitiesTest::entities(api_v3_SyntaxConformanceAllEntitiesTest::toBeSkipped_get(TRUE));
93 }
94
95 public static function entities_create() {
96 return api_v3_SyntaxConformanceAllEntitiesTest::entities(api_v3_SyntaxConformanceAllEntitiesTest::toBeSkipped_create(TRUE));
97 }
98
99 public static function entities_updatesingle() {
100 return api_v3_SyntaxConformanceAllEntitiesTest::entities(api_v3_SyntaxConformanceAllEntitiesTest::toBeSkipped_updatesingle(TRUE));
101 }
102
103 public static function entities_delete() {
104 return api_v3_SyntaxConformanceAllEntitiesTest::entities(api_v3_SyntaxConformanceAllEntitiesTest::toBeSkipped_delete(TRUE));
105 }
106
107 public static function toBeSkipped_get($sequential = FALSE) {
108 $entitiesWithoutGet = array('MailingEventSubscribe', 'MailingEventConfirm', 'MailingEventResubscribe', 'MailingEventUnsubscribe', 'MailingGroup', 'Location');
109 if ($sequential === TRUE) {
110 return $entitiesWithoutGet;
111 }
112 $entities = array();
113 foreach ($entitiesWithoutGet as $e) {
114 $entities[] = array($e);
115 }
116 return $entities;
117 }
118 /**
119 * Mailing Contact Just doesn't support id. We have always insisted on finding a way to
120 * support id in API but in this case the underlying tables are crying out for a restructue
121 * & it just doesn't make sense
122 * @param unknown_type $sequential
123 * @return multitype:string |multitype:multitype:string
124 */
125 public static function toBeSkipped_getByID($sequential = FALSE) {
126 return array('MailingContact');
127 }
128
129 public static function toBeSkipped_create($sequential = FALSE) {
130 $entitiesWithoutCreate = array('MailingGroup', 'Constant', 'Entity', 'Location', 'Profile', 'MailingRecipients');
131 if ($sequential === TRUE) {
132 return $entitiesWithoutCreate;
133 }
134 $entities = array();
135 foreach ($entitiesWithoutCreate as $e) {
136 $entities[] = array($e);
137 }
138 return $entities;
139 }
140
141 public static function toBeSkipped_delete($sequential = FALSE) {
142 $entitiesWithout = array('Mailing', 'MailingGroup', 'Constant', 'Entity', 'Location', 'Domain', 'Profile', 'CustomValue');
143 if ($sequential === TRUE) {
144 return $entitiesWithout;
145 }
146 $entities = array();
147 foreach ($entitiesWithout as $e) {
148 $entities[] = array($e);
149 }
150 return $entities;
151 }
152 /**
153 * Generate list of entities to test for get by id functions
154 * @param boolean $sequential
155 * @return multitype:string |multitype:multitype:string
156 */
157 public static function toBeSkipped_automock($sequential = FALSE) {
158 $entitiesWithoutGet = array('MailingContact', 'EntityTag', 'Participant', 'ParticipantPayment', 'Setting', 'SurveyRespondant', 'MailingRecipients', 'CustomSearch', 'Extension', 'ReportTemplate', 'System');
159 if ($sequential === TRUE) {
160 return $entitiesWithoutGet;
161 }
162 $entities = array();
163 foreach ($entitiesWithoutGet as $e) {
164 $entities[] = array($e);
165 }
166 return $entities;
167 }
168
169
170 /*
171 * At this stage exclude the ones that don't pass & add them as we can troubleshoot them
172 */
173
174 public static function toBeSkipped_updatesingle($sequential = FALSE) {
175 $entitiesWithout = array(
176 'Mailing',
177 'MailingGroup',
178 'MailingJob',
179 'Address',
180 'MailingEventUnsubscribe',
181 'MailingEventSubscribe',
182 'Constant',
183 'Entity',
184 'Location',
185 'Domain',
186 'Profile',
187 'CustomValue',
188 'SurveyRespondant',
189 'Tag',
190 'UFMatch',
191 'UFJoin',
192 'UFField',
193 'OptionValue',
194 'Relationship',
195 'RelationshipType',
196 'ParticipantStatusType',
197 'Note',
198 'OptionGroup',
199 'Membership',
200 'MembershipType',
201 'MembershipStatus',
202 'Group',
203 'GroupOrganization',
204 'GroupNesting',
205 'Job',
206 'File',
207 'EntityTag',
208 'CustomField',
209 'CustomGroup',
210 'Contribution',
211 'ContributionRecur',
212 'ActivityType',
213 'MailingEventConfirm',
214 'Case',
215 'Contact',
216 'ContactType',
217 'MailingEventResubscribe',
218 'UFGroup',
219 'Activity',
220 'Email',
221 'Event',
222 'GroupContact',
223 'MembershipPayment',
224 'Participant',
225 'ParticipantPayment',
226 'LineItem',
227 'PriceSet',
228 'PriceField',
229 'PriceFieldValue',
230 'PledgePayment',
231 'ContributionPage',
232 'Phone',
233 'PaymentProcessor',
234 'MailSettings',
235 'Setting',
236 'MailingContact',
237 );
238 if ($sequential === TRUE) {
239 return $entitiesWithout;
240 }
241 $entities = array();
242 foreach ($entitiesWithout as $e) {
243 $entities[] = array(
244 $e,
245 );
246 }
247 return array('pledge');
248 return $entities;
249 }
250
251 public function getKnownUnworkablesUpdateSingle($entity, $key){
252 // can't update values are values for which updates don't result in the value being changed
253 $knownFailures = array(
254 'Address' => array(
255 'cant_update' => array(
256 'state_province_id', //issues with country id - need to ensure same country
257 'master_id',//creates relationship
258 ),
259 'cant_return' => array(
260 )
261 ),
262 'Pledge' => array(
263 'cant_update' => array(
264 'pledge_original_installment_amount',
265 'installments',
266 'original_installment_amount',
267 'next_pay_date',
268 'amount' // can't be changed through API
269 ),
270 'break_return' => array(// if these are passed in they are retrieved from the wrong table
271 'honor_contact_id',
272 'cancel_date',
273 'contribution_page_id',
274 'financial_account_id',
275 'financial_type_id',
276 'currency'
277 ),
278 'cant_return' => array(// can't be retrieved from api
279 'honor_type_id', //due to uniquename missing
280 'end_date',
281 'modified_date',
282 'acknowledge_date',
283 'start_date',
284 'frequency_day',
285 'currency',
286 'max_reminders',
287 'initial_reminder_day',
288 'additional_reminder_day',
289 'frequency_unit',
290 'pledge_contribution_page_id',
291 'pledge_status_id',
292 'pledge_campaign_id',
293 )
294 ),
295 'PaymentProcessorType' => array(
296 'cant_update' => array(
297 'billing_mode',
298 ),
299 'break_return' => array(
300 ),
301 'cant_return' => array(
302 ),
303 ),
304 );
305 if(empty($knownFailures[$entity]) || empty($knownFailures[$entity][$key])){
306 return array();
307 }
308 return $knownFailures[$entity][$key];
309 }
310
311 /** testing the _get **/
312
313 /**
314 * @dataProvider toBeSkipped_get
315 entities that don't need a get action
316 */
317 public function testNotImplemented_get($Entity) {
318 $result = civicrm_api($Entity, 'Get', array('version' => 3));
319 $this->assertEquals(1, $result['is_error'], 'In line ' . __LINE__);
320 $this->assertContains("API ($Entity,Get) does not exist", $result['error_message']);
321 }
322
323 /**
324 * @dataProvider entities
325 * @expectedException PHPUnit_Framework_Error
326 */
327 public function testWithoutParam_get($Entity) {
328 // should get php complaining that a param is missing
329 $result = civicrm_api($Entity, 'Get');
330 }
331
332 /**
333 * @dataProvider entities
334 */
335 public function testGetFields($Entity) {
336 if (in_array($Entity, $this->deprecatedAPI) || $Entity == 'Entity' || $Entity == 'CustomValue' || $Entity == 'MailingGroup') {
337 return;
338 }
339
340 $result = civicrm_api($Entity, 'getfields', array('version' => 3));
341 $this->assertTrue(is_array($result['values']), "$Entity ::get fields doesn't return values array in line " . __LINE__);
342 foreach ($result['values'] as $key => $value) {
343 $this->assertTrue(is_array($value), $Entity . "::" . $key . " is not an array in line " . __LINE__);
344 }
345 }
346
347 /**
348 * @dataProvider entities_get
349 */
350 public function testEmptyParam_get($Entity) {
351
352 if (in_array($Entity, $this->toBeImplemented['get'])) {
353 // $this->markTestIncomplete("civicrm_api3_{$Entity}_get to be implemented");
354 return;
355 }
356 $result = civicrm_api($Entity, 'Get', array());
357 $this->assertEquals(1, $result['is_error'], 'In line ' . __LINE__);
358 $this->assertContains("Mandatory key(s) missing from params array", $result['error_message']);
359 }
360 /**
361 * @dataProvider entities_get
362 */
363 public function testEmptyParam_getString($Entity) {
364
365 if (in_array($Entity, $this->toBeImplemented['get'])) {
366 // $this->markTestIncomplete("civicrm_api3_{$Entity}_get to be implemented");
367 return;
368 }
369 $result = $this->callAPIFailure($Entity, 'Get', 'string');
370 $this->assertEquals(2000, $result['error_code']);
371 $this->assertEquals('Input variable `params` is not an array', $result['error_message']);
372 }
373 /**
374 * @dataProvider entities_get
375 * @Xdepends testEmptyParam_get // no need to test the simple if the empty doesn't work/is skipped. doesn't seem to work
376 */
377 public function testSimple_get($Entity) {
378 // $this->markTestSkipped("test gives core error on test server (but not on our locals). Skip until we can get server to pass");
379 if (in_array($Entity, $this->toBeImplemented['get'])) {
380 return;
381 }
382 $result = civicrm_api($Entity, 'Get', array('version' => 3));
383 // @TODO: list the get that have mandatory params
384 if ($result['is_error']) {
385 $this->assertContains("Mandatory key(s) missing from params array", $result['error_message']);
386 // either id or contact_id or entity_id is one of the field missing
387 $this->assertContains("id", $result['error_message']);
388 }
389 else {
390 $this->assertEquals(3, $result['version']);
391 $this->assertArrayHasKey('count', $result);
392 $this->assertArrayHasKey('values', $result);
393 }
394 }
395
396 /**
397 * @dataProvider entities_get
398 */
399 public function testAcceptsOnlyID_get($Entity) {
400 // big random number. fun fact: if you multiply it by pi^e, the result is another random number, but bigger ;)
401 $nonExistantID = 30867307034;
402 if (in_array($Entity, $this->toBeImplemented['get'])
403 || in_array($Entity, $this->toBeSkipped_getByID())
404 ) {
405 return;
406 }
407
408 // FIXME
409 // the below function returns different values and hence an early return
410 // we'll fix this once beta1 is released
411 // return;
412
413 $result = civicrm_api($Entity, 'Get', array('version' => 3, 'id' => $nonExistantID));
414
415 if ($result['is_error']) {
416 // just to get a clearer message in the log
417 $this->assertEquals("only id should be enough", $result['error_message']);
418 }
419 if (!in_array($Entity, $this->onlyIDNonZeroCount['get'])) {
420 $this->assertEquals(0, $result['count']);
421 }
422 }
423
424 /**
425 * Create two entities and make sure we can fetch them individually by ID
426 *
427 * @dataProvider entities_get
428 *
429 * limitations include the problem with avoiding loops when creating test objects -
430 * hence FKs only set by createTestObject when required. e.g parent_id on campaign is not being followed through
431 * Currency - only seems to support US
432 */
433 public function testByID_get($entityName) {
434 if (in_array($entityName, self::toBeSkipped_automock(TRUE))) {
435 // $this->markTestIncomplete("civicrm_api3_{$Entity}_create to be implemented");
436 return;
437 }
438
439 $baoString = _civicrm_api3_get_DAO($entityName);
440 if (empty($baoString)) {
441 $this->markTestIncomplete("Entity [$entityName] cannot be mocked - no known DAO");
442 return;
443 }
444
445 // create entities
446 $baoObj1 = CRM_Core_DAO::createTestObject($baoString, array('currency' => 'USD'));
447 $this->assertTrue(is_integer($baoObj1->id), 'check first id');
448 $this->deletableTestObjects[$baoString][] = $baoObj1->id;
449 $baoObj2 = CRM_Core_DAO::createTestObject($baoString, array('currency' => 'USD'));
450 $this->assertTrue(is_integer($baoObj2->id), 'check second id');
451 $this->deletableTestObjects[$baoString][] = $baoObj2->id;
452
453 // fetch first by ID
454 $result = civicrm_api($entityName, 'get', array(
455 'version' => 3,
456 'id' => $baoObj1->id,
457 ));
458 $this->assertAPISuccess($result);
459 $this->assertTrue(!empty($result['values'][$baoObj1->id]), 'Should find first object by id');
460 $this->assertEquals($baoObj1->id, $result['values'][$baoObj1->id]['id'], 'Should find id on first object');
461 $this->assertEquals(1, count($result['values']));
462
463 // fetch second by ID
464 $result = civicrm_api($entityName, 'get', array(
465 'version' => 3,
466 'id' => $baoObj2->id,
467 ));
468 $this->assertAPISuccess($result);
469 $this->assertTrue(!empty($result['values'][$baoObj2->id]), 'Should find second object by id');
470 $this->assertEquals($baoObj2->id, $result['values'][$baoObj2->id]['id'], 'Should find id on second object');
471 $this->assertEquals(1, count($result['values']));
472 }
473
474 /**
475 * Create two entities and make sure we can fetch them individually by ID (e.g. using "contact_id=>2"
476 * or "group_id=>4")
477 *
478 * @dataProvider entities_get
479 *
480 * limitations include the problem with avoiding loops when creating test objects -
481 * hence FKs only set by createTestObject when required. e.g parent_id on campaign is not being followed through
482 * Currency - only seems to support US
483 */
484 public function testByIDAlias_get($entityName) {
485 if (in_array($entityName, self::toBeSkipped_automock(TRUE))) {
486 // $this->markTestIncomplete("civicrm_api3_{$Entity}_create to be implemented");
487 return;
488 }
489
490 $baoString = _civicrm_api3_get_DAO($entityName);
491 if (empty($baoString)) {
492 $this->markTestIncomplete("Entity [$entityName] cannot be mocked - no known DAO");
493 return;
494 }
495
496 $idFieldName = _civicrm_api_get_entity_name_from_camel($entityName) . '_id';
497
498 // create entities
499 $baoObj1 = CRM_Core_DAO::createTestObject($baoString, array('currency' => 'USD'));
500 $this->assertTrue(is_integer($baoObj1->id), 'check first id');
501 $this->deletableTestObjects[$baoString][] = $baoObj1->id;
502 $baoObj2 = CRM_Core_DAO::createTestObject($baoString, array('currency' => 'USD'));
503 $this->assertTrue(is_integer($baoObj2->id), 'check second id');
504 $this->deletableTestObjects[$baoString][] = $baoObj2->id;
505
506 // fetch first by ID
507 $result = civicrm_api($entityName, 'get', array(
508 'version' => 3,
509 $idFieldName => $baoObj1->id,
510 ));
511 $this->assertAPISuccess($result);
512 $this->assertTrue(!empty($result['values'][$baoObj1->id]), 'Should find first object by id');
513 $this->assertEquals($baoObj1->id, $result['values'][$baoObj1->id]['id'], 'Should find id on first object');
514 $this->assertEquals(1, count($result['values']));
515
516 // fetch second by ID
517 $result = civicrm_api($entityName, 'get', array(
518 'version' => 3,
519 $idFieldName => $baoObj2->id,
520 ));
521 $this->assertAPISuccess($result);
522 $this->assertTrue(!empty($result['values'][$baoObj2->id]), 'Should find second object by id');
523 $this->assertEquals($baoObj2->id, $result['values'][$baoObj2->id]['id'], 'Should find id on second object');
524 $this->assertEquals(1, count($result['values']));
525 }
526
527 /**
528 * @dataProvider entities_get
529 */
530 public function testNonExistantID_get($Entity) {
531 // cf testAcceptsOnlyID_get
532 $nonExistantID = 30867307034;
533 if (in_array($Entity, $this->toBeImplemented['get'])) {
534 return;
535 }
536
537 $result = civicrm_api($Entity, 'Get', array('version' => 3, 'id' => $nonExistantID));
538
539 // redundant with testAcceptsOnlyID_get
540 if ($result['is_error']) {
541 return;
542 }
543
544
545 $this->assertArrayHasKey('version', $result);
546 $this->assertEquals(3, $result['version']);
547 if (!in_array($Entity, $this->onlyIDNonZeroCount['get'])) {
548 $this->assertEquals(0, $result['count']);
549 }
550 }
551
552 /** testing the _create **/
553
554 /**
555 * @dataProvider toBeSkipped_create
556 entities that don't need a create action
557 */
558 public function testNotImplemented_create($Entity) {
559 $result = civicrm_api($Entity, 'Create', array('version' => 3));
560 $this->assertEquals(1, $result['is_error'], 'In line ' . __LINE__);
561 $this->assertContains("API ($Entity,Create) does not exist", $result['error_message']);
562 }
563
564 /**
565 * @dataProvider entities
566 * @expectedException PHPUnit_Framework_Error
567 */
568 public function testWithoutParam_create($Entity) {
569 // should create php complaining that a param is missing
570 $result = civicrm_api($Entity, 'Create');
571 }
572
573 /**
574 * @dataProvider entities_create
575 */
576 public function testEmptyParam_create($Entity) {
577 if (in_array($Entity, $this->toBeImplemented['create'])) {
578 // $this->markTestIncomplete("civicrm_api3_{$Entity}_create to be implemented");
579 return;
580 }
581 $result = civicrm_api($Entity, 'Create', array());
582 $this->assertEquals(1, $result['is_error'], 'In line ' . __LINE__);
583 $this->assertContains("Mandatory key(s) missing from params array", $result['error_message']);
584 }
585
586 /**
587 * @dataProvider entities
588 */
589 public function testCreateWrongTypeParamTag_create() {
590 $result = civicrm_api("Tag", 'Create', 'this is not a string');
591 $this->assertEquals(1, $result['is_error'], 'In line ' . __LINE__);
592 $this->assertEquals("Input variable `params` is not an array", $result['error_message']);
593 }
594
595 /**
596 * @dataProvider entities_updatesingle
597 *
598 * limitations include the problem with avoiding loops when creating test objects -
599 * hence FKs only set by createTestObject when required. e.g parent_id on campaign is not being followed through
600 * Currency - only seems to support US
601 */
602 public function testCreateSingleValueAlter($entityName) {
603 if (in_array($entityName, $this->toBeImplemented['create'])) {
604 // $this->markTestIncomplete("civicrm_api3_{$Entity}_create to be implemented");
605 return;
606 }
607
608 $baoString = _civicrm_api3_get_DAO($entityName);
609 $this->assertNotEmpty($baoString, $entityName);
610 $this->assertNotEmpty($entityName, $entityName);
611 $fieldsget = $fields = civicrm_api($entityName, 'getfields', array(
612 'version' => 3, 'action' => 'get'
613 )
614 );
615 if($entityName != 'Pledge'){
616 $fields = civicrm_api($entityName, 'getfields', array(
617 'version' => 3, 'action' => 'create'
618 )
619 );
620 }
621 $fields = $fields['values'];
622 $return = array_keys($fieldsget['values']);
623 $valuesNotToReturn = $this->getKnownUnworkablesUpdateSingle($entityName, 'break_return');
624 // these can't be requested as return values
625 $entityValuesThatDontWork = array_merge(
626 $this->getKnownUnworkablesUpdateSingle($entityName, 'cant_update'),
627 $this->getKnownUnworkablesUpdateSingle($entityName, 'cant_return'),
628 $valuesNotToReturn
629 );
630
631 $return = array_diff($return,$valuesNotToReturn);
632 $baoObj = new CRM_Core_DAO();
633 $baoObj->createTestObject($baoString, array('currency' => 'USD'), 2, 0);
634 $getentities = civicrm_api($entityName, 'get', array(
635 'version' => 3,
636 'sequential' => 1,
637 'return' => $return,
638 'options' => array(
639 'sort' => 'id DESC',
640 'limit' => 2,
641 ),
642 ));
643 // lets use first rather than assume only one exists
644 $entity = $getentities['values'][0];
645 $entity2 = $getentities['values'][1];
646 foreach ($fields as $field => $specs) {
647 $fieldName = $field;
648 if (!empty($specs['uniquename'])) {
649 $fieldName = $specs['uniquename'];
650 }
651 if ($field == 'currency' || $field == 'id' || $field == strtolower($entityName) . '_id'
652 || in_array($field,$entityValuesThatDontWork)) {
653 //@todo id & entity_id are correct but we should fix currency & frequency_day
654 continue;
655 }
656 switch ($specs['type']) {
657 case CRM_Utils_Type::T_DATE:
658 case CRM_Utils_Type::T_TIMESTAMP:
659 $entity[$fieldName] = '2012-05-20';
660 break;
661 //case CRM_Utils_Type::T_DATETIME:
662
663 case 12:
664 $entity[$fieldName] = '2012-05-20 03:05:20';
665 break;
666
667 case CRM_Utils_Type::T_STRING:
668 case CRM_Utils_Type::T_BLOB:
669 case CRM_Utils_Type::T_MEDIUMBLOB:
670 case CRM_Utils_Type::T_TEXT:
671 case CRM_Utils_Type::T_LONGTEXT:
672 case CRM_Utils_Type::T_EMAIL:
673 $entity[$fieldName] = substr('New String',0, CRM_Utils_Array::Value('maxlength',$specs,100));
674 break;
675
676 case CRM_Utils_Type::T_INT:
677 // probably created with a 1
678 $entity[$fieldName] = '6';
679 if (CRM_Utils_Array::value('FKClassName', $specs)) {
680 if($specs['FKClassName'] == $baoString){
681 $entity[$fieldName] = (string) $entity2['id'];
682 }
683 else{
684 $entity[$fieldName] = (string) empty($entity2[$field]) ? CRM_Utils_Array::value($specs['uniqueName'], $entity2) : $entity2[$field];
685 //todo - there isn't always something set here - & our checking on unset values is limited
686 if (empty($entity[$field])) {
687 unset($entity[$field]);
688 }
689 }
690 }
691 break;
692
693 case CRM_Utils_Type::T_BOOL:
694 case CRM_Utils_Type::T_BOOLEAN:
695 // probably created with a 1
696 $entity[$fieldName] = '0';
697 break;
698
699 case CRM_Utils_Type::T_FLOAT:
700 case CRM_Utils_Type::T_MONEY:
701 $entity[$field] = '222';
702 break;
703
704 case CRM_Utils_Type::T_URL:
705 $entity[$field] = 'warm.beer.com';
706 }
707 if (!empty($specs['pseudoconstant']) || !empty($specs['enumValues'])) {
708 $options = civicrm_api($entityName, 'getoptions', array('context' => 'create', 'field' => $field, 'version' => 3));
709 if (empty($options['values'])) {
710 print_r($options);
711 }
712 $entity[$field] = array_rand($options['values']);
713 }
714 $updateParams = array(
715 'version' => 3,
716 'id' => $entity['id'],
717 $field => $entity[$field],
718 );
719
720 $update = civicrm_api($entityName, 'create', $updateParams);
721 if(!empty($update['is_error'])){
722 print_r($update);
723 }
724 $this->assertAPISuccess($update, print_r($updateParams, TRUE) . 'in line ' . __LINE__);
725 $checkParams = array(
726 'id' => $entity['id'],
727 'version' => 3,
728 'sequential' => 1,
729 'return' => $return,
730 'options' => array(
731 'sort' => 'id DESC',
732 'limit' => 2,
733 ),
734 );
735
736 $checkEntity = civicrm_api($entityName, 'getsingle', $checkParams);
737 $this->assertEquals($entity, $checkEntity, "changing field $fieldName\n" .
738 print_r($entity, TRUE)
739 //print_r(array('update-params' => $updateParams, 'update-result' => $update, 'getsingle-params' => $checkParams, 'getsingle-result' => $checkEntity, 'expected entity' => $entity), TRUE)
740 );
741
742 }
743 $baoObj->deleteTestObjects($baoString);
744 $baoObj->free();
745 }
746
747 /** testing the _getFields **/
748
749 /** testing the _delete **/
750
751 /**
752 * @dataProvider toBeSkipped_delete
753 entities that don't need a delete action
754 */
755 public function testNotImplemented_delete($Entity) {
756 $nonExistantID = 151416349;
757 $result = civicrm_api($Entity, 'Delete', array('version' => 3, 'id' => $nonExistantID));
758 $this->assertEquals(1, $result['is_error'], 'In line ' . __LINE__);
759 $this->assertContains("API ($Entity,Delete) does not exist", $result['error_message']);
760 }
761
762 /**
763 * @dataProvider entities
764 * @expectedException PHPUnit_Framework_Error
765 */
766 public function testWithoutParam_delete($Entity) {
767 // should delete php complaining that a param is missing
768 $result = civicrm_api($Entity, 'Delete');
769 }
770
771 /**
772 * @dataProvider entities_delete
773 */
774 public function testEmptyParam_delete($Entity) {
775 if (in_array($Entity, $this->toBeImplemented['delete'])) {
776 // $this->markTestIncomplete("civicrm_api3_{$Entity}_delete to be implemented");
777 return;
778 }
779 $result = civicrm_api($Entity, 'Delete', array());
780 $this->assertEquals(1, $result['is_error'], 'In line ' . __LINE__);
781 $this->assertContains("Mandatory key(s) missing from params array", $result['error_message']);
782 }
783
784 /**
785 * @dataProvider entities
786 */
787 public function testDeleteWrongTypeParamTag_delete() {
788 $result = civicrm_api("Tag", 'Delete', 'this is not a string');
789 $this->assertEquals(1, $result['is_error'], 'In line ' . __LINE__);
790 $this->assertEquals("Input variable `params` is not an array", $result['error_message']);
791 }
792
793 /**
794 * Verify that HTML metacharacters provided as inputs appear consistently
795 * as outputs.
796 *
797 * At time of writing, the encoding scheme requires (for example) that an
798 * event title be partially-HTML-escaped before writing to DB. To provide
799 * consistency, the API must perform extra encoding and decoding on some
800 * fields.
801 *
802 * In this example, the event 'title' is subject to encoding, but the
803 * event 'description' is not.
804 */
805 public function testEncodeDecodeConsistency() {
806 // Create example
807 $createResult = civicrm_api('Event', 'Create', array(
808 'version' => 3,
809 'title' => 'CiviCRM <> TheRest',
810 'description' => 'TheRest <> CiviCRM',
811 'event_type_id' => 1,
812 'is_public' => 1,
813 'start_date' => 20081021,
814 ));
815 $this->assertAPISuccess($createResult);
816 $eventId = $createResult['id'];
817 $this->assertEquals('CiviCRM <> TheRest', $createResult['values'][$eventId]['title']);
818 $this->assertEquals('TheRest <> CiviCRM', $createResult['values'][$eventId]['description']);
819
820 // Verify "get" handles decoding in result value
821 $getByIdResult = civicrm_api('Event', 'Get', array(
822 'version' => 3,
823 'id' => $eventId,
824 ));
825 $this->assertAPISuccess($getByIdResult);
826 $this->assertEquals('CiviCRM <> TheRest', $getByIdResult['values'][$eventId]['title']);
827 $this->assertEquals('TheRest <> CiviCRM', $getByIdResult['values'][$eventId]['description']);
828
829 // Verify "get" handles encoding in search value
830 $getByTitleResult = civicrm_api('Event', 'Get', array(
831 'version' => 3,
832 'title' => 'CiviCRM <> TheRest',
833 ));
834 $this->assertAPISuccess($getByTitleResult);
835 $this->assertEquals('CiviCRM <> TheRest', $getByTitleResult['values'][$eventId]['title']);
836 $this->assertEquals('TheRest <> CiviCRM', $getByTitleResult['values'][$eventId]['description']);
837
838 // Verify that "getSingle" handles decoding
839 $getSingleResult = civicrm_api('Event', 'GetSingle', array(
840 'version' => 3,
841 'id' => $eventId,
842 ));
843
844 $this->assertAPISuccess($getSingleResult);
845 $this->assertEquals('CiviCRM <> TheRest', $getSingleResult['title']);
846 $this->assertEquals('TheRest <> CiviCRM', $getSingleResult['description']);
847
848 // Verify that chaining handles decoding
849 $chainResult = civicrm_api('Event', 'Get', array(
850 'version' => 3,
851 'id' => $eventId,
852 'api.event.get' => array(
853 ),
854 ));
855 $this->assertEquals('CiviCRM <> TheRest', $chainResult['values'][$eventId]['title']);
856 $this->assertEquals('TheRest <> CiviCRM', $chainResult['values'][$eventId]['description']);
857 $this->assertEquals('CiviCRM <> TheRest', $chainResult['values'][$eventId]['api.event.get']['values'][0]['title']);
858 $this->assertEquals('TheRest <> CiviCRM', $chainResult['values'][$eventId]['api.event.get']['values'][0]['description']);
859
860 // Verify that "setvalue" handles encoding for updates
861 $setValueTitleResult = civicrm_api('Event', 'setvalue', array(
862 'version' => 3,
863 'id' => $eventId,
864 'field' => 'title',
865 'value' => 'setValueTitle: CiviCRM <> TheRest',
866 ));
867 $this->assertAPISuccess($setValueTitleResult);
868 $this->assertEquals('setValueTitle: CiviCRM <> TheRest', $setValueTitleResult['values']['title']);
869 $setValueDescriptionResult = civicrm_api('Event', 'setvalue', array(
870 'version' => 3,
871 'id' => $eventId,
872 'field' => 'description',
873 'value' => 'setValueDescription: TheRest <> CiviCRM',
874 ));
875 $this->assertTrue((bool)$setValueDescriptionResult['is_error']); // not supported by setValue
876 //$this->assertAPISuccess($setValueDescriptionResult);
877 //$this->assertEquals('setValueDescription: TheRest <> CiviCRM', $setValueDescriptionResult['values']['description']);
878 }
879
880 /**
881 * Verify that write operations (create/update) use partial HTML-encoding
882 *
883 * In this example, the event 'title' is subject to encoding, but the
884 * event 'description' is not.
885 */
886 public function testEncodeWrite() {
887 // Create example
888 $createResult = civicrm_api('Event', 'Create', array(
889 'version' => 3,
890 'title' => 'createNew: CiviCRM <> TheRest',
891 'description' => 'createNew: TheRest <> CiviCRM',
892 'event_type_id' => 1,
893 'is_public' => 1,
894 'start_date' => 20081021,
895 ));
896 $this->assertAPISuccess($createResult);
897 $eventId = $createResult['id'];
898 $this->assertDBQuery('createNew: CiviCRM &lt;&gt; TheRest', 'SELECT title FROM civicrm_event WHERE id = %1', array(
899 1 => array($eventId, 'Integer')
900 ));
901 $this->assertDBQuery('createNew: TheRest <> CiviCRM', 'SELECT description FROM civicrm_event WHERE id = %1', array(
902 1 => array($eventId, 'Integer')
903 ));
904
905 // Verify that "create" handles encoding for updates
906 $createWithIdResult = civicrm_api('Event', 'Create', array(
907 'version' => 3,
908 'id' => $eventId,
909 'title' => 'createWithId: CiviCRM <> TheRest',
910 'description' => 'createWithId: TheRest <> CiviCRM',
911 ));
912 $this->assertAPISuccess($createWithIdResult);
913 $this->assertDBQuery('createWithId: CiviCRM &lt;&gt; TheRest', 'SELECT title FROM civicrm_event WHERE id = %1', array(
914 1 => array($eventId, 'Integer')
915 ));
916 $this->assertDBQuery('createWithId: TheRest <> CiviCRM', 'SELECT description FROM civicrm_event WHERE id = %1', array(
917 1 => array($eventId, 'Integer')
918 ));
919
920 // Verify that "setvalue" handles encoding for updates
921 $setValueTitleResult = civicrm_api('Event', 'setvalue', array(
922 'version' => 3,
923 'id' => $eventId,
924 'field' => 'title',
925 'value' => 'setValueTitle: CiviCRM <> TheRest',
926 ));
927 $this->assertAPISuccess($setValueTitleResult);
928 $this->assertDBQuery('setValueTitle: CiviCRM &lt;&gt; TheRest', 'SELECT title FROM civicrm_event WHERE id = %1', array(
929 1 => array($eventId, 'Integer')
930 ));
931 $setValueDescriptionResult = civicrm_api('Event', 'setvalue', array(
932 'version' => 3,
933 'id' => $eventId,
934 'field' => 'description',
935 'value' => 'setValueDescription: TheRest <> CiviCRM',
936 ));
937 $this->assertTrue((bool)$setValueDescriptionResult['is_error']); // not supported by setValue
938 //$this->assertAPISuccess($setValueDescriptionResult);
939 //$this->assertDBQuery('setValueDescription: TheRest <> CiviCRM', 'SELECT description FROM civicrm_event WHERE id = %1', array(
940 // 1 => array($eventId, 'Integer')
941 //));
942 }
943
944 }