Code Coverage |
||||||||||
Classes and Traits |
Functions and Methods |
Lines |
||||||||
Total | |
0.00% |
0 / 1 |
|
0.00% |
0 / 19 |
CRAP | |
0.00% |
0 / 165 |
REST | |
0.00% |
0 / 1 |
|
0.00% |
0 / 19 |
2070 | |
0.00% |
0 / 165 |
_before(\Codeception\TestCase $test) | |
0.00% |
0 / 1 |
56 | |
0.00% |
0 / 26 |
|||
haveHttpHeader($name, $value) | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 4 |
|||
amHttpAuthenticated($username, $password) | |
0.00% |
0 / 1 |
6 | |
0.00% |
0 / 9 |
|||
sendPOST($url, $params = array() | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 4 |
|||
sendGET($url, $params = array() | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 4 |
|||
sendPUT($url, $params = array() | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 4 |
|||
sendDELETE($url, $params = array() | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 4 |
|||
execute($method = 'GET', $url, $parameters = array() | |
0.00% |
0 / 1 |
156 | |
0.00% |
0 / 30 |
|||
seeResponseIsJson() | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 9 |
|||
seeResponseContains($text) | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 4 |
|||
dontSeeResponseContains($text) | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 4 |
|||
seeResponseContainsJson($json = array() | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 8 |
|||
grabResponse() | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 4 |
|||
grabDataFromJsonResponse($path) | |
0.00% |
0 / 1 |
20 | |
0.00% |
0 / 16 |
|||
arrayIntersectAssocRecursive($arr1, $arr2) | |
0.00% |
0 / 1 |
42 | |
0.00% |
0 / 15 |
|||
arrayHasArray(array $needle, array $haystack) | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 4 |
|||
dontSeeResponseContainsJson($json = array() | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 8 |
|||
seeResponseEquals($response) | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 4 |
|||
seeResponseCodeIs($num) | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 4 |
<?php | |
namespace Codeception\Module; | |
use Symfony\Component\BrowserKit\Cookie; | |
use Codeception\Exception\ModuleConfig as ModuleConfigException; | |
/** | |
* Module for testing REST WebService. | |
* | |
* This module can be used either with frameworks or PHPBrowser. | |
* It tries to guess the framework is is attached to. | |
* | |
* Whether framework is used it operates via standard framework modules. | |
* Otherwise sends raw HTTP requests to url via PHPBrowser. | |
* | |
* ## Configuration | |
* | |
* * url *optional* - the url of api | |
* | |
* ## Public Properties | |
* | |
* * headers - array of headers going to be sent. | |
* * params - array of sent data | |
* * response - last response (string) | |
* | |
* | |
*/ | |
class REST extends \Codeception\Module | |
{ | |
protected $config = array('url' => ''); | |
/** | |
* @var \Symfony\Component\BrowserKit\Client|\Behat\Mink\Driver\Goutte\Client | |
*/ | |
public $client = null; | |
public $is_functional = false; | |
public $headers = array(); | |
public $params = array(); | |
public $response = ""; | |
public function _before(\Codeception\TestCase $test) | |
{ | |
if (!$this->client) { | |
if (!strpos($this->config['url'], '://')) { | |
// not valid url | |
foreach ($this->getModules() as $module) { | |
if ($module instanceof \Codeception\Util\Framework) { | |
$this->client = $module->client; | |
$this->is_functional = true; | |
break; | |
} | |
} | |
} else { | |
if (!$this->hasModule('PhpBrowser')) { | |
throw new ModuleConfigException(__CLASS__, "For REST testing via HTTP please enable PhpBrowser module"); | |
} | |
$this->client = $this->getModule('PhpBrowser')->session->getDriver()->getClient(); | |
} | |
if (!$this->client) { | |
throw new ModuleConfigException(__CLASS__, "Client for REST requests not initialized.\nProvide either PhpBrowser module, or a framework module which shares FrameworkInterface"); | |
} | |
} | |
$this->headers = array(); | |
$this->params = array(); | |
$this->response = ""; | |
$this->client->setServerParameters(array()); | |
} | |
/** | |
* Sets HTTP header | |
* | |
* @param $name | |
* @param $value | |
*/ | |
public function haveHttpHeader($name, $value) | |
{ | |
$this->headers[$name] = $value; | |
} | |
/** | |
* Adds HTTP authentication via username/password. | |
* | |
* @param $username | |
* @param $password | |
*/ | |
public function amHttpAuthenticated($username, $password) | |
{ | |
if ($this->is_functional) { | |
$this->client->setServerParameter('PHP_AUTH_USER', $username); | |
$this->client->setServerParameter('PHP_AUTH_PW', $password); | |
} else { | |
$this->client->setAuth($username, $password); | |
} | |
} | |
/** | |
* Sends a POST request to given uri. | |
* | |
* Parameters and files (as array of filenames) can be provided. | |
* | |
* @param $url | |
* @param array $params | |
* @param array $files | |
*/ | |
public function sendPOST($url, $params = array(), $files = array()) | |
{ | |
$this->execute('POST', $url, $params, $files); | |
} | |
/** | |
* Sends a GET request to given uri. | |
* | |
* @param $url | |
* @param array $params | |
*/ | |
public function sendGET($url, $params = array()) | |
{ | |
$this->execute('GET', $url, $params); | |
} | |
/** | |
* Sends PUT request to given uri. | |
* | |
* @param $url | |
* @param array $params | |
* @param array $files | |
*/ | |
public function sendPUT($url, $params = array(), $files = array()) | |
{ | |
$this->execute('PUT', $url, $params, $files); | |
} | |
/** | |
* Sends DELETE request to given uri. | |
* | |
* @param $url | |
* @param array $params | |
* @param array $files | |
*/ | |
public function sendDELETE($url, $params = array(), $files = array()) | |
{ | |
$this->execute('DELETE', $url, $params, $files); | |
} | |
protected function execute($method = 'GET', $url, $parameters = array(), $files = array()) | |
{ | |
foreach ($this->headers as $header => $val) { | |
$this->client->setServerParameter("HTTP_$header", $val); | |
} | |
// allow full url to be requested | |
$url = (strpos($url, '://') === false ? $this->config['url'] : '') . $url; | |
if (is_array($parameters) || $parameters instanceof \ArrayAccess) { | |
$parameters = $this->scalarizeArray($parameters); | |
if (array_key_exists('Content-Type', $this->headers) | |
&& $this->headers['Content-Type'] === 'application/json' | |
&& $method != 'GET' | |
) { | |
$parameters = json_encode($parameters); | |
} | |
} | |
if (is_array($parameters) || $method == 'GET') { | |
if ($method == 'GET' && !empty($parameters)) { | |
$url .= '?' . http_build_query($parameters); | |
$this->debugSection("Request", "$method $url"); | |
} else { | |
$this->debugSection("Request", "$method $url?" . http_build_query($parameters)); | |
} | |
$this->client->request($method, $url, $parameters, $files); | |
} else { | |
$this->debugSection("Request", "$method $url " . $parameters); | |
$this->client->request($method, $url, array(), $files, array(), $parameters); | |
} | |
$this->response = $this->client->getResponse()->getContent(); | |
$this->debugSection("Response", $this->response); | |
} | |
/** | |
* Checks weather last response was valid JSON. | |
* This is done with json_last_error function. | |
* | |
*/ | |
public function seeResponseIsJson() | |
{ | |
json_decode($this->response); | |
\PHPUnit_Framework_Assert::assertEquals( | |
0, | |
$num = json_last_error(), | |
"json decoding error #$num, see http://php.net/manual/en/function.json-last-error.php" | |
); | |
} | |
/** | |
* Checks weather the last response contains text. | |
* | |
* @param $text | |
*/ | |
public function seeResponseContains($text) | |
{ | |
\PHPUnit_Framework_Assert::assertContains($text, $this->response, "REST response contains"); | |
} | |
/** | |
* Checks weather last response do not contain text. | |
* | |
* @param $text | |
*/ | |
public function dontSeeResponseContains($text) | |
{ | |
\PHPUnit_Framework_Assert::assertNotContains($text, $this->response, "REST response contains"); | |
} | |
/** | |
* Checks weather the last JSON response contains provided array. | |
* The response is converted to array with json_decode($response, true) | |
* Thus, JSON is represented by associative array. | |
* This method matches that response array contains provided array. | |
* | |
* Examples: | |
* | |
* ``` php | |
* <?php | |
* // response: {name: john, email: john@gmail.com} | |
* $I->seeResponseContainsJson(array('name' => 'john')); | |
* | |
* // response {user: john, profile: { email: john@gmail.com }} | |
* $I->seeResponseContainsJson(array('email' => 'john@gmail.com')); | |
* | |
* ?> | |
* ``` | |
* | |
* This method recursively checks if one array can be found inside of another. | |
* | |
* @param array $json | |
*/ | |
public function seeResponseContainsJson($json = array()) | |
{ | |
$resp_json = json_decode($this->response, true); | |
\PHPUnit_Framework_Assert::assertTrue( | |
$this->arrayHasArray($json, $resp_json), | |
"response JSON matches provided" | |
); | |
} | |
/** | |
* Returns current response so that it can be used in next scenario steps. | |
* | |
* Example: | |
* | |
* ``` php | |
* <?php | |
* $user_id = $I->grabResponse(); | |
* $I->sendPUT('/user', array('id' => $user_id, 'name' => 'davert')); | |
* ?> | |
* ``` | |
* | |
* @version 1.1 | |
* @return string | |
*/ | |
public function grabResponse() | |
{ | |
return $this->response; | |
} | |
/** | |
* Returns data from the current JSON response using specified path | |
* so that it can be used in next scenario steps | |
* | |
* Example: | |
* | |
* ``` php | |
* <?php | |
* $user_id = $I->grabDataFromJsonResponse('user.user_id'); | |
* $I->sendPUT('/user', array('id' => $user_id, 'name' => 'davert')); | |
* ?> | |
* ``` | |
* | |
* @param string $path | |
* | |
* @since 1.1.2 | |
* @return string | |
* | |
* @author tiger.seo@gmail.com | |
*/ | |
public function grabDataFromJsonResponse($path) | |
{ | |
$data = $response = json_decode($this->response, true); | |
if (json_last_error() !== JSON_ERROR_NONE) { | |
$this->fail('Response is not of JSON format or is malformed'); | |
$this->debugSection('Response', $this->response); | |
} | |
foreach (explode('.', $path) as $key) { | |
if (!array_key_exists($key, $data)) { | |
$this->fail('Response does not have required data'); | |
$this->debugSection('Response', $response); | |
} | |
$data = $data[$key]; | |
} | |
return $data; | |
} | |
/** | |
* @author nleippe@integr8ted.com | |
* @author tiger.seo@gmail.com | |
* @link http://www.php.net/manual/en/function.array-intersect-assoc.php#39822 | |
* | |
* @param mixed $arr1 | |
* @param mixed $arr2 | |
* | |
* @return array|bool | |
*/ | |
private function arrayIntersectAssocRecursive($arr1, $arr2) | |
{ | |
if (!is_array($arr1) || !is_array($arr2)) { | |
return $arr1 == $arr2 ? $arr1 : null; | |
} | |
$commonkeys = array_intersect(array_keys($arr1), array_keys($arr2)); | |
$ret = array(); | |
foreach ($commonkeys as $key) { | |
$_return = $this->arrayIntersectAssocRecursive($arr1[$key], $arr2[$key]); | |
if ($_return !== null) { | |
$ret[$key] = $_return; | |
} | |
} | |
return $ret; | |
} | |
protected function arrayHasArray(array $needle, array $haystack) | |
{ | |
return $needle == $this->arrayIntersectAssocRecursive($needle, $haystack); | |
} | |
/** | |
* Opposite to seeResponseContainsJson | |
* | |
* @param array $json | |
*/ | |
public function dontSeeResponseContainsJson($json = array()) | |
{ | |
$resp_json = json_decode($this->response, true); | |
\PHPUnit_Framework_Assert::assertFalse( | |
$this->arrayHasArray($json, $resp_json), | |
"response JSON matches provided" | |
); | |
} | |
/** | |
* Checks if response is exactly the same as provided. | |
* | |
* @param $response | |
*/ | |
public function seeResponseEquals($response) | |
{ | |
\PHPUnit_Framework_Assert::assertEquals($response, $this->$response); | |
} | |
/** | |
* Checks response code. | |
* | |
* @param $num | |
*/ | |
public function seeResponseCodeIs($num) | |
{ | |
\PHPUnit_Framework_Assert::assertEquals($num, $this->client->getResponse()->getStatus()); | |
} | |
} |