--- /dev/null
+<?php
+
+namespace Civi\Test;
+
+/**
+ * Class Api3TestTrait
+ * @package Civi\Test
+ *
+ * This trait defines a number of helper functions for testing APIv3. Commonly
+ * used helpers include `callAPISuccess()`, `callAPIFailure()`,
+ * `assertAPISuccess()`, and `assertAPIFailure()`.
+ *
+ * This trait is intended for use with PHPUnit-based test cases.
+ */
+trait Api3TestTrait {
+
+ /**
+ * Api version - easier to override than just a define
+ */
+ protected $_apiversion = 3;
+
+ /**
+ * Check that api returned 'is_error' => 1
+ * else provide full message
+ * @param array $result
+ * @param $expected
+ * @param array $valuesToExclude
+ * @param string $prefix
+ * Extra test to add to message.
+ */
+ public function assertAPIArrayComparison($result, $expected, $valuesToExclude = array(), $prefix = '') {
+ $valuesToExclude = array_merge($valuesToExclude, array('debug', 'xdebug', 'sequential'));
+ foreach ($valuesToExclude as $value) {
+ if (isset($result[$value])) {
+ unset($result[$value]);
+ }
+ if (isset($expected[$value])) {
+ unset($expected[$value]);
+ }
+ }
+ $this->assertEquals($result, $expected, "api result array comparison failed " . $prefix . print_r($result, TRUE) . ' was compared to ' . print_r($expected, TRUE));
+ }
+
+ /**
+ * Check that a deleted item has been deleted.
+ *
+ * @param $entity
+ * @param $id
+ */
+ public function assertAPIDeleted($entity, $id) {
+ $this->callAPISuccess($entity, 'getcount', array('id' => $id), 0);
+ }
+
+ /**
+ * Check that api returned 'is_error' => 1.
+ *
+ * @param array $apiResult
+ * Api result.
+ * @param string $prefix
+ * Extra test to add to message.
+ * @param null $expectedError
+ */
+ public function assertAPIFailure($apiResult, $prefix = '', $expectedError = NULL) {
+ if (!empty($prefix)) {
+ $prefix .= ': ';
+ }
+ if ($expectedError && !empty($apiResult['is_error'])) {
+ $this->assertEquals($expectedError, $apiResult['error_message'], 'api error message not as expected' . $prefix);
+ }
+ $this->assertEquals(1, $apiResult['is_error'], "api call should have failed but it succeeded " . $prefix . (print_r($apiResult, TRUE)));
+ $this->assertNotEmpty($apiResult['error_message']);
+ }
+
+ /**
+ * Check that api returned 'is_error' => 0.
+ *
+ * @param array $apiResult
+ * Api result.
+ * @param string $prefix
+ * Extra test to add to message.
+ */
+ public function assertAPISuccess($apiResult, $prefix = '') {
+ if (!empty($prefix)) {
+ $prefix .= ': ';
+ }
+ $errorMessage = empty($apiResult['error_message']) ? '' : " " . $apiResult['error_message'];
+
+ if (!empty($apiResult['debug_information'])) {
+ $errorMessage .= "\n " . print_r($apiResult['debug_information'], TRUE);
+ }
+ if (!empty($apiResult['trace'])) {
+ $errorMessage .= "\n" . print_r($apiResult['trace'], TRUE);
+ }
+ $this->assertEquals(0, $apiResult['is_error'], $prefix . $errorMessage);
+ }
+
+ /**
+ * This function exists to wrap api functions.
+ * so we can ensure they fail where expected & throw exceptions without litterering the test with checks
+ * @param string $entity
+ * @param string $action
+ * @param array $params
+ * @param string $expectedErrorMessage
+ * Error.
+ * @param null $extraOutput
+ * @return array|int
+ */
+ public function callAPIFailure($entity, $action, $params, $expectedErrorMessage = NULL, $extraOutput = NULL) {
+ if (is_array($params)) {
+ $params += array(
+ 'version' => $this->_apiversion,
+ );
+ }
+ $result = $this->civicrm_api($entity, $action, $params);
+ $this->assertAPIFailure($result, "We expected a failure for $entity $action but got a success", $expectedErrorMessage);
+ return $result;
+ }
+
+ /**
+ * 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
+ * @param mixed $checkAgainst
+ * Optional value to check result against, implemented for getvalue,.
+ * 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
+ */
+ public function callAPISuccess($entity, $action, $params, $checkAgainst = NULL) {
+ $params = array_merge(array(
+ 'version' => $this->_apiversion,
+ 'debug' => 1,
+ ),
+ $params
+ );
+ switch (strtolower($action)) {
+ case 'getvalue':
+ return $this->callAPISuccessGetValue($entity, $params, $checkAgainst);
+
+ case 'getsingle':
+ return $this->callAPISuccessGetSingle($entity, $params, $checkAgainst);
+
+ case 'getcount':
+ return $this->callAPISuccessGetCount($entity, $params, $checkAgainst);
+ }
+ $result = $this->civicrm_api($entity, $action, $params);
+ $this->assertAPISuccess($result, "Failure in api call for $entity $action");
+ 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 null $count
+ * @throws Exception
+ * @return array|int
+ */
+ public function callAPISuccessGetCount($entity, $params, $count = NULL) {
+ $params += array(
+ 'version' => $this->_apiversion,
+ 'debug' => 1,
+ );
+ $result = $this->civicrm_api($entity, 'getcount', $params);
+ if (!is_int($result) || !empty($result['is_error']) || isset($result['values'])) {
+ throw new Exception('Invalid getcount result : ' . print_r($result, TRUE) . " type :" . gettype($result));
+ }
+ if (is_int($count)) {
+ $this->assertEquals($count, $result, "incorrect count returned from $entity getcount");
+ }
+ return $result;
+ }
+
+ /**
+ * 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.
+ * - boolean
+ * - integer
+ * - double
+ * - string
+ * - array
+ * - object
+ *
+ * @throws Exception
+ * @return array|int
+ */
+ public function callAPISuccessGetSingle($entity, $params, $checkAgainst = NULL) {
+ $params += array(
+ 'version' => $this->_apiversion,
+ );
+ $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));
+ }
+ if ($checkAgainst) {
+ // @todo - have gone with the fn that unsets id? should we check id?
+ $this->checkArrayEquals($result, $checkAgainst);
+ }
+ 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.
+ * - boolean
+ * - integer
+ * - double
+ * - string
+ * - array
+ * - object
+ *
+ * @return array|int
+ */
+ public function callAPISuccessGetValue($entity, $params, $type = NULL) {
+ $params += array(
+ 'version' => $this->_apiversion,
+ 'debug' => 1,
+ );
+ $result = $this->civicrm_api($entity, 'getvalue', $params);
+ if ($type) {
+ if ($type == 'integer') {
+ // api seems to return integers as strings
+ $this->assertTrue(is_numeric($result), "expected a numeric value but got " . print_r($result, 1));
+ }
+ else {
+ $this->assertType($type, $result, "returned result should have been of type $type but was ");
+ }
+ }
+ return $result;
+ }
+
+ /**
+ * A stub for the API interface. This can be overriden by subclasses to change how the API is called.
+ *
+ * @param $entity
+ * @param $action
+ * @param array $params
+ * @return array|int
+ */
+ public function civicrm_api($entity, $action, $params) {
+ return civicrm_api($entity, $action, $params);
+ }
+
+}
*/
class CiviUnitTestCase extends PHPUnit_Extensions_Database_TestCase {
- /**
- * Api version - easier to override than just a define
- */
- protected $_apiversion = API_LATEST_VERSION;
+ use \Civi\Test\Api3TestTrait;
+
/**
* Database has been initialized.
*
);
}
- /**
- * Check that api returned 'is_error' => 0.
- *
- * @param array $apiResult
- * Api result.
- * @param string $prefix
- * Extra test to add to message.
- */
- public function assertAPISuccess($apiResult, $prefix = '') {
- if (!empty($prefix)) {
- $prefix .= ': ';
- }
- $errorMessage = empty($apiResult['error_message']) ? '' : " " . $apiResult['error_message'];
-
- if (!empty($apiResult['debug_information'])) {
- $errorMessage .= "\n " . print_r($apiResult['debug_information'], TRUE);
- }
- if (!empty($apiResult['trace'])) {
- $errorMessage .= "\n" . print_r($apiResult['trace'], TRUE);
- }
- $this->assertEquals(0, $apiResult['is_error'], $prefix . $errorMessage);
- }
-
- /**
- * Check that api returned 'is_error' => 1.
- *
- * @param array $apiResult
- * Api result.
- * @param string $prefix
- * Extra test to add to message.
- * @param null $expectedError
- */
- public function assertAPIFailure($apiResult, $prefix = '', $expectedError = NULL) {
- if (!empty($prefix)) {
- $prefix .= ': ';
- }
- if ($expectedError && !empty($apiResult['is_error'])) {
- $this->assertEquals($expectedError, $apiResult['error_message'], 'api error message not as expected' . $prefix);
- }
- $this->assertEquals(1, $apiResult['is_error'], "api call should have failed but it succeeded " . $prefix . (print_r($apiResult, TRUE)));
- $this->assertNotEmpty($apiResult['error_message']);
- }
-
/**
* @param $expected
* @param $actual
return $this->assertInternalType($expected, $actual, $message);
}
- /**
- * Check that a deleted item has been deleted.
- *
- * @param $entity
- * @param $id
- */
- public function assertAPIDeleted($entity, $id) {
- $this->callAPISuccess($entity, 'getcount', array('id' => $id), 0);
- }
-
-
- /**
- * Check that api returned 'is_error' => 1
- * else provide full message
- * @param array $result
- * @param $expected
- * @param array $valuesToExclude
- * @param string $prefix
- * Extra test to add to message.
- */
- public function assertAPIArrayComparison($result, $expected, $valuesToExclude = array(), $prefix = '') {
- $valuesToExclude = array_merge($valuesToExclude, array('debug', 'xdebug', 'sequential'));
- foreach ($valuesToExclude as $value) {
- if (isset($result[$value])) {
- unset($result[$value]);
- }
- if (isset($expected[$value])) {
- unset($expected[$value]);
- }
- }
- $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 array $params
- * @return array|int
- */
- public function civicrm_api($entity, $action, $params) {
- return civicrm_api($entity, $action, $params);
- }
-
/**
* Create a batch of external API calls which can
* be executed concurrently.
return $calls;
}
- /**
- * 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
- * @param mixed $checkAgainst
- * Optional value to check result against, implemented for getvalue,.
- * 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
- */
- public function callAPISuccess($entity, $action, $params, $checkAgainst = NULL) {
- $params = array_merge(array(
- 'version' => $this->_apiversion,
- 'debug' => 1,
- ),
- $params
- );
- switch (strtolower($action)) {
- case 'getvalue':
- return $this->callAPISuccessGetValue($entity, $params, $checkAgainst);
-
- case 'getsingle':
- return $this->callAPISuccessGetSingle($entity, $params, $checkAgainst);
-
- case 'getcount':
- return $this->callAPISuccessGetCount($entity, $params, $checkAgainst);
- }
- $result = $this->civicrm_api($entity, $action, $params);
- $this->assertAPISuccess($result, "Failure in api call for $entity $action");
- 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.
- * - boolean
- * - integer
- * - double
- * - string
- * - array
- * - object
- *
- * @return array|int
- */
- public function callAPISuccessGetValue($entity, $params, $type = NULL) {
- $params += array(
- 'version' => $this->_apiversion,
- 'debug' => 1,
- );
- $result = $this->civicrm_api($entity, 'getvalue', $params);
- if ($type) {
- if ($type == 'integer') {
- // api seems to return integers as strings
- $this->assertTrue(is_numeric($result), "expected a numeric value but got " . print_r($result, 1));
- }
- else {
- $this->assertType($type, $result, "returned result should have been of type $type but was ");
- }
- }
- return $result;
- }
-
- /**
- * 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.
- * - boolean
- * - integer
- * - double
- * - string
- * - array
- * - object
- *
- * @throws Exception
- * @return array|int
- */
- public function callAPISuccessGetSingle($entity, $params, $checkAgainst = NULL) {
- $params += array(
- 'version' => $this->_apiversion,
- );
- $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));
- }
- if ($checkAgainst) {
- // @todo - have gone with the fn that unsets id? should we check id?
- $this->checkArrayEquals($result, $checkAgainst);
- }
- 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 null $count
- * @throws Exception
- * @return array|int
- */
- public function callAPISuccessGetCount($entity, $params, $count = NULL) {
- $params += array(
- 'version' => $this->_apiversion,
- 'debug' => 1,
- );
- $result = $this->civicrm_api($entity, 'getcount', $params);
- if (!is_int($result) || !empty($result['is_error']) || isset($result['values'])) {
- throw new Exception('Invalid getcount result : ' . print_r($result, TRUE) . " type :" . gettype($result));
- }
- if (is_int($count)) {
- $this->assertEquals($count, $result, "incorrect count returned from $entity getcount");
- }
- return $result;
- }
/**
* This function exists to wrap api functions.
return $result;
}
- /**
- * This function exists to wrap api functions.
- * so we can ensure they fail where expected & throw exceptions without litterering the test with checks
- * @param string $entity
- * @param string $action
- * @param array $params
- * @param string $expectedErrorMessage
- * Error.
- * @param null $extraOutput
- * @return array|int
- */
- public function callAPIFailure($entity, $action, $params, $expectedErrorMessage = NULL, $extraOutput = NULL) {
- if (is_array($params)) {
- $params += array(
- 'version' => $this->_apiversion,
- );
- }
- $result = $this->civicrm_api($entity, $action, $params);
- $this->assertAPIFailure($result, "We expected a failure for $entity $action but got a success", $expectedErrorMessage);
- return $result;
- }
-
/**
* Create required data based on $this->entity & $this->params
* This is just a way to set up the test data for delete & get functions