|
<?php |
|
|
|
namespace AppBundle\Tests\Api; |
|
|
|
use GuzzleHttp\ClientInterface; |
|
use GuzzleHttp\Event\Emitter; |
|
use GuzzleHttp\Event\EmitterInterface; |
|
use GuzzleHttp\Exception\RequestException; |
|
use GuzzleHttp\Message\MessageFactory; |
|
use GuzzleHttp\Message\Request; |
|
use GuzzleHttp\Message\RequestInterface; |
|
use GuzzleHttp\Message\Response; |
|
use GuzzleHttp\Stream\Stream; |
|
use Sanpi\Behatch\Json\Json; |
|
use AppBundle\Hydra\HydraClient; |
|
use AppBundle\Hydra\HydraFactory; |
|
|
|
class FakeGuzzleClient implements ClientInterface |
|
{ |
|
/** |
|
* @var EmitterInterface |
|
*/ |
|
private $emitter; |
|
|
|
/** |
|
* {@inheritdoc} |
|
*/ |
|
public function createRequest($method, $url = null, array $options = []) |
|
{ |
|
throw new \RuntimeException(sprintf('FakeGuzzleClient::createRequest is not implemented !')); |
|
} |
|
|
|
/** |
|
* {@inheritdoc} |
|
*/ |
|
public function get($url = null, $options = []) |
|
{ |
|
return $this->getResponse('GET', $url, $options); |
|
} |
|
|
|
/** |
|
* {@inheritdoc} |
|
*/ |
|
public function head($url = null, array $options = []) |
|
{ |
|
return $this->getResponse('HEAD', $url, $options); |
|
} |
|
|
|
/** |
|
* {@inheritdoc} |
|
*/ |
|
public function delete($url = null, array $options = []) |
|
{ |
|
return $this->getResponse('DELETE', $url, $options); |
|
} |
|
|
|
/** |
|
* {@inheritdoc} |
|
*/ |
|
public function put($url = null, array $options = []) |
|
{ |
|
return $this->getResponse('PUT', $url, $options); |
|
} |
|
|
|
/** |
|
* {@inheritdoc} |
|
*/ |
|
public function patch($url = null, array $options = []) |
|
{ |
|
return $this->getResponse('PATCH', $url, $options); |
|
} |
|
|
|
/** |
|
* {@inheritdoc} |
|
*/ |
|
public function post($url = null, array $options = []) |
|
{ |
|
return $this->getResponse('POST', $url, $options); |
|
} |
|
|
|
/** |
|
* {@inheritdoc} |
|
*/ |
|
public function options($url = null, array $options = []) |
|
{ |
|
return $this->getResponse('OPTIONS', $url, $options); |
|
} |
|
|
|
/** |
|
* {@inheritdoc} |
|
*/ |
|
public function send(RequestInterface $request) |
|
{ |
|
throw new \RuntimeException(sprintf('FakeGuzzleClient::send is not implemented !')); |
|
} |
|
|
|
/** |
|
* {@inheritdoc} |
|
*/ |
|
public function getDefaultOption($keyOrPath = null) |
|
{ |
|
throw new \RuntimeException(sprintf('FakeGuzzleClient::getDefaultOption is not implemented !')); |
|
} |
|
|
|
/** |
|
* {@inheritdoc} |
|
*/ |
|
public function setDefaultOption($keyOrPath, $value) |
|
{ |
|
throw new \RuntimeException(sprintf('FakeGuzzleClient::setDefaultOption is not implemented !')); |
|
} |
|
|
|
/** |
|
* {@inheritdoc} |
|
*/ |
|
public function getBaseUrl() |
|
{ |
|
throw new \RuntimeException(sprintf('FakeGuzzleClient::getBaseUrl is not implemented !')); |
|
} |
|
|
|
/** |
|
* {@inheritdoc} |
|
*/ |
|
public function getEmitter() |
|
{ |
|
if (!$this->emitter) { |
|
$this->emitter = new Emitter(); |
|
} |
|
|
|
return $this->emitter; |
|
} |
|
|
|
/** |
|
* This method will find the file corresponding to the URL, and return a response based on it. |
|
* |
|
* @param $method |
|
* @param $url |
|
* @param array $options |
|
* |
|
* @return Response |
|
*/ |
|
private function getResponse($method, $url, array $options = []) |
|
{ |
|
$parentDir = realpath(dirname(__FILE__).'/../../../../tmp/thom-api-mock/mocks/'); |
|
list($url, $options) = $this->cleanData($url, $options); |
|
$request = (new MessageFactory())->createRequest($method, $url, $options); |
|
$path = $this->getFilenameByRequest($request, $parentDir); |
|
|
|
if (!file_exists($path)) { |
|
throw new \RuntimeException(sprintf('Mock not found: %s', $path)); |
|
} |
|
|
|
$data = json_decode(file_get_contents($path)); |
|
$response = new Response($data->response->statusCode, [], Stream::factory(json_encode($data->response->content))); |
|
|
|
if ($data->response->statusCode >= 400) { |
|
$e = new RequestException('', $request, $response); |
|
HydraClient::generateException($e); |
|
} |
|
|
|
return HydraFactory::generate($response); |
|
} |
|
|
|
private function cleanData($url, array $options) |
|
{ |
|
if ('/get_token' === $url && isset($options['json']['refresh_token_key'])) { |
|
$options['json']['refresh_token_key'] = 'foobar'; |
|
} |
|
|
|
$baseUri = parse_url($url, PHP_URL_PATH); |
|
$query = parse_url($url, PHP_URL_QUERY); |
|
$url = ''; |
|
if ($query) { |
|
$query = explode('&', $query); |
|
sort($query); |
|
$url = '?'.implode('&', $query); |
|
} |
|
$url = $baseUri.$url; |
|
|
|
return [ |
|
$url, |
|
$options, |
|
]; |
|
} |
|
|
|
/** |
|
* Creates a filename string from a request object, with the following schema : |
|
* `uri/segments?query=string&others#METHOD-md5Content-md5JsonParams.json`. |
|
* |
|
* @param Request $request |
|
* @param string $parentDir |
|
* @param bool $useFirstUriSegmentAsDir |
|
* |
|
* @return string |
|
*/ |
|
private function getFilenameByRequest(Request $request, $parentDir = null, $useFirstUriSegmentAsDir = true) |
|
{ |
|
$requestUri = trim(parse_url($request->getUrl(), PHP_URL_PATH), '/'); |
|
$requestQueryString = parse_url($request->getUrl(), PHP_URL_QUERY); |
|
$requestMethod = $request->getMethod(); |
|
|
|
$content = json_decode((string) $request->getBody(), true); |
|
if ($content) { |
|
ksort($content); |
|
} |
|
|
|
$requestContent = $content |
|
? json_encode($content) |
|
: $requestContent = ''; |
|
|
|
$filename = $requestUri; |
|
|
|
if ($useFirstUriSegmentAsDir && 1 === count(explode('/', $filename))) { |
|
$filename .= '/'; |
|
} |
|
|
|
if (null !== $requestQueryString) { |
|
$filename .= '?'.$requestQueryString; |
|
} |
|
|
|
$filename .= '#'.$requestMethod; |
|
|
|
if ($requestContent) { |
|
try { |
|
$content = (new Json($requestContent))->encode(false); |
|
} catch (\Exception $e) { |
|
$content = $requestContent; |
|
} |
|
|
|
$filename .= '-'.substr(md5($content), 0, 5); |
|
} |
|
|
|
$filename .= '.json'; |
|
|
|
if ($parentDir) { |
|
return rtrim($parentDir, DIRECTORY_SEPARATOR).'/'.$filename; |
|
} |
|
|
|
return $filename; |
|
} |
|
} |