Merge remote-tracking branch 'upstream/4.5' into 4.5-master-2014-10-14-11-24-52
[civicrm-core.git] / tests / phpunit / CiviTest / CiviUnitTestCase.php
index 496ca2df3beed1a63e52715487571bdc3f71e26b..85b165f58d420ce540735adda19844ba5da8b332 100644 (file)
@@ -39,11 +39,6 @@ require_once CIVICRM_SETTINGS_PATH;
 /**
  *  Include class definitions
  */
-require_once 'PHPUnit/Extensions/Database/TestCase.php';
-require_once 'PHPUnit/Framework/TestResult.php';
-require_once 'PHPUnit/Extensions/Database/DataSet/FlatXmlDataSet.php';
-require_once 'PHPUnit/Extensions/Database/DataSet/XmlDataSet.php';
-require_once 'PHPUnit/Extensions/Database/DataSet/QueryDataSet.php';
 require_once 'tests/phpunit/Utils.php';
 require_once 'api/api.php';
 require_once 'CRM/Financial/BAO/FinancialType.php';
@@ -82,6 +77,11 @@ class CiviUnitTestCase extends PHPUnit_Extensions_Database_TestCase {
    */
   static protected $_dbName;
 
+  /**
+   * Track tables we have modified during a test
+   */
+  protected $_tablesToTruncate = array();
+
   /**
    * @var array of temporary directory names
    */
@@ -161,10 +161,16 @@ class CiviUnitTestCase extends PHPUnit_Extensions_Database_TestCase {
     }
   }
 
+  /**
+   * @return bool
+   */
   function requireDBReset() {
     return $this->DBResetRequired;
   }
 
+  /**
+   * @return string
+   */
   static function getDBName() {
     $dbName = !empty($GLOBALS['mysql_db']) ? $GLOBALS['mysql_db'] : 'civicrm_tests_dev';
     return $dbName;
@@ -298,6 +304,10 @@ class CiviUnitTestCase extends PHPUnit_Extensions_Database_TestCase {
     // Rebuild triggers
     civicrm_api('system', 'flush', array('version' => 3, 'triggers' => 1));
 
+    CRM_Core_BAO_ConfigSetting::setEnabledComponents(array(
+      'CiviEvent', 'CiviContribute', 'CiviMember', 'CiviMail', 'CiviReport', 'CiviPledge'
+    ));
+
     return TRUE;
   }
 
@@ -308,7 +318,7 @@ class CiviUnitTestCase extends PHPUnit_Extensions_Database_TestCase {
     $GLOBALS['_PEAR_ERRORSTACK_OVERRIDE_CALLBACK'] = array();
 
     $env = new CRM_Utils_Check_Env();
-    CRM_Utils_Check::singleton()->assertValid($env->checkAll());
+    CRM_Utils_Check::singleton()->assertValid($env->checkMysqlTime());
   }
 
   /**
@@ -366,6 +376,34 @@ class CiviUnitTestCase extends PHPUnit_Extensions_Database_TestCase {
     else {
       error_reporting(E_ALL & ~E_NOTICE);
     }
+    $this->_sethtmlGlobals();
+  }
+
+  /**
+   * Read everything from the datasets directory and insert into the db
+   */
+  public function loadAllFixtures() {
+    $fixturesDir = __DIR__ . '/../../fixtures';
+
+    $this->getConnection()->getConnection()->query("SET FOREIGN_KEY_CHECKS = 0;");
+
+    $xmlFiles = glob($fixturesDir . '/*.xml');
+    foreach ($xmlFiles as $xmlFixture) {
+      $op = new PHPUnit_Extensions_Database_Operation_Insert();
+      $dataset = $this->createXMLDataSet($xmlFixture);
+      $this->_tablesToTruncate = array_merge($this->_tablesToTruncate, $dataset->getTableNames());
+      $op->execute($this->_dbconn, $dataset);
+    }
+
+    $yamlFiles = glob($fixturesDir . '/*.yaml');
+    foreach ($yamlFiles as $yamlFixture) {
+      $op = new PHPUnit_Extensions_Database_Operation_Insert();
+      $dataset = new PHPUnit_Extensions_Database_DataSet_YamlDataSet($yamlFixture);
+      $this->_tablesToTruncate = array_merge($this->_tablesToTruncate, $dataset->getTableNames());
+      $op->execute($this->_dbconn, $dataset);
+    }
+
+    $this->getConnection()->getConnection()->query("SET FOREIGN_KEY_CHECKS = 1;");
   }
 
   /**
@@ -399,6 +437,8 @@ class CiviUnitTestCase extends PHPUnit_Extensions_Database_TestCase {
    */
   protected function tearDown() {
     error_reporting(E_ALL & ~E_NOTICE);
+    $session = CRM_Core_Session::singleton();
+    $session->set('userID', NULL);
     $tablesToTruncate = array('civicrm_contact');
     $this->quickCleanup($tablesToTruncate);
     $this->cleanTempDirs();
@@ -483,6 +523,16 @@ class CiviUnitTestCase extends PHPUnit_Extensions_Database_TestCase {
   }
 
   // Request a record from the DB by seachColumn+searchValue. Success if a record is found.
+  /**
+   * @param $daoName
+   * @param $searchValue
+   * @param $returnColumn
+   * @param $searchColumn
+   * @param $message
+   *
+   * @return null|string
+   * @throws PHPUnit_Framework_AssertionFailedError
+   */
   function assertDBNotNull($daoName, $searchValue, $returnColumn, $searchColumn, $message) {
     if (empty($searchValue)) {
       $this->fail("empty value passed to assertDBNotNull");
@@ -494,12 +544,24 @@ class CiviUnitTestCase extends PHPUnit_Extensions_Database_TestCase {
   }
 
   // Request a record from the DB by seachColumn+searchValue. Success if returnColumn value is NULL.
+  /**
+   * @param $daoName
+   * @param $searchValue
+   * @param $returnColumn
+   * @param $searchColumn
+   * @param $message
+   */
   function assertDBNull($daoName, $searchValue, $returnColumn, $searchColumn, $message) {
     $value = CRM_Core_DAO::getFieldValue($daoName, $searchValue, $returnColumn, $searchColumn, TRUE);
     $this->assertNull($value, $message);
   }
 
   // Request a record from the DB by id. Success if row not found.
+  /**
+   * @param $daoName
+   * @param $id
+   * @param null $message
+   */
   function assertDBRowNotExist($daoName, $id, $message = NULL) {
     $message = $message ? $message : "$daoName (#$id) should not exist";
     $value = CRM_Core_DAO::getFieldValue($daoName, $id, 'id', 'id', TRUE);
@@ -507,6 +569,11 @@ class CiviUnitTestCase extends PHPUnit_Extensions_Database_TestCase {
   }
 
   // Request a record from the DB by id. Success if row not found.
+  /**
+   * @param $daoName
+   * @param $id
+   * @param null $message
+   */
   function assertDBRowExist($daoName, $id, $message = NULL) {
     $message = $message ? $message : "$daoName (#$id) should exist";
     $value = CRM_Core_DAO::getFieldValue($daoName, $id, 'id', 'id', TRUE);
@@ -514,6 +581,14 @@ class CiviUnitTestCase extends PHPUnit_Extensions_Database_TestCase {
   }
 
   // Compare a single column value in a retrieved DB record to an expected value
+  /**
+   * @param $daoName
+   * @param $searchValue
+   * @param $returnColumn
+   * @param $searchColumn
+   * @param $expectedValue
+   * @param $message
+   */
   function assertDBCompareValue($daoName, $searchValue, $returnColumn, $searchColumn,
                                 $expectedValue, $message
   ) {
@@ -522,6 +597,11 @@ class CiviUnitTestCase extends PHPUnit_Extensions_Database_TestCase {
   }
 
   // Compare all values in a single retrieved DB record to an array of expected values
+  /**
+   * @param $daoName
+   * @param $searchParams
+   * @param $expectedValues
+   */
   function assertDBCompareValues($daoName, $searchParams, $expectedValues) {
     //get the values from db
     $dbValues = array();
@@ -582,6 +662,13 @@ class CiviUnitTestCase extends PHPUnit_Extensions_Database_TestCase {
     $this->assertTrue(abs($actual - $expected) < $tolerance, $message);
   }
 
+  /**
+   * @param $expectedValues
+   * @param $actualValues
+   * @param null $message
+   *
+   * @throws PHPUnit_Framework_AssertionFailedError
+   */
   function assertAttributesEquals($expectedValues, $actualValues, $message = NULL) {
     foreach ($expectedValues as $paramName => $paramValue) {
       if (isset($actualValues[$paramName])) {
@@ -593,6 +680,10 @@ class CiviUnitTestCase extends PHPUnit_Extensions_Database_TestCase {
     }
   }
 
+  /**
+   * @param $key
+   * @param $list
+   */
   function assertArrayKeyExists($key, &$list) {
     $result = isset($list[$key]) ? TRUE : FALSE;
     $this->assertTrue($result, ts("%1 element exists?",
@@ -600,6 +691,10 @@ class CiviUnitTestCase extends PHPUnit_Extensions_Database_TestCase {
     ));
   }
 
+  /**
+   * @param $key
+   * @param $list
+   */
   function assertArrayValueNotNull($key, &$list) {
     $this->assertArrayKeyExists($key, $list);
 
@@ -635,8 +730,10 @@ class CiviUnitTestCase extends PHPUnit_Extensions_Database_TestCase {
   /**
    * check that api returned 'is_error' => 1
    * else provide full message
+   *
    * @param array $apiResult api result
    * @param string $prefix extra test to add to message
+   * @param null $expectedError
    */
   function assertAPIFailure($apiResult, $prefix = '', $expectedError = NULL) {
     if (!empty($prefix)) {
@@ -649,6 +746,11 @@ class CiviUnitTestCase extends PHPUnit_Extensions_Database_TestCase {
     $this->assertNotEmpty($apiResult['error_message']);
   }
 
+  /**
+   * @param $expected
+   * @param $actual
+   * @param string $message
+   */
   function assertType($expected, $actual, $message = '') {
     return $this->assertInternalType($expected, $actual, $message);
   }
@@ -664,8 +766,11 @@ class CiviUnitTestCase extends PHPUnit_Extensions_Database_TestCase {
   /**
    * check that api returned 'is_error' => 1
    * else provide full message
-   * @param array $apiResult api result
+   * @param $result
+   * @param $expected
+   * @param array $valuesToExclude
    * @param string $prefix extra test to add to message
+   * @internal param array $apiResult api result
    */
   function assertAPIArrayComparison($result, $expected, $valuesToExclude = array(), $prefix = '') {
     $valuesToExclude = array_merge($valuesToExclude, array('debug', 'xdebug', 'sequential'));
@@ -680,9 +785,22 @@ class CiviUnitTestCase extends PHPUnit_Extensions_Database_TestCase {
     $this->assertEquals($result, $expected, "api result array comparison failed " . $prefix . print_r($result, TRUE) . ' was compared to ' . print_r($expected, TRUE));
   }
 
+  /**
+   * A stub for the API interface. This can be overriden by subclasses to change how the API is called.
+   *
+   * @param $entity
+   * @param $action
+   * @param $params
+   * @return array|int
+   */
+  function civicrm_api($entity, $action, $params) {
+    return civicrm_api($entity, $action, $params);
+  }
+
   /**
    * This function exists to wrap api functions
    * so we can ensure they succeed & throw exceptions without litterering the test with checks
+   *
    * @param string $entity
    * @param string $action
    * @param array $params
@@ -690,6 +808,8 @@ class CiviUnitTestCase extends PHPUnit_Extensions_Database_TestCase {
    *   getcount, getsingle. Note that for getvalue the type is checked rather than the value
    *   for getsingle the array is compared against an array passed in - the id is not compared (for
    *   better or worse )
+   *
+   * @return array|int
    */
   function callAPISuccess($entity, $action, $params, $checkAgainst = NULL) {
     $params = array_merge(array(
@@ -706,7 +826,7 @@ class CiviUnitTestCase extends PHPUnit_Extensions_Database_TestCase {
       case 'getcount' :
           return $this->callAPISuccessGetCount($entity, $params, $checkAgainst);
     }
-    $result = civicrm_api($entity, $action, $params);
+    $result = $this->civicrm_api($entity, $action, $params);
     $this->assertAPISuccess($result, "Failure in api call for $entity $action");
     return $result;
   }
@@ -715,6 +835,7 @@ class CiviUnitTestCase extends PHPUnit_Extensions_Database_TestCase {
    * This function exists to wrap api getValue function & check the result
    * so we can ensure they succeed & throw exceptions without litterering the test with checks
    * There is a type check in this
+   *
    * @param string $entity
    * @param array $params
    * @param string $type - per http://php.net/manual/en/function.gettype.php possible types
@@ -724,13 +845,15 @@ class CiviUnitTestCase extends PHPUnit_Extensions_Database_TestCase {
    * - string
    * - array
    * - object
+   *
+   * @return array|int
    */
   function callAPISuccessGetValue($entity, $params, $type = NULL) {
     $params += array(
       'version' => $this->_apiversion,
       'debug' => 1,
     );
-    $result = civicrm_api($entity, 'getvalue', $params);
+    $result = $this->civicrm_api($entity, 'getvalue', $params);
     if($type){
       if($type == 'integer'){
         // api seems to return integers as strings
@@ -746,6 +869,7 @@ class CiviUnitTestCase extends PHPUnit_Extensions_Database_TestCase {
   /**
    * This function exists to wrap api getsingle function & check the result
    * so we can ensure they succeed & throw exceptions without litterering the test with checks
+   *
    * @param string $entity
    * @param array $params
    * @param array $checkAgainst - array to compare result against
@@ -755,13 +879,16 @@ class CiviUnitTestCase extends PHPUnit_Extensions_Database_TestCase {
    * - string
    * - array
    * - object
+   *
+   * @throws Exception
+   * @return array|int
    */
   function callAPISuccessGetSingle($entity, $params, $checkAgainst = NULL) {
     $params += array(
       'version' => $this->_apiversion,
       'debug' => 1,
     );
-    $result = civicrm_api($entity, 'getsingle', $params);
+    $result = $this->civicrm_api($entity, 'getsingle', $params);
     if(!is_array($result) || !empty($result['is_error']) || isset($result['values'])) {
       throw new Exception('Invalid getsingle result' . print_r($result, TRUE));
     }
@@ -771,13 +898,17 @@ class CiviUnitTestCase extends PHPUnit_Extensions_Database_TestCase {
     }
     return $result;
   }
+
   /**
    * This function exists to wrap api getValue function & check the result
    * so we can ensure they succeed & throw exceptions without litterering the test with checks
    * There is a type check in this
    * @param string $entity
    * @param array $params
-   * @param string $type - per http://php.net/manual/en/function.gettype.php possible types
+   * @param null $count
+   * @throws Exception
+   * @return array|int
+   * @internal param string $type - per http://php.net/manual/en/function.gettype.php possible types
    * - boolean
    * - integer
    * - double
@@ -790,7 +921,7 @@ class CiviUnitTestCase extends PHPUnit_Extensions_Database_TestCase {
       'version' => $this->_apiversion,
       'debug' => 1,
     );
-    $result = civicrm_api($entity, 'getcount', $params);
+    $result = $this->civicrm_api($entity, 'getcount', $params);
     if(!is_integer($result) || !empty($result['is_error']) || isset($result['values'])) {
       throw new Exception('Invalid getcount result : ' . print_r($result, TRUE) . " type :" . gettype($result));
     }
@@ -799,6 +930,7 @@ class CiviUnitTestCase extends PHPUnit_Extensions_Database_TestCase {
     }
     return $result;
   }
+
   /**
    * This function exists to wrap api functions
    * so we can ensure they succeed, generate and example & throw exceptions without litterering the test with checks
@@ -808,6 +940,10 @@ class CiviUnitTestCase extends PHPUnit_Extensions_Database_TestCase {
    * @param array $params
    * @param string $function - pass this in to create a generated example
    * @param string $file - pass this in to create a generated example
+   * @param string $description
+   * @param string|null $subfile
+   * @param string|null $actionName
+   * @return array|int
    */
   function callAPIAndDocument($entity, $action, $params, $function, $file, $description = "", $subfile = NULL, $actionName = NULL){
     $params['version'] = $this->_apiversion;
@@ -823,6 +959,8 @@ class CiviUnitTestCase extends PHPUnit_Extensions_Database_TestCase {
    * @param string $action
    * @param array $params
    * @param string $expectedErrorMessage error
+   * @param null $extraOutput
+   * @return array|int
    */
   function callAPIFailure($entity, $action, $params, $expectedErrorMessage = NULL, $extraOutput = NULL) {
     if (is_array($params)) {
@@ -830,7 +968,7 @@ class CiviUnitTestCase extends PHPUnit_Extensions_Database_TestCase {
         'version' => $this->_apiversion,
       );
     }
-    $result = civicrm_api($entity, $action, $params);
+    $result = $this->civicrm_api($entity, $action, $params);
     $this->assertAPIFailure($result, "We expected a failure for $entity $action but got a success");
     return $result;
   }
@@ -917,7 +1055,6 @@ class CiviUnitTestCase extends PHPUnit_Extensions_Database_TestCase {
       $params[$key] = $values[$seq % sizeof($values)];
     }
     if ($contact_type == 'Individual' ) {
-        $employer = $this->sampleContact('Organization', $seq);
         $params['email'] = strtolower(
           $params['first_name'] . '_' . $params['last_name'] . '@civicrm.org'
         );
@@ -939,14 +1076,17 @@ class CiviUnitTestCase extends PHPUnit_Extensions_Database_TestCase {
    */
   private function _contactCreate($params) {
     $result = $this->callAPISuccess('contact', 'create', $params);
-    if (CRM_Utils_Array::value('is_error', $result) ||
-      !CRM_Utils_Array::value('id', $result)
-    ) {
+    if (!empty($result['is_error']) || empty($result['id'])) {
       throw new Exception('Could not create test contact, with message: ' . CRM_Utils_Array::value('error_message', $result) . "\nBacktrace:" . CRM_Utils_Array::value('trace', $result));
     }
     return $result['id'];
   }
 
+  /**
+   * @param $contactID
+   *
+   * @return array|int
+   */
   function contactDelete($contactID) {
     $params = array(
       'id' => $contactID,
@@ -964,6 +1104,11 @@ class CiviUnitTestCase extends PHPUnit_Extensions_Database_TestCase {
     return  $result;
   }
 
+  /**
+   * @param $contactTypeId
+   *
+   * @throws Exception
+   */
   function contactTypeDelete($contactTypeId) {
     require_once 'CRM/Contact/BAO/ContactType.php';
     $result = CRM_Contact_BAO_ContactType::del($contactTypeId);
@@ -972,20 +1117,26 @@ class CiviUnitTestCase extends PHPUnit_Extensions_Database_TestCase {
     }
   }
 
+  /**
+   * @param array $params
+   *
+   * @return mixed
+   */
   function membershipTypeCreate($params = array()) {
     CRM_Member_PseudoConstant::flush('membershipType');
     CRM_Core_Config::clearDBCache();
+    $memberOfOrganization = $this->organizationCreate();
     $params = array_merge(array(
       'name' => 'General',
       'duration_unit' => 'year',
       'duration_interval' => 1,
       'period_type' => 'rolling',
-      'member_of_contact_id' => 1,
+      'member_of_contact_id' => $memberOfOrganization,
       'domain_id' => 1,
       'financial_type_id' => 1,
       'is_active' => 1,
       'sequential' => 1,
-      'visibility' => 1,
+      'visibility' => 'Public',
     ), $params);
 
     $result = $this->callAPISuccess('MembershipType', 'Create', $params);
@@ -996,6 +1147,11 @@ class CiviUnitTestCase extends PHPUnit_Extensions_Database_TestCase {
     return $result['id'];
   }
 
+  /**
+   * @param $params
+   *
+   * @return mixed
+   */
   function contactMembershipCreate($params) {
     $pre = array(
       'join_date' => '2007-01-21',
@@ -1017,19 +1173,27 @@ class CiviUnitTestCase extends PHPUnit_Extensions_Database_TestCase {
   /**
    * Function to delete Membership Type
    *
-   * @param int $membershipTypeID
+   * @param $params
+   * @internal param int $membershipTypeID
    */
   function membershipTypeDelete($params) {
-    $result = $this->callAPISuccess('MembershipType', 'Delete', $params);
-    return;
+    $this->callAPISuccess('MembershipType', 'Delete', $params);
   }
 
+  /**
+   * @param $membershipID
+   */
   function membershipDelete($membershipID) {
     $deleteParams = array('id' => $membershipID);
     $result = $this->callAPISuccess('Membership', 'Delete', $deleteParams);
     return;
   }
 
+  /**
+   * @param string $name
+   *
+   * @return mixed
+   */
   function membershipStatusCreate($name = 'test member status') {
     $params['name'] = $name;
     $params['start_event'] = 'start_date';
@@ -1042,6 +1206,9 @@ class CiviUnitTestCase extends PHPUnit_Extensions_Database_TestCase {
     return $result['id'];
   }
 
+  /**
+   * @param $membershipStatusID
+   */
   function membershipStatusDelete($membershipStatusID) {
     if (!$membershipStatusID) {
       return;
@@ -1050,6 +1217,11 @@ class CiviUnitTestCase extends PHPUnit_Extensions_Database_TestCase {
     return;
   }
 
+  /**
+   * @param array $params
+   *
+   * @return mixed
+   */
   function relationshipTypeCreate($params = array()) {
     $params = array_merge(array(
         'name_a_b' => 'Relation 1 for relationship type create',
@@ -1078,6 +1250,11 @@ class CiviUnitTestCase extends PHPUnit_Extensions_Database_TestCase {
     $this->callAPISuccess('relationship_type', 'delete', $params);
   }
 
+  /**
+   * @param null $params
+   *
+   * @return mixed
+   */
   function paymentProcessorTypeCreate($params = NULL) {
     if (is_null($params)) {
       $params = array(
@@ -1150,6 +1327,7 @@ class CiviUnitTestCase extends PHPUnit_Extensions_Database_TestCase {
   /**
    * Function to create contribution page
    *
+   * @param $params
    * @return object of contribution page
    */
   function contributionPageCreate($params) {
@@ -1171,6 +1349,7 @@ class CiviUnitTestCase extends PHPUnit_Extensions_Database_TestCase {
   /**
    * Function to create Tag
    *
+   * @param array $params
    * @return array result of created tag
    */
   function tagCreate($params = array()) {
@@ -1201,7 +1380,9 @@ class CiviUnitTestCase extends PHPUnit_Extensions_Database_TestCase {
   /**
    * Add entity(s) to the tag
    *
-   * @param  array  $params
+   * @param  array $params
+   *
+   * @return bool
    */
   function entityTagAdd($params) {
     $result = $this->callAPISuccess('entity_tag', 'create', $params);
@@ -1211,8 +1392,9 @@ class CiviUnitTestCase extends PHPUnit_Extensions_Database_TestCase {
   /**
    * Function to create contribution
    *
-   * @param int $cID      contact_id
-   * @param int $cTypeID  id of financial type
+   * @param int $cID contact_id
+   *
+   * @internal param int $cTypeID id of financial type
    *
    * @return int id of created contribution
    */
@@ -1239,7 +1421,8 @@ class CiviUnitTestCase extends PHPUnit_Extensions_Database_TestCase {
   /**
    * Function to delete contribution
    *
-   * @param int $contributionId
+   * @param $pledgeId
+   * @internal param int $contributionId
    */
   function pledgeDelete($pledgeId) {
     $params = array(
@@ -1251,9 +1434,13 @@ class CiviUnitTestCase extends PHPUnit_Extensions_Database_TestCase {
   /**
    * Function to create contribution
    *
-   * @param int $cID      contact_id
-   * @param int $cTypeID  id of financial type
+   * @param int $cID contact_id
+   * @param int $cTypeID id of financial type
    *
+   * @param int $invoiceID
+   * @param int $trxnID
+   * @param int $paymentInstrumentID
+   * @param bool $isFee
    * @return int id of created contribution
    */
   function contributionCreate($cID, $cTypeID = 1, $invoiceID = 67890, $trxnID = 12345, $paymentInstrumentID = 1, $isFee = TRUE) {
@@ -1284,8 +1471,11 @@ class CiviUnitTestCase extends PHPUnit_Extensions_Database_TestCase {
   /**
    * Function to create online contribution
    *
-   * @param int $financialType  id of financial type
+   * @param $params
+   * @param int $financialType id of financial type
    *
+   * @param int $invoiceID
+   * @param int $trxnID
    * @return int id of created contribution
    */
   function onlineContributionCreate($params, $financialType, $invoiceID = 67890, $trxnID = 12345) {
@@ -1309,6 +1499,8 @@ class CiviUnitTestCase extends PHPUnit_Extensions_Database_TestCase {
    * Function to delete contribution
    *
    * @param int $contributionId
+   *
+   * @return array|int
    */
   function contributionDelete($contributionId) {
     $params = array(
@@ -1360,7 +1552,9 @@ class CiviUnitTestCase extends PHPUnit_Extensions_Database_TestCase {
   /**
    * Function to delete event
    *
-   * @param int $id  ID of the event
+   * @param int $id ID of the event
+   *
+   * @return array|int
    */
   function eventDelete($id) {
     $params = array(
@@ -1373,6 +1567,8 @@ class CiviUnitTestCase extends PHPUnit_Extensions_Database_TestCase {
    * Function to delete participant
    *
    * @param int $participantID
+   *
+   * @return array|int
    */
   function participantDelete($participantID) {
     $params = array(
@@ -1384,6 +1580,8 @@ class CiviUnitTestCase extends PHPUnit_Extensions_Database_TestCase {
   /**
    * Function to create participant payment
    *
+   * @param $participantID
+   * @param null $contributionID
    * @return int $id of created payment
    */
   function participantPaymentCreate($participantID, $contributionID = NULL) {
@@ -1412,6 +1610,7 @@ class CiviUnitTestCase extends PHPUnit_Extensions_Database_TestCase {
   /**
    * Function to add a Location
    *
+   * @param $contactID
    * @return int location id of created location
    */
   function locationAdd($contactID) {
@@ -1451,6 +1650,7 @@ class CiviUnitTestCase extends PHPUnit_Extensions_Database_TestCase {
   /**
    * Function to add a Location Type
    *
+   * @param null $params
    * @return int location id of created location
    */
   function locationTypeCreate($params = NULL) {
@@ -1488,8 +1688,8 @@ class CiviUnitTestCase extends PHPUnit_Extensions_Database_TestCase {
    *
    * @params array to add group
    *
+   * @param array $params
    * @return int groupId of created group
-   *
    */
   function groupCreate($params = array()) {
     $params = array_merge(array(
@@ -1512,7 +1712,8 @@ class CiviUnitTestCase extends PHPUnit_Extensions_Database_TestCase {
   /**
    * Function to delete a Group
    *
-   * @param int $id
+   * @param $gid
+   * @internal param int $id
    */
   function groupDelete($gid) {
 
@@ -1541,9 +1742,11 @@ class CiviUnitTestCase extends PHPUnit_Extensions_Database_TestCase {
     ), $params);
     $this->callAPISuccess('uf_field', 'create', $params);
   }
+
   /**
    * Function to add a UF Join Entry
    *
+   * @param null $params
    * @return int $id of created UF Join
    */
   function ufjoinCreate($params = NULL) {
@@ -1598,20 +1801,23 @@ class CiviUnitTestCase extends PHPUnit_Extensions_Database_TestCase {
   /**
    * Function to delete Group for a contact
    *
-   * @param array $params
+   * @param $contactId
+   * @internal param array $params
    */
   function contactGroupDelete($contactId) {
     $params = array(
       'contact_id.1' => $contactId,
       'group_id' => 1,
     );
-    civicrm_api('GroupContact', 'Delete', $params);
+    $this->civicrm_api('GroupContact', 'Delete', $params);
   }
 
   /**
    * Function to create Activity
    *
-   * @param int $contactId
+   * @param null $params
+   * @return array|int
+   * @internal param int $contactId
    */
   function activityCreate($params = NULL) {
 
@@ -1674,8 +1880,10 @@ class CiviUnitTestCase extends PHPUnit_Extensions_Database_TestCase {
   /**
    * Function to create custom group
    *
-   * @param string $className
-   * @param string $title  name of custom group
+   * @param array $params
+   * @return array|int
+   * @internal param string $className
+   * @internal param string $title name of custom group
    */
   function customGroupCreate($params = array()) {
     $defaults = array(
@@ -1753,10 +1961,10 @@ class CiviUnitTestCase extends PHPUnit_Extensions_Database_TestCase {
    * participant:testCreateWithCustom for how to use this
    *
    * @param string $function __FUNCTION__
-   * @param string $file __FILE__
+   * @param $filename
+   * @internal param string $file __FILE__
    *
    * @return array $ids ids of created objects
-   *
    */
   function entityCustomGroupWithSingleFieldCreate($function, $filename) {
     $params = array('title' => $function);
@@ -1772,7 +1980,9 @@ class CiviUnitTestCase extends PHPUnit_Extensions_Database_TestCase {
   /**
    * Function to delete custom group
    *
-   * @param int    $customGroupID
+   * @param int $customGroupID
+   *
+   * @return array|int
    */
   function customGroupDelete($customGroupID) {
     $params['id'] = $customGroupID;
@@ -1783,8 +1993,9 @@ class CiviUnitTestCase extends PHPUnit_Extensions_Database_TestCase {
    * Function to create custom field
    *
    * @param array $params (custom_group_id) is required
-   * @param string $name  name of custom field
-   * @param int $apiversion API  version to use
+   * @return array|int
+   * @internal param string $name name of custom field
+   * @internal param int $apiversion API  version to use
    */
   function customFieldCreate($params) {
     $params = array_merge(array(
@@ -1810,6 +2021,8 @@ class CiviUnitTestCase extends PHPUnit_Extensions_Database_TestCase {
    * Function to delete custom field
    *
    * @param int $customFieldID
+   *
+   * @return array|int
    */
   function customFieldDelete($customFieldID) {
 
@@ -1822,6 +2035,7 @@ class CiviUnitTestCase extends PHPUnit_Extensions_Database_TestCase {
    *
    * @params array $params  name-value pair for an event
    *
+   * @param $cId
    * @return array $note
    */
   function noteCreate($cId) {
@@ -1862,7 +2076,7 @@ class CiviUnitTestCase extends PHPUnit_Extensions_Database_TestCase {
    * @param string $action - optional action - otherwise taken from function name
    */
   function documentMe($params, $result, $function, $filename, $description = "", $subfile = NULL, $action = NULL) {
-    if (defined('DONT_DOCUMENT_TEST_CONFIG')) {
+    if (defined('DONT_DOCUMENT_TEST_CONFIG') && DONT_DOCUMENT_TEST_CONFIG) {
       return;
     }
     $entity = substr(basename($filename), 0, strlen(basename($filename)) - 8);
@@ -1888,6 +2102,14 @@ class CiviUnitTestCase extends PHPUnit_Extensions_Database_TestCase {
         $action = empty($action) ? 'getfields' : $action;
         $entityAction = 'GetFields';
       }
+      elseif (strstr($function, 'GetList')) {
+        $action = empty($action) ? 'getlist' : $action;
+        $entityAction = 'GetList';
+      }
+      elseif (strstr($function, 'GetActions')) {
+        $action = empty($action) ? 'getactions' : $action;
+        $entityAction = 'GetActions';
+      }
       elseif (strstr($function, 'Get')) {
         $action = empty($action) ? 'get' : $action;
         $entityAction = 'Get';
@@ -1960,7 +2182,10 @@ class CiviUnitTestCase extends PHPUnit_Extensions_Database_TestCase {
   /**
    * Tidy up examples array so that fields that change often ..don't
    * and debug related fields are unset
-   * @param array $params
+   *
+   * @param $result
+   *
+   * @internal param array $params
    */
   function tidyExampleResult(&$result){
     if(!is_array($result)) {
@@ -2046,8 +2271,10 @@ class CiviUnitTestCase extends PHPUnit_Extensions_Database_TestCase {
   /**
    * Function to create custom field with Option Values
    *
-   * @param array    $customGroup
-   * @param string $name  name of custom field
+   * @param array $customGroup
+   * @param string $name name of custom field
+   *
+   * @return array|int
    */
   function customFieldOptionValueCreate($customGroup, $name) {
     $fieldParams = array(
@@ -2081,6 +2308,11 @@ class CiviUnitTestCase extends PHPUnit_Extensions_Database_TestCase {
     return $this->callAPISuccess('custom_field', 'create', $params);
   }
 
+  /**
+   * @param $entities
+   *
+   * @return bool
+   */
   function confirmEntitiesDeleted($entities) {
     foreach ($entities as $entity) {
 
@@ -2092,12 +2324,18 @@ class CiviUnitTestCase extends PHPUnit_Extensions_Database_TestCase {
     }
   }
 
+  /**
+   * @param $tablesToTruncate
+   * @param bool $dropCustomValueTables
+   */
   function quickCleanup($tablesToTruncate, $dropCustomValueTables = FALSE) {
     if ($dropCustomValueTables) {
       $tablesToTruncate[] = 'civicrm_custom_group';
       $tablesToTruncate[] = 'civicrm_custom_field';
     }
 
+    $tablesToTruncate = array_unique(array_merge($this->_tablesToTruncate, $tablesToTruncate));
+
     CRM_Core_DAO::executeQuery("SET FOREIGN_KEY_CHECKS = 0;");
     foreach ($tablesToTruncate as $table) {
       $sql = "TRUNCATE TABLE $table";
@@ -2122,6 +2360,42 @@ AND    ( TABLE_NAME LIKE 'civicrm_value_%' )
     }
   }
 
+  /**
+   * Clean up financial entities after financial tests (so we remember to get all the tables :-))
+   */
+  function quickCleanUpFinancialEntities() {
+    $tablesToTruncate = array(
+      'civicrm_contribution',
+      'civicrm_contribution_soft',
+      'civicrm_financial_trxn',
+      'civicrm_financial_item',
+      'civicrm_contribution_recur',
+      'civicrm_line_item',
+      'civicrm_contribution_page',
+      'civicrm_payment_processor',
+      'civicrm_entity_financial_trxn',
+      'civicrm_membership',
+      'civicrm_membership_type',
+      'civicrm_membership_payment',
+      'civicrm_membership_log',
+      'civicrm_membership_block',
+      'civicrm_event',
+      'civicrm_participant',
+      'civicrm_participant_payment',
+      'civicrm_pledge',
+      'civicrm_price_set_entity',
+      'civicrm_price_field_value',
+      'civicrm_price_field',
+    );
+    $this->quickCleanup($tablesToTruncate);
+    CRM_Core_DAO::executeQuery("DELETE FROM civicrm_membership_status WHERE name NOT IN('New', 'Current', 'Grace', 'Expired', 'Pending', 'Cancelled', 'Deceased')");
+    $this->restoreDefaultPriceSetConfig();
+  }
+
+  function restoreDefaultPriceSetConfig() {
+    CRM_Core_DAO::executeQuery("INSERT INTO `civicrm_price_field` (`id`, `price_set_id`, `name`, `label`, `html_type`, `is_enter_qty`, `help_pre`, `help_post`, `weight`, `is_display_amounts`, `options_per_line`, `is_active`, `is_required`, `active_on`, `expire_on`, `javascript`, `visibility_id`) VALUES (1, 1, 'contribution_amount', 'Contribution Amount', 'Text', 0, NULL, NULL, 1, 1, 1, 1, 1, NULL, NULL, NULL, 1)");
+    CRM_Core_DAO::executeQuery("INSERT INTO `civicrm_price_field_value` (`id`, `price_field_id`, `name`, `label`, `description`, `amount`, `count`, `max_value`, `weight`, `membership_type_id`, `membership_num_terms`, `is_default`, `is_active`, `financial_type_id`, `deductible_amount`) VALUES (1, 1, 'contribution_amount', 'Contribution Amount', NULL, '1', NULL, NULL, 1, NULL, NULL, 0, 1, 1, 0.00)");
+  }
   /*
    * Function does a 'Get' on the entity & compares the fields in the Params with those returned
    * Default behaviour is to also delete the entity
@@ -2132,6 +2406,15 @@ AND    ( TABLE_NAME LIKE 'civicrm_value_%' )
    * @param string $errorText text to print on error
    *
    */
+  /**
+   * @param $params
+   * @param $id
+   * @param $entity
+   * @param int $delete
+   * @param string $errorText
+   *
+   * @throws Exception
+   */
   function getAndCheck($params, $id, $entity, $delete = 1, $errorText = '') {
 
     $result = $this->callAPISuccessGetSingle($entity, array(
@@ -2215,7 +2498,7 @@ AND    ( TABLE_NAME LIKE 'civicrm_value_%' )
     if (array_key_exists('id', $unformattedArray)) {
       unset($unformattedArray['id']);
     }
-    if (CRM_Utils_Array::value('values', $unformattedArray) && is_array($unformattedArray['values'])) {
+    if (!empty($unformattedArray['values']) && is_array($unformattedArray['values'])) {
       foreach ($unformattedArray['values'] as $key => $value) {
         if (is_Array($value)) {
           foreach ($value as $k => $v) {
@@ -2268,7 +2551,8 @@ AND    ( TABLE_NAME LIKE 'civicrm_value_%' )
   /**
    * Generate a temporary folder
    *
-   * @return $string
+   * @param string $prefix
+   * @return string $string
    */
   function createTempDir($prefix = 'test-') {
     $tempDir = CRM_Utils_File::tempdir($prefix);
@@ -2329,6 +2613,9 @@ AND    ( TABLE_NAME LIKE 'civicrm_value_%' )
     }
   }
 
+  /**
+   * @param $name
+   */
   function financialAccountDelete($name) {
     $financialAccount = new CRM_Financial_DAO_FinancialAccount();
     $financialAccount->name = $name;
@@ -2525,15 +2812,18 @@ AND    ( TABLE_NAME LIKE 'civicrm_value_%' )
 
   /**
    * Set up an acl allowing contact to see 2 specified groups
-   *  - $this->_permissionedGroup & $this->_permissionedDisbaledGroup
+   *  - $this->_permissionedGroup & $this->_permissionedDisabledGroup
    *
-   *  You need to have precreated these groups & created the user e.g
+   *  You need to have pre-created these groups & created the user e.g
    *  $this->createLoggedInUser();
    *   $this->_permissionedDisabledGroup = $this->groupCreate(array('title' => 'pick-me-disabled', 'is_active' => 0, 'name' => 'pick-me-disabled'));
    *   $this->_permissionedGroup = $this->groupCreate(array('title' => 'pick-me-active', 'is_active' => 1, 'name' => 'pick-me-active'));
    *
    */
   function setupACL() {
+    global $_REQUEST;
+    $_REQUEST = $this->_params;
+
     CRM_Core_Config::singleton()->userPermissionClass->permissions = array('access CiviCRM');
     $optionGroupID = $this->callAPISuccessGetValue('option_group', array('return' => 'id', 'name' => 'acl_role'));
     $optionValue = $this->callAPISuccess('option_value', 'create', array('option_group_id' => $optionGroupID,
@@ -2581,7 +2871,30 @@ AND    ( TABLE_NAME LIKE 'civicrm_value_%' )
     ));
     //flush cache
     CRM_ACL_BAO_Cache::resetCache();
-      CRM_ACL_API::groupPermission('whatever', 9999, NULL, 'civicrm_saved_search', NULL, NULL, TRUE);
+    CRM_Contact_BAO_Group::getPermissionClause(TRUE);
+    CRM_ACL_API::groupPermission('whatever', 9999, NULL, 'civicrm_saved_search', NULL, NULL, TRUE);
+  }
+
+  /**
+   * alter default price set so that the field numbers are not all 1 (hiding errors)
+   */
+  function offsetDefaultPriceSet() {
+    $contributionPriceSet = $this->callAPISuccess('price_set', 'getsingle', array('name' => 'default_contribution_amount'));
+    $firstID = $contributionPriceSet['id'];
+    $this->callAPISuccess('price_set', 'create', array('id' => $contributionPriceSet['id'], 'is_active' => 0, 'name' => 'old'));
+    unset($contributionPriceSet['id']);
+    $newPriceSet = $this->callAPISuccess('price_set', 'create', $contributionPriceSet);
+    $priceField = $this->callAPISuccess('price_field', 'getsingle', array('price_set_id' => $firstID, 'options' => array('limit' => 1)));
+    unset($priceField['id']);
+    $priceField['price_set_id'] = $newPriceSet['id'];
+    $newPriceField = $this->callAPISuccess('price_field', 'create', $priceField);
+    $priceFieldValue = $this->callAPISuccess('price_field_value', 'getsingle', array('price_set_id' => $firstID, 'sequential' => 1, 'options' => array('limit' => 1)));
+
+    unset($priceFieldValue['id']);
+    //create some padding to use up ids
+    $this->callAPISuccess('price_field_value', 'create', $priceFieldValue);
+    $this->callAPISuccess('price_field_value', 'create', $priceFieldValue);
+    $this->callAPISuccess('price_field_value', 'create', array_merge($priceFieldValue, array('price_field_id' => $newPriceField['id'])));
   }
 
 /**
@@ -2621,9 +2934,40 @@ AND    ( TABLE_NAME LIKE 'civicrm_value_%' )
    $result = $this->callAPISuccess('payment_processor', 'create', $params);
    return $result['id'];
  }
+  /**
+   * Set up initial recurring payment allowing subsequent IPN payments
+   */
+  function setupRecurringPaymentProcessorTransaction() {
+    $contributionRecur = $this->callAPISuccess('contribution_recur', 'create', array(
+      'contact_id' => $this->_contactID,
+      'amount' => 1000,
+      'sequential' => 1,
+      'installments' => 5,
+      'frequency_unit' => 'Month',
+      'frequency_interval' => 1,
+      'invoice_id' => $this->_invoiceID,
+      'contribution_status_id' => 2,
+      'processor_id' => $this->_paymentProcessorID,
+      'api.contribution.create' => array(
+        'total_amount' => '200',
+        'invoice_id' => $this->_invoiceID,
+        'financial_type_id' => 1,
+        'contribution_status_id' => 'Pending',
+        'contact_id' => $this->_contactID,
+        'contribution_page_id' => $this->_contributionPageID,
+        'payment_processor_id' => $this->_paymentProcessorID,
+      )
+    ));
+    $this->_contributionRecurID = $contributionRecur['id'];
+    $this->_contributionID = $contributionRecur['values']['0']['api.contribution.create']['id'];
+  }
 
 
-function CiviUnitTestCase_fatalErrorHandler($message) {
+  /**
+   * @param $message
+   *
+   * @throws Exception
+   */function CiviUnitTestCase_fatalErrorHandler($message) {
   throw new Exception("{$message['message']}: {$message['code']}");
 }
 }