From 135976c32e5058de4cd77feb3cd623a545dfe97a Mon Sep 17 00:00:00 2001 From: Eileen McNaughton Date: Wed, 5 Nov 2014 02:03:29 +1300 Subject: [PATCH] synchronise test classes with 4.6 so we aren't constantly re-solving test-related problems --- CRM/Member/BAO/Membership.php | 7 +- tests/phpunit/CiviTest/CiviUnitTestCase.php | 645 ++++++++++++++++---- 2 files changed, 520 insertions(+), 132 deletions(-) diff --git a/CRM/Member/BAO/Membership.php b/CRM/Member/BAO/Membership.php index 6f27098fd7..3b8c10f0f0 100644 --- a/CRM/Member/BAO/Membership.php +++ b/CRM/Member/BAO/Membership.php @@ -1989,8 +1989,13 @@ WHERE civicrm_membership.contact_id = civicrm_contact.id * @static * @access public */ - static function createRelatedMemberships(&$params, &$dao) { + static function createRelatedMemberships(&$params, &$dao, $reset = FALSE) { static $relatedContactIds = array(); + if ($reset) { + // not sure why a static var is in use here - we need a way to reset it from the test suite + $relatedContactIds = array(); + return; + } $membership = new CRM_Member_DAO_Membership(); $membership->id = $dao->id; diff --git a/tests/phpunit/CiviTest/CiviUnitTestCase.php b/tests/phpunit/CiviTest/CiviUnitTestCase.php index 496ca2df3b..403c7b51b8 100644 --- a/tests/phpunit/CiviTest/CiviUnitTestCase.php +++ b/tests/phpunit/CiviTest/CiviUnitTestCase.php @@ -82,6 +82,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 +166,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; @@ -308,13 +319,16 @@ 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()); } /** * Common setup functions for all unit tests */ protected function setUp() { + $session = CRM_Core_Session::singleton(); + $session->set('userID', NULL); + CRM_Utils_Hook::singleton(TRUE); $this->errorScope = CRM_Core_TemporaryErrorScope::useException(); // REVERT // Use a temporary file for STDIN @@ -366,6 +380,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 +441,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 +527,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 +548,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 +573,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 +585,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 +601,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 +666,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 +684,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 +695,10 @@ class CiviUnitTestCase extends PHPUnit_Extensions_Database_TestCase { )); } + /** + * @param $key + * @param $list + */ function assertArrayValueNotNull($key, &$list) { $this->assertArrayKeyExists($key, $list); @@ -635,8 +734,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 +750,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 +770,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 +789,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 +812,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( @@ -704,9 +828,9 @@ class CiviUnitTestCase extends PHPUnit_Extensions_Database_TestCase { case 'getsingle' : return $this->callAPISuccessGetSingle($entity, $params, $checkAgainst); case 'getcount' : - return $this->callAPISuccessGetCount($entity, $params, $checkAgainst); + 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 +839,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 +849,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 +873,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 +883,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 +902,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 +925,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 +934,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 +944,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 +963,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 +972,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,12 +1059,11 @@ 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' - ); - $params['prefix_id'] = 3; - $params['suffix_id'] = 3; + $params['email'] = strtolower( + $params['first_name'] . '_' . $params['last_name'] . '@civicrm.org' + ); + $params['prefix_id'] = 3; + $params['suffix_id'] = 3; } return $params; } @@ -939,14 +1080,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 +1108,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 +1121,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 +1151,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 +1177,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 +1210,9 @@ class CiviUnitTestCase extends PHPUnit_Extensions_Database_TestCase { return $result['id']; } + /** + * @param $membershipStatusID + */ function membershipStatusDelete($membershipStatusID) { if (!$membershipStatusID) { return; @@ -1050,6 +1221,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', @@ -1059,7 +1235,7 @@ class CiviUnitTestCase extends PHPUnit_Extensions_Database_TestCase { 'is_reserved' => 1, 'is_active' => 1, ), - $params + $params ); $result = $this->callAPISuccess('relationship_type', 'create', $params); @@ -1078,6 +1254,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 +1331,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 +1353,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 +1384,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 +1396,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 +1425,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 +1438,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 +1475,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 +1503,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 +1556,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 +1571,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 +1584,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 +1614,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 +1654,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,22 +1692,22 @@ 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( - 'name' => 'Test Group 1', - 'domain_id' => 1, - 'title' => 'New Test Group Created', - 'description' => 'New Test Group Created', - 'is_active' => 1, - 'visibility' => 'Public Pages', - 'group_type' => array( - '1' => 1, - '2' => 1, - ), - ), $params); + 'name' => 'Test Group 1', + 'domain_id' => 1, + 'title' => 'New Test Group Created', + 'description' => 'New Test Group Created', + 'is_active' => 1, + 'visibility' => 'Public Pages', + 'group_type' => array( + '1' => 1, + '2' => 1, + ), + ), $params); $result = $this->callAPISuccess('Group', 'create', $params); return $result['id']; @@ -1512,7 +1716,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 +1746,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 +1805,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 +1884,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( @@ -1693,7 +1905,7 @@ class CiviUnitTestCase extends PHPUnit_Extensions_Database_TestCase { } //have a crack @ deleting it first in the hope this will prevent derailing our tests - $check = $this->callAPISuccess('custom_group', 'get', array('title' => $params['title'], array('api.custom_group.delete' => 1))); + $this->callAPISuccess('custom_group', 'get', array('title' => $params['title'], array('api.custom_group.delete' => 1))); return $this->callAPISuccess('custom_group', 'create', $params); } @@ -1753,10 +1965,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 +1984,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 +1997,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 +2025,8 @@ class CiviUnitTestCase extends PHPUnit_Extensions_Database_TestCase { * Function to delete custom field * * @param int $customFieldID + * + * @return array|int */ function customFieldDelete($customFieldID) { @@ -1822,6 +2039,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 +2080,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 +2106,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 +2186,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)) { @@ -2003,33 +2232,33 @@ class CiviUnitTestCase extends PHPUnit_Extensions_Database_TestCase { } foreach ($resultArray as $index => &$values) { - if(!is_array($values)) { - continue; - } - foreach($values as $key => &$value) { - if(substr($key, 0, 3) == 'api' && is_array($value)) { - if(isset($value['is_error'])) { - // we have a std nested result format - $this->tidyExampleResult($value); - } - else{ - foreach ($value as &$nestedResult) { - // this is an alternative syntax for nested results a keyed array of results - $this->tidyExampleResult($nestedResult); - } - } - } - if(in_array($key, $keysToUnset)) { - unset($values[$key]); - break; - } - if(array_key_exists($key, $fieldsToChange) && !empty($value)) { - $value = $fieldsToChange[$key]; + if(!is_array($values)) { + continue; + } + foreach($values as $key => &$value) { + if(substr($key, 0, 3) == 'api' && is_array($value)) { + if(isset($value['is_error'])) { + // we have a std nested result format + $this->tidyExampleResult($value); } - if(is_string($value)) { - $value = addslashes($value); + else{ + foreach ($value as &$nestedResult) { + // this is an alternative syntax for nested results a keyed array of results + $this->tidyExampleResult($nestedResult); + } } } + if(in_array($key, $keysToUnset)) { + unset($values[$key]); + break; + } + if(array_key_exists($key, $fieldsToChange) && !empty($value)) { + $value = $fieldsToChange[$key]; + } + if(is_string($value)) { + $value = addslashes($value); + } + } } } @@ -2046,8 +2275,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 +2312,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 +2328,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 +2364,44 @@ 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(); + $var = TRUE; + CRM_Member_BAO_Membership::createRelatedMemberships($var, $var, TRUE); + } + + 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 +2412,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 +2504,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 +2557,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 +2619,9 @@ AND ( TABLE_NAME LIKE 'civicrm_value_%' ) } } + /** + * @param $name + */ function financialAccountDelete($name) { $financialAccount = new CRM_Financial_DAO_FinancialAccount(); $financialAccount->name = $name; @@ -2525,15 +2818,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,49 +2877,136 @@ 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_ACL_API::groupPermission('whatever', 9999, NULL, 'civicrm_saved_search', NULL, NULL, TRUE); } -/** - * Create an instance of the paypal processor - * @todo this isn't a great place to put it - but really it belongs on a class that extends - * this parent class & we don't have a structure for that yet - * There is another function to this effect on the PaypalPro test but it appears to be silently failing - * & the best protection agains that is the functions this class affords - */ - function paymentProcessorCreate($params = array()) { - $params = array_merge(array( - 'name' => 'demo', - 'domain_id' => CRM_Core_Config::domainID(), - 'payment_processor_type_id' => 'PayPal', - 'is_active' => 1, - 'is_default' => 0, - 'is_test' => 1, - 'user_name' => 'sunil._1183377782_biz_api1.webaccess.co.in', - 'password' => '1183377788', - 'signature' => 'APixCoQ-Zsaj-u3IH7mD5Do-7HUqA9loGnLSzsZga9Zr-aNmaJa3WGPH', - 'url_site' => 'https://www.sandbox.paypal.com/', - 'url_api' => 'https://api-3t.sandbox.paypal.com/', - 'url_button' => 'https://www.paypal.com/en_US/i/btn/btn_xpressCheckout.gif', - 'class_name' => 'Payment_PayPalImpl', - 'billing_mode' => 3, - 'financial_type_id' => 1, - ), - $params); - if(!is_numeric($params['payment_processor_type_id'])) { - // really the api should handle this through getoptions but it's not exactly api call so lets just sort it - //here - $params['payment_processor_type_id'] = $this->callAPISuccess('payment_processor_type', 'getvalue', array( - 'name' => $params['payment_processor_type_id'], - 'return' => 'id', - ), 'integer'); - } - $result = $this->callAPISuccess('payment_processor', 'create', $params); - return $result['id']; - } - - -function CiviUnitTestCase_fatalErrorHandler($message) { - throw new Exception("{$message['message']}: {$message['code']}"); -} + /** + * 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']))); + } + + /** + * Create an instance of the paypal processor + * @todo this isn't a great place to put it - but really it belongs on a class that extends + * this parent class & we don't have a structure for that yet + * There is another function to this effect on the PaypalPro test but it appears to be silently failing + * & the best protection agains that is the functions this class affords + */ + function paymentProcessorCreate($params = array()) { + $params = array_merge(array( + 'name' => 'demo', + 'domain_id' => CRM_Core_Config::domainID(), + 'payment_processor_type_id' => 'PayPal', + 'is_active' => 1, + 'is_default' => 0, + 'is_test' => 1, + 'user_name' => 'sunil._1183377782_biz_api1.webaccess.co.in', + 'password' => '1183377788', + 'signature' => 'APixCoQ-Zsaj-u3IH7mD5Do-7HUqA9loGnLSzsZga9Zr-aNmaJa3WGPH', + 'url_site' => 'https://www.sandbox.paypal.com/', + 'url_api' => 'https://api-3t.sandbox.paypal.com/', + 'url_button' => 'https://www.paypal.com/en_US/i/btn/btn_xpressCheckout.gif', + 'class_name' => 'Payment_PayPalImpl', + 'billing_mode' => 3, + 'financial_type_id' => 1, + ), + $params); + if(!is_numeric($params['payment_processor_type_id'])) { + // really the api should handle this through getoptions but it's not exactly api call so lets just sort it + //here + $params['payment_processor_type_id'] = $this->callAPISuccess('payment_processor_type', 'getvalue', array( + 'name' => $params['payment_processor_type_id'], + 'return' => 'id', + ), 'integer'); + } + $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']; + } + + /** + * we don't have a good way to set up a recurring contribution with a membership so let's just do one then alter it + */ + function setupMembershipRecurringPaymentProcessorTransaction() { + $this->ids['membership_type'] = $this->membershipTypeCreate(); + //create a contribution so our membership & contribution don't both have id = 1 + $this->contributionCreate($this->_contactID, 1, 'abcd', '345j'); + $this->setupRecurringPaymentProcessorTransaction(); + + $this->ids['membership'] = $this->callAPISuccess('membership', 'create', array( + 'contact_id' => $this->_contactID, + 'membership_type_id' => $this->ids['membership_type'], + 'contribution_recur_id' => $this->_contributionRecurID, + 'format.only_id' => TRUE, + )); + //CRM-15055 creates line items we don't want so get rid of them so we can set up our own line items + CRM_Core_DAO::executeQuery("TRUNCATE civicrm_line_item"); + + $this->callAPISuccess('line_item', 'create', array( + 'entity_table' => 'civicrm_membership', + 'entity_id' => $this->ids['membership'], + 'contribution_id' => $this->_contributionID, + 'label' => 'General', + 'qty' => 1, + 'unit_price' => 200, + 'line_total' => 200, + 'financial_type_id' => 1, + 'price_field_id' => $this->callAPISuccess('price_field', 'getvalue', array('return' => 'id', 'label' => 'Membership Amount')), + 'price_field_value_id' => $this->callAPISuccess('price_field_value', 'getvalue', array('return' => 'id', 'label' => 'General')), + )); + $this->callAPISuccess('membership_payment', 'create', array('contribution_id' => $this->_contributionID, 'membership_id' => $this->ids['membership'])); + } + + /** + * @param $message + * + * @throws Exception + */ + function CiviUnitTestCase_fatalErrorHandler($message) { + throw new Exception("{$message['message']}: {$message['code']}"); + } } -- 2.25.1