diff --git a/README.md b/README.md index 564e464..e0463f3 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,5 @@ # HTTP Mock for PHP -[![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/InterNations/http-mock?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Build Status](https://travis-ci.org/InterNations/http-mock.svg)](https://travis-ci.org/InterNations/http-mock) [![Dependency Status](https://www.versioneye.com/user/projects/53479c42fe0d0720b500006a/badge.png)](https://www.versioneye.com/user/projects/53479c42fe0d0720b500006a) [![Average time to resolve an issue](http://isitmaintained.com/badge/resolution/InterNations/http-mock.svg)](http://isitmaintained.com/project/InterNations/http-mock "Average time to resolve an issue") [![Percentage of issues still open](http://isitmaintained.com/badge/open/InterNations/http-mock.svg)](http://isitmaintained.com/project/InterNations/http-mock "Percentage of issues still open") - Mock HTTP requests on the server side in your PHP unit tests. HTTP Mock for PHP mocks the server side of an HTTP request to allow integration testing with the HTTP side. @@ -9,7 +7,14 @@ It uses PHP’s builtin web server to start a second process that handles the mo registering request matcher and responses from the client side. *BIG FAT WARNING:* software like this is inherently insecure. Only use in trusted, controlled environments. +This is a fork of https://github.com/internations/http-mock + +Its been updated to use PSR/7 Http methods, and Slim on the server side. +The API has been kept the same where possible, but any direct use of Request or Response objects +will be different. ## Usage +`composer require --dev pagely/http-mock` + Read the [docs](doc/index.md) diff --git a/composer.json b/composer.json index fd71746..2fa4b4a 100644 --- a/composer.json +++ b/composer.json @@ -1,6 +1,6 @@ { - "name": "internations/http-mock", - "description": "Mock HTTP requests on the server side in your PHP unit tests", + "name": "pagely/http-mock", + "description": "Mock HTTP requests on the server side in your PHP unit tests, PSR/7 Fork of internations version", "license": "MIT", "authors": [ { @@ -10,15 +10,19 @@ { "name": "Max Beutel", "email": "max.beutel@internations.org" + }, + { + "name": "Joshua Eichorn", + "email": "joshua.eichorn@pagely.com" } ], "require": { - "php": "~7.1", - "silex/silex": "~2.0", - "guzzle/guzzle": ">=3.8", - "symfony/process": "~3|~4", + "php": "~7.1|~8", + "symfony/process": "~3|~4|~5", "jeremeamia/superclosure": "~2", - "lstrojny/hmmmath": ">=0.5.0" + "lstrojny/hmmmath": ">=0.5.0", + "guzzlehttp/guzzle": "^6.3", + "slim/slim": "^3.12" }, "require-dev": { "internations/kodierungsregelwerksammlung": "~0.23.0", @@ -26,9 +30,18 @@ "phpunit/phpunit": "^7" }, "autoload": { - "psr-4": {"InterNations\\Component\\HttpMock\\": "src/"} + "psr-4": {"Pagely\\Component\\HttpMock\\": "src/"} }, "autoload-dev": { - "psr-4": {"InterNations\\Component\\HttpMock\\Tests\\": "tests/"} - } + "psr-4": {"Pagely\\Component\\HttpMock\\Tests\\": "tests/"} + }, + "repositories": [ + { + "type": "composer", + "url": "https://gdartifactory1.jfrog.io/artifactory/api/composer/composer-virt/" + }, + { + "packagist.org": false + } + ] } diff --git a/doc/recording.md b/doc/recording.md index 892e045..10c03c4 100644 --- a/doc/recording.md +++ b/doc/recording.md @@ -2,7 +2,7 @@ Once a SUT (system under test) has fired HTTP requests, we often want to validate that our assumption about the nature of those requests are valid. For that purpose HTTP mock stores every request for later inspection. The recorded requests -are presented as an instance of `InterNations\Component\HttpMock\Request\UnifiedRequest`. +are presented as an instance of `Slim\Http\Response`. ```php $this->http->mock diff --git a/doc/server.md b/doc/server.md index a1059f4..c3dc689 100644 --- a/doc/server.md +++ b/doc/server.md @@ -6,7 +6,8 @@ Overview of the internal server functionality ``` POST /_expectation { - response (required): serialized Symfony response + response (required): stringified http respopnse + responseCallback (optional): serialized closure that is passed in the response, and can return a new Response matcher (optional): serialized list of closures limiter (optional): serialized closure that limits the validity of the expectation } diff --git a/doc/start.md b/doc/start.md index b972367..c8cd34c 100644 --- a/doc/start.md +++ b/doc/start.md @@ -1,13 +1,13 @@ # Getting started with HTTP mock HTTP mock comes out of the box with an integration with [PHPUnit](https://phpunit.de) in the shape of -`InterNations\Component\HttpMock\PHPUnit\HttpMockTrait`. In order to use it, we start and stop the background HTTP +`Pagely\Component\HttpMock\PHPUnit\HttpMockTrait`. In order to use it, we start and stop the background HTTP server in `setUpBeforeClass()` and `tearDownAfterClass()` respectively. ```php namespace Acme\Tests; -use InterNations\Component\HttpMock\PHPUnit\HttpMockTrait; +use Pagely\Component\HttpMock\PHPUnit\HttpMockTrait; class ExampleTest extends PHPUnit_Framework_TestCase { @@ -58,10 +58,10 @@ class ExampleTest extends PHPUnit_Framework_TestCase ->end(); $this->http->setUp(); - $this->assertSame('mocked body', $this->http->client->post('http://localhost:8082/foo')->send()->getBody(true)); + $this->assertSame('mocked body', (string)$this->http->client->post('http://localhost:8082/foo')->getBody()); $this->assertSame('POST', $this->http->requests->latest()->getMethod()); - $this->assertSame('/foo', $this->http->requests->latest()->getPath()); + $this->assertSame('/foo', $this->http->requests->latest()->getUri()->getPath()); } } ``` diff --git a/doc/stubbing.md b/doc/stubbing.md index c779181..8ef97e8 100644 --- a/doc/stubbing.md +++ b/doc/stubbing.md @@ -24,8 +24,8 @@ The example above say: when we see a `GET` request asking for `/resource` respon What we see here is internally syntactic sugar for the following, more verbose, example using plain callbacks. ```php -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\Response; +use Psr\Http\Message\RequestInterface as Request; +use Psr\Http\Message\ResponseInterface as Response; $this->http->mock ->when() @@ -43,21 +43,20 @@ $this->http->mock ->end(); ``` -What we can see above is that we use standard Symfony HTTP foundation `Request` and `Response` objects. If you want to -learn more about it, look at -[Symfony’s documentation](https://symfony.com/doc/current/components/http_foundation/introduction.html). +What we can see above is that we use standard PSR/7 Request Response, we use the Guzzle implementation on the Client and the Slim implementation on the server side, hurrah standards Let’s have a look what we can do with matching and response building shortcuts: ```php -use Symfony\Component\HttpFoundation\Response; +use Psr\Http\Message\ResponseInterface as Response; +use Slim\Http\StatusCode; $this->http->mock ->when() ->methodIs('GET') ->pathIs('/resource') ->then() - ->statusCode(Response::HTTP_NOT_FOUND) + ->statusCode(StatusCode::HTTP_NOT_FOUND) ->header('X-Custom-Header', 'Header Value') ->body('response') ->end();` diff --git a/public/index.php b/public/index.php index d9d901e..f10e911 100644 --- a/public/index.php +++ b/public/index.php @@ -1,4 +1,8 @@ responseBuilder->getResponse(); } + public function getResponseCallback() + { + return $this->responseBuilder->getResponseCallback(); + } + public function getLimiter() { return new SerializableClosure($this->limiter); diff --git a/src/Matcher/AbstractMatcher.php b/src/Matcher/AbstractMatcher.php index 429d60b..397c863 100644 --- a/src/Matcher/AbstractMatcher.php +++ b/src/Matcher/AbstractMatcher.php @@ -1,9 +1,9 @@ basePath; return static function (Request $request) use ($basePath) { - return substr_replace($request->getPathInfo(), '', 0, strlen($basePath)); + return substr_replace($request->getUri()->getPath(), '', 0, strlen($basePath)); }; } @@ -31,28 +31,32 @@ public function createMethodExtractor() public function createParamExtractor($param) { return static function (Request $request) use ($param) { - return $request->query->get($param); + return $request->getParam($param); }; } public function createParamExistsExtractor($param) { return static function (Request $request) use ($param) { - return $request->query->has($param); + return $request->getParam($param, false) !== false; }; } public function createHeaderExtractor($header) { return static function (Request $request) use ($header) { - return $request->headers->get($header); + $r = $request->getHeaderLine($header); + if (empty($r)) { + return null; + } + return $r; }; } public function createHeaderExistsExtractor($header) { return static function (Request $request) use ($header) { - return $request->headers->has($header); + return $request->hasHeader($header); }; } } diff --git a/src/Matcher/MatcherFactory.php b/src/Matcher/MatcherFactory.php index 34d5461..9971b1d 100644 --- a/src/Matcher/MatcherFactory.php +++ b/src/Matcher/MatcherFactory.php @@ -1,5 +1,5 @@ wrapped = $wrapped; - $this->init($params); - } - - /** - * Get the user agent of the request - * - * @return string - */ - public function getUserAgent() - { - return $this->userAgent; - } - - /** - * Get the body of the request if set - * - * @return EntityBodyInterface|null - */ - public function getBody() - { - return $this->invokeWrappedIfEntityEnclosed(__FUNCTION__, func_get_args()); - } - - /** - * Get a POST field from the request - * - * @param string $field Field to retrieve - * - * @return mixed|null - */ - public function getPostField($field) - { - return $this->invokeWrappedIfEntityEnclosed(__FUNCTION__, func_get_args()); - } - - /** - * Get the post fields that will be used in the request - * - * @return QueryString - */ - public function getPostFields() - { - return $this->invokeWrappedIfEntityEnclosed(__FUNCTION__, func_get_args()); - } - - /** - * Returns an associative array of POST field names to PostFileInterface objects - * - * @return array - */ - public function getPostFiles() - { - return $this->invokeWrappedIfEntityEnclosed(__FUNCTION__, func_get_args()); - } - - /** - * Get a POST file from the request - * - * @param string $fieldName POST fields to retrieve - * - * @return array|null Returns an array wrapping an array of PostFileInterface objects - */ - public function getPostFile($fieldName) - { - return $this->invokeWrappedIfEntityEnclosed(__FUNCTION__, func_get_args()); - } - - /** - * Get application and plugin specific parameters set on the message. - * - * @return Collection - */ - public function getParams() - { - return $this->wrapped->getParams(); - } - - /** - * Retrieve an HTTP header by name. Performs a case-insensitive search of all headers. - * - * @param string $header Header to retrieve. - * - * @return Header|null Returns NULL if no matching header is found. - * Returns a Header object if found. - */ - public function getHeader($header) - { - return $this->wrapped->getHeader($header); - } - - /** - * Get all headers as a collection - * - * @return HeaderCollection - */ - public function getHeaders() - { - return $this->wrapped->getHeaders(); - } - - /** - * Get an array of message header lines - * - * @return array - */ - public function getHeaderLines() - { - return $this->wrapped->getHeaderLines(); - } - - /** - * Check if the specified header is present. - * - * @param string $header The header to check. - * - * @return boolean Returns TRUE or FALSE if the header is present - */ - public function hasHeader($header) - { - return $this->wrapped->hasHeader($header); - } - - /** - * Get the raw message headers as a string - * - * @return string - */ - public function getRawHeaders() - { - return $this->wrapped->getRawHeaders(); - } - - /** - * Get the collection of key value pairs that will be used as the query - * string in the request - * - * @return QueryString - */ - public function getQuery() - { - return $this->wrapped->getQuery(); - } - - /** - * Get the HTTP method of the request - * - * @return string - */ - public function getMethod() - { - return $this->wrapped->getMethod(); - } - - /** - * Get the URI scheme of the request (http, https, ftp, etc) - * - * @return string - */ - public function getScheme() - { - return $this->wrapped->getScheme(); - } - - /** - * Get the host of the request - * - * @return string - */ - public function getHost() - { - return $this->wrapped->getHost(); - } - - /** - * Get the HTTP protocol version of the request - * - * @return string - */ - public function getProtocolVersion() - { - return $this->wrapped->getProtocolVersion(); - } - - /** - * Get the path of the request (e.g. '/', '/index.html') - * - * @return string - */ - public function getPath() - { - return $this->wrapped->getPath(); - } - - /** - * Get the port that the request will be sent on if it has been set - * - * @return integer|null - */ - public function getPort() - { - return $this->wrapped->getPort(); - } - - /** - * Get the username to pass in the URL if set - * - * @return string|null - */ - public function getUsername() - { - return $this->wrapped->getUsername(); - } - - /** - * Get the password to pass in the URL if set - * - * @return string|null - */ - public function getPassword() - { - return $this->wrapped->getPassword(); - } - - /** - * Get the full URL of the request (e.g. 'http://www.guzzle-project.com/') - * scheme://username:password@domain:port/path?query_string#fragment - * - * @param boolean $asObject Set to TRUE to retrieve the URL as a clone of the URL object owned by the request. - * - * @return string|Url - */ - public function getUrl($asObject = false) - { - return $this->wrapped->getUrl($asObject); - } - - /** - * Get an array of Cookies - * - * @return array - */ - public function getCookies() - { - return $this->wrapped->getCookies(); - } - - /** - * Get a cookie value by name - * - * @param string $name Cookie to retrieve - * - * @return null|string - */ - public function getCookie($name) - { - return $this->wrapped->getCookie($name); - } - - protected function invokeWrappedIfEntityEnclosed($method, array $params = []) - { - if (!$this->wrapped instanceof EntityEnclosingRequestInterface) { - throw new BadMethodCallException( - sprintf( - 'Cannot call method "%s" on a request that does not enclose an entity.' - . ' Did you expect a POST/PUT request instead of %s %s?', - $method, - $this->wrapped->getMethod(), - $this->wrapped->getPath() - ) - ); - } - - return call_user_func_array([$this->wrapped, $method], $params); - } - - private function init(array $params) - { - foreach ($params as $property => $value) { - if (property_exists($this, $property)) { - $this->{$property} = $value; - } - } - } -} diff --git a/src/RequestCollectionFacade.php b/src/RequestCollectionFacade.php index e185902..2e2e287 100644 --- a/src/RequestCollectionFacade.php +++ b/src/RequestCollectionFacade.php @@ -1,20 +1,17 @@ client = $client; } @@ -71,72 +68,39 @@ public function shift() public function count() { $response = $this->client - ->get('/_request/count') - ->send(); + ->get('/_request/count'); - return (int) $response->getBody(true); + return (int) $response->getBody()->getContents(); } /** * @param Response $response * @param string $path * @throws UnexpectedValueException - * @return UnifiedRequest + * @return RequestInterface */ - private function parseRequestFromResponse(Response $response, $path) + private function parseRequestFromResponse(ResponseInterface $response, $path) { try { - $requestInfo = Util::deserialize($response->getBody()); + $contents = $response->getBody()->getContents(); + $requestInfo = Util::deserialize($contents); } catch (UnexpectedValueException $e) { throw new UnexpectedValueException( - sprintf('Cannot deserialize response from "%s": "%s"', $path, $response->getBody()), + sprintf('Cannot deserialize response from "%s": "%s"', $path, $contents), null, $e ); } - $request = RequestFactory::getInstance()->fromMessage($requestInfo['request']); - $params = $this->configureRequest( - $request, - $requestInfo['server'], - isset($requestInfo['enclosure']) ? $requestInfo['enclosure'] : [] - ); - - return new UnifiedRequest($request, $params); - } - - private function configureRequest(RequestInterface $request, array $server, array $enclosure) - { - if (isset($server['HTTP_HOST'])) { - $request->setHost($server['HTTP_HOST']); - } - - if (isset($server['HTTP_PORT'])) { - $request->setPort($server['HTTP_PORT']); - } - - if (isset($server['PHP_AUTH_USER'])) { - $request->setAuth($server['PHP_AUTH_USER'], isset($server['PHP_AUTH_PW']) ? $server['PHP_AUTH_PW'] : null); - } - - $params = []; - - if (isset($server['HTTP_USER_AGENT'])) { - $params['userAgent'] = $server['HTTP_USER_AGENT']; - } - - if ($request instanceof EntityEnclosingRequestInterface) { - $request->addPostFields($enclosure); - } + $request = \GuzzleHttp\Psr7\parse_request($requestInfo['request']); - return $params; + return $request; } private function getRecordedRequest($path) { $response = $this->client - ->get($path) - ->send(); + ->get($path); return $this->parseResponse($response, $path); } @@ -144,13 +108,12 @@ private function getRecordedRequest($path) private function deleteRecordedRequest($path) { $response = $this->client - ->delete($path) - ->send(); + ->delete($path); return $this->parseResponse($response, $path); } - private function parseResponse(Response $response, $path) + private function parseResponse(ResponseInterface $response, $path) { $statusCode = $response->getStatusCode(); @@ -161,7 +124,7 @@ private function parseResponse(Response $response, $path) } $contentType = $response->hasHeader('content-type') - ? $response->getContentType() + ? $response->getHeaderLine('content-type') : ''; if (substr($contentType, 0, 10) !== 'text/plain') { diff --git a/src/RequestStorage.php b/src/RequestStorage.php index f2838f8..7ff8fd4 100644 --- a/src/RequestStorage.php +++ b/src/RequestStorage.php @@ -1,7 +1,7 @@ directory . $this->pid . '-' . $name . '-' . $request->server->get('SERVER_PORT'); + return $this->directory . $this->pid . '-' . $name . '-' . $request->getUri()->getPort(); } public function clear(Request $request, $name) diff --git a/src/Response/CallbackResponse.php b/src/Response/CallbackResponse.php deleted file mode 100644 index 025979c..0000000 --- a/src/Response/CallbackResponse.php +++ /dev/null @@ -1,28 +0,0 @@ -callback = $callback; - } - - public function sendCallback() - { - if ($this->callback) { - $callback = $this->callback; - $callback($this); - } - } - - public function send() - { - $this->sendCallback(); - parent::send(); - } -} diff --git a/src/ResponseBuilder.php b/src/ResponseBuilder.php index 62890ba..3aa789f 100644 --- a/src/ResponseBuilder.php +++ b/src/ResponseBuilder.php @@ -1,7 +1,7 @@ mockBuilder = $mockBuilder; - $this->response = new CallbackResponse(); + $this->response = new Response(); } public function statusCode($statusCode) { - $this->response->setStatusCode($statusCode); + $this->response = $this->response->withStatus($statusCode); return $this; } public function body($body) { - $this->response->setContent($body); + $this->response = $this->response->withBody(\GuzzleHttp\Psr7\stream_for($body)); return $this; } public function callback(Closure $callback) { - $this->response->setCallback(new SerializableClosure($callback)); + $this->responseCallback = new SerializableClosure($callback); return $this; } public function header($header, $value) { - $this->response->headers->set($header, $value); + $this->response = $this->response->withHeader($header, $value); return $this; } @@ -56,4 +58,10 @@ public function getResponse() { return $this->response; } + + + public function getResponseCallback() + { + return $this->responseCallback; + } } diff --git a/src/Server.php b/src/Server.php index d362a68..c718769 100644 --- a/src/Server.php +++ b/src/Server.php @@ -1,12 +1,12 @@ getBaseUrl()); - $client->getEventDispatcher()->addListener( - 'request.error', - static function (Event $event) { - $event->stopPropagation(); - } - ); + $client = new Client(['base_uri' => $this->getBaseUrl(), 'http_errors' => false]); return $client; } @@ -84,16 +78,16 @@ public function setUp(array $expectations) foreach ($expectations as $expectation) { $response = $this->getClient()->post( '/_expectation', - null, - [ + ['json' => [ 'matcher' => serialize($expectation->getMatcherClosures()), 'limiter' => serialize($expectation->getLimiter()), - 'response' => serialize($expectation->getResponse()), - ] - )->send(); + 'response' => Util::serializePsrMessage($expectation->getResponse()), + 'responseCallback' => serialize($expectation->getResponseCallback()), + ]] + ); if ($response->getStatusCode() !== 201) { - throw new RuntimeException('Could not set up expectations'); + throw new RuntimeException('Could not set up expectations: '.$response->getBody()->getContents()); } } } @@ -104,20 +98,29 @@ public function clean() $this->start(); } - $this->getClient()->delete('/_all')->send(); + $this->getClient()->delete('/_all'); } private function pollWait() { - foreach (FibonacciFactory::sequence(50000, 10000) as $sleepTime) { + $success = false; + foreach (FibonacciFactory::sequence(50000, 10000, 8) as $sleepTime) { try { usleep($sleepTime); - $this->getClient()->head('/_me')->send(); + $r = $this->getClient()->head('/_me'); + if ($r->getStatusCode() !== 418) { + continue; + } + $success = true; break; - } catch (CurlException $e) { + } catch (ServerException $e) { continue; } } + + if (!$success) { + throw $e; + } } public function getIncrementalErrorOutput() diff --git a/src/Util.php b/src/Util.php index 6437a41..ffe0628 100644 --- a/src/Util.php +++ b/src/Util.php @@ -1,5 +1,5 @@ getHeaders(); + foreach($headers as $key => $list) { + foreach($list as $value) { + if (substr($key, 0, 5) === 'HTTP_') { + $newKey = substr($key, 5); + $newKey = str_replace(' ', '-', ucwords(strtolower(str_replace('_', ' ', $newKey)))); + $message = $message->withoutHeader($key)->withHeader($newKey, $value); + } + else + { + $newKey = str_replace(' ', '-', ucwords(strtolower(str_replace('_', ' ', $key)))); + $message = $message->withoutHeader($key)->withHeader($newKey, $value); + } + } + } + return \GuzzleHttp\Psr7\str($message); + } } diff --git a/src/app.php b/src/app.php index 4df7419..2ddc0c6 100644 --- a/src/app.php +++ b/src/app.php @@ -1,13 +1,16 @@ [ + 'displayErrorDetails' => true, + ] +]); +$container['storage'] = new RequestStorage(getmypid(), __DIR__ . '/../state/'); +$app = new App($container); $app->delete( '/_expectation', - static function (Request $request) use ($app) { - $app['storage']->clear($request, 'expectations'); + function (Request $request, Response $response) use ($container) { + $container['storage']->clear($request, 'expectations'); - return new Response('', Response::HTTP_OK); + return $response->withStatus(StatusCode::HTTP_OK); } ); $app->post( '/_expectation', - static function (Request $request) use ($app) { + function (Request $request, Response $response) use ($container) { + $data = json_decode($request->getBody()->getContents(), true); $matcher = []; - if ($request->request->has('matcher')) { - $matcher = Util::silentDeserialize($request->request->get('matcher')); - $validator = static function ($closure) { + if (!empty($data['matcher'])) { + $matcher = Util::silentDeserialize($data['matcher']); + $validator = function ($closure) { return is_callable($closure); }; if (!is_array($matcher) || count(array_filter($matcher, $validator)) !== count($matcher)) { - return new Response( - 'POST data key "matcher" must be a serialized list of closures', - Response::HTTP_EXPECTATION_FAILED + return $response->withStatus(StatusCode::HTTP_EXPECTATION_FAILED)->write( + 'POST data key "matcher" must be a serialized list of closures' ); } } - if (!$request->request->has('response')) { - return new Response('POST data key "response" not found in POST data', Response::HTTP_EXPECTATION_FAILED); + if (empty($data['response'])) { + return $response->withStatus(StatusCode::HTTP_EXPECTATION_FAILED)->write( + 'POST data key "response" not found in POST data' + ); } - $response = Util::silentDeserialize($request->request->get('response')); - - if (!$response instanceof Response) { - return new Response( - 'POST data key "response" must be a serialized Symfony response', - Response::HTTP_EXPECTATION_FAILED + try + { + $responseToSave = Util::responseDeserialize($data['response']); + } + catch(Exception $e) + { + return $response->withStatus(StatusCode::HTTP_EXPECTATION_FAILED)->write( + 'POST data key "response" must be an http response message in text form' ); } $limiter = null; - if ($request->request->has('limiter')) { - $limiter = Util::silentDeserialize($request->request->get('limiter')); + if (!empty($data['limiter'])) { + $limiter = Util::silentDeserialize($data['limiter']); if (!is_callable($limiter)) { - return new Response( - 'POST data key "limiter" must be a serialized closure', - Response::HTTP_EXPECTATION_FAILED + return $response->withStatus(StatusCode::HTTP_EXPECTATION_FAILED)->write( + 'POST data key "limiter" must be a serialized closure' ); } } // Fix issue with silex default error handling - $response->headers->set('X-Status-Code', $response->getStatusCode()); + // not sure if this is need anymore + $response = $response->withHeader('X-Status-Code', $response->getStatusCode()); + + $responseCallback = null; + if (!empty($data['responseCallback'])) { + $responseCallback = Util::silentDeserialize($data['responseCallback']); + + if ($responseCallback !== null && !is_callable($responseCallback)) { + return $response->withStatus(StatusCode::HTTP_EXPECTATION_FAILED)->write( + 'POST data key "responseCallback" must be a serialized closure: ' + .print_r($data['responseCallback'], true) + ); + } + } - $app['storage']->prepend( + $container['storage']->prepend( $request, 'expectations', - ['matcher' => $matcher, 'response' => $response, 'limiter' => $limiter, 'runs' => 0] + [ + 'matcher' => $matcher, + 'response' => $data['response'], + 'limiter' => $limiter, + 'responseCallback' => $responseCallback, + 'runs' => 0 + ] ); - return new Response('', Response::HTTP_CREATED); + return $response->withStatus(StatusCode::HTTP_CREATED); } ); -$app->error( - static function (Exception $e, Request $request, $code, GetResponseForExceptionEvent $event = null) use ($app) { - if ($e instanceof NotFoundHttpException) { - $app['storage']->append( - $request, - 'requests', - serialize( - [ - 'server' => $request->server->all(), - 'request' => (string) $request, - 'enclosure' => $request->request->all(), - ] - ) - ); +$container['phpErrorHandler'] = function($container) { + return function (Request $request, Response $response, Error $e) use ($container) { + return $response->withStatus(500) + ->withHeader('Content-Type', 'text/plain') + ->write($e->getMessage()."\n".$e->getTraceAsString()."\n"); + }; +}; + +$container['notFoundHandler'] = function($container) { + return function (Request $request, Response $response) use ($container) { + $container['storage']->append( + $request, + 'requests', + serialize( + [ + 'request' => Util::serializePsrMessage($request), + 'server' => $request->getServerParams(), + ] + ) + ); - $notFoundResponse = new Response('No matching expectation found', Response::HTTP_NOT_FOUND); + $notFoundResponse = $response->withStatus(StatusCode::HTTP_NOT_FOUND); - $expectations = $app['storage']->read($request, 'expectations'); + $expectations = $container['storage']->read($request, 'expectations'); - foreach ($expectations as $pos => $expectation) { - foreach ($expectation['matcher'] as $matcher) { - if (!$matcher($request)) { - continue 2; - } + foreach ($expectations as $pos => $expectation) { + foreach ($expectation['matcher'] as $matcher) { + if (!$matcher($request)) { + continue 2; } + } - if (isset($expectation['limiter']) && !$expectation['limiter']($expectation['runs'])) { - $notFoundResponse = new Response('Expectation no longer applicable', Response::HTTP_GONE); - continue; + if (isset($expectation['limiter']) && !$expectation['limiter']($expectation['runs'])) { + if ($notFoundResponse->getStatusCode() != StatusCode::HTTP_GONE) { + $notFoundResponse = $response->withStatus(StatusCode::HTTP_GONE) + ->write('Expectation no longer applicable'); } + continue; + } - ++$expectations[$pos]['runs']; - $app['storage']->store($request, 'expectations', $expectations); - - if (method_exists($event, 'allowCustomResponseCode')) { - $event->allowCustomResponseCode(); - } + ++$expectations[$pos]['runs']; + $container['storage']->store($request, 'expectations', $expectations); - return $expectation['response']; + $r = Util::responseDeserialize($expectation['response']); + if (!empty($expectation['responseCallback'])) { + $callback = $expectation['responseCallback']; + return $callback($r); } + return $r; + } - return $notFoundResponse; + if ($notFoundResponse->getStatusCode() == StatusCode::HTTP_NOT_FOUND) { + $notFoundResponse = $notFoundResponse->write('No matching expectation found'); } - return new Response('Server error: ' . $e->getMessage(), $code); - } -); + return $notFoundResponse; + }; +}; + +$container['errorHandler'] = function($container) { + return function (Request $request, Response $response, Exception $e) use ($container) { + return $response->withStatus(StatusCode::HTTP_INTERNAL_SERVER_ERROR)->write( + 'Server error: ' . $e->getMessage()); + }; +}; $app->get( '/_request/count', - static function (Request $request) use ($app) { - return count($app['storage']->read($request, 'requests')); + function (Request $request, Response $response) use ($container) { + $count = count($container['storage']->read($request, 'requests')); + return $response->withStatus(StatusCode::HTTP_OK) + ->write($count) + ->withHeader('Content-Type', 'text/plain'); } ); $app->get( - '/_request/{index}', - static function (Request $request, $index) use ($app) { - $requestData = $app['storage']->read($request, 'requests'); + '/_request/{index:[0-9]+}', + function (Request $request, Response $response, $args) use ($container) { + $index = (int)$args['index']; + $requestData = $container['storage']->read($request, 'requests'); if (!isset($requestData[$index])) { - return new Response('Index ' . $index . ' not found', Response::HTTP_NOT_FOUND); + return $response->withStatus(StatusCode::HTTP_NOT_FOUND)->write( + 'Index ' . $index . ' not found'); } - return new Response($requestData[$index], Response::HTTP_OK, ['Content-Type' => 'text/plain']); + return $response->withStatus(StatusCode::HTTP_OK) + ->write($requestData[$index]) + ->withHeader('Content-Type', 'text/plain'); } -)->assert('index', '\d+'); +); $app->delete( - '/_request/{action}', - static function (Request $request, $action) use ($app) { - $requestData = $app['storage']->read($request, 'requests'); - $fn = 'array_' . ($action === 'last' ? 'pop' : 'shift'); + '/_request/{action:last|latest|first}', + function (Request $request, Response $response, $args) use ($container) { + $action = $args['action']; + + $requestData = $container['storage']->read($request, 'requests'); + $fn = 'array_' . ($action === 'last' || $action === 'latest' ? 'pop' : 'shift'); $requestString = $fn($requestData); - $app['storage']->store($request, 'requests', $requestData); + $container['storage']->store($request, 'requests', $requestData); if (!$requestString) { - return new Response($action . ' not possible', Response::HTTP_NOT_FOUND); + return $response->withStatus(StatusCode::HTTP_NOT_FOUND)->write( + $action . ' not possible' + ); } - return new Response($requestString, Response::HTTP_OK, ['Content-Type' => 'text/plain']); + return $response->withStatus(StatusCode::HTTP_OK) + ->write($requestString) + ->withHeader('Content-Type', 'text/plain'); } -)->assert('index', '(last|first)'); +); $app->get( - '/_request/{action}', - static function (Request $request, $action) use ($app) { - $requestData = $app['storage']->read($request, 'requests'); - $fn = 'array_' . ($action === 'last' ? 'pop' : 'shift'); + '/_request/{action:last|latest|first}', + function (Request $request, Response $response, $args) use ($container) { + $action = $args['action']; + $requestData = $container['storage']->read($request, 'requests'); + $fn = 'array_' . ($action === 'last' || $action === 'latest' ? 'pop' : 'shift'); $requestString = $fn($requestData); if (!$requestString) { - return new Response($action . ' not available', Response::HTTP_NOT_FOUND); + return $response->withStatus(StatusCode::HTTP_NOT_FOUND)->write( + $action . ' not available' + ); } - return new Response($requestString, Response::HTTP_OK, ['Content-Type' => 'text/plain']); + return $response->withStatus(StatusCode::HTTP_OK) + ->withHeader('Content-Type', 'text/plain') + ->write($requestString); } -)->assert('index', '(last|first)'); +); $app->delete( '/_request', - static function (Request $request) use ($app) { - $app['storage']->store($request, 'requests', []); + function (Request $request, Response $response) use ($container) { + $container['storage']->store($request, 'requests', []); - return new Response('', Response::HTTP_OK); + return $response->withStatus(StatusCode::HTTP_OK); } ); $app->delete( '/_all', - static function (Request $request) use ($app) { - $app['storage']->store($request, 'requests', []); - $app['storage']->store($request, 'expectations', []); + function (Request $request, Response $response) use ($container) { + $container['storage']->store($request, 'requests', []); + $container['storage']->store($request, 'expectations', []); - return new Response('', Response::HTTP_OK); + return $response->withStatus(StatusCode::HTTP_OK); } ); $app->get( '/_me', - static function () { - return new Response('O RLY?', Response::HTTP_I_AM_A_TEAPOT, ['Content-Type' => 'text/plain']); + function (Request $request, Response $response) { + return $response->withStatus(StatusCode::HTTP_IM_A_TEAPOT) + ->write('O RLY?') + ->withHeader('Content-Type', 'text/plain'); } ); diff --git a/tests/AppIntegrationTest.php b/tests/AppIntegrationTest.php index c8d8ebc..9556826 100644 --- a/tests/AppIntegrationTest.php +++ b/tests/AppIntegrationTest.php @@ -1,15 +1,14 @@ getOutput(), (string) static::$server1->getOutput()); - static::assertSame('', (string) static::$server1->getErrorOutput(), (string) static::$server1->getErrorOutput()); + $out = (string) static::$server1->getOutput(); + static::assertSame('', $out, $out); + + $out = (string) static::$server1->getErrorOutput(); + //static::assertSame('', $out, $out); + echo $out."\n"; + static::$server1->stop(); } @@ -49,110 +53,135 @@ public function setUp() public function testSimpleUseCase() { - $response = $this->client->post( - '/_expectation', - null, - $this->createExpectationParams( - [ - static function ($request) { - return $request instanceof Request; - } - ], - new Response('fake body', 200) - ) - )->send(); + $params = $this->createExpectationParams( + [ + static function ($request) { + return $request instanceof RequestInterface; + } + ], + new Response(200, ['Host' => 'localhost'], 'fake body') + ); + + $response = $this->client->post( '/_expectation', ['json' => $params]); $this->assertSame('', (string) $response->getBody()); $this->assertSame(201, $response->getStatusCode()); - $response = $this->client->post('/foobar', ['X-Special' => 1], ['post' => 'data'])->send(); + $response = $this->client->post('/foobar', [ + 'headers' => ['X-Special' => 1], + 'form_params' => ['post' => 'data'], + ]); $this->assertSame(200, $response->getStatusCode()); $this->assertSame('fake body', (string) $response->getBody()); - $response = $this->client->get('/_request/latest')->send(); + $response = $this->client->get('/_request/latest'); /** @var EntityEnclosingRequest $request */ $request = $this->parseRequestFromResponse($response); - $this->assertSame('1', (string) $request->getHeader('X-Special')); + $this->assertSame('1', (string) $request->getHeaderLine('X-Special')); $this->assertSame('post=data', (string) $request->getBody()); + + // should be the same as latest + $response = $this->client->get('/_request/last'); + $request = $this->parseRequestFromResponse($response); + $this->assertSame('1', (string) $request->getHeaderLine('X-Special')); } public function testRecording() { - $this->client->delete('/_all')->send(); + $this->client->delete('/_all'); - $this->assertSame(404, $this->client->get('/_request/latest')->send()->getStatusCode()); - $this->assertSame(404, $this->client->get('/_request/0')->send()->getStatusCode()); - $this->assertSame(404, $this->client->get('/_request/first')->send()->getStatusCode()); - $this->assertSame(404, $this->client->get('/_request/last')->send()->getStatusCode()); + $this->assertSame(404, $this->client->get('/_request/latest')->getStatusCode()); + $this->assertSame(404, $this->client->get('/_request/0')->getStatusCode()); + $this->assertSame(404, $this->client->get('/_request/first')->getStatusCode()); + $this->assertSame(404, $this->client->get('/_request/last')->getStatusCode()); - $this->client->get('/req/0')->send(); - $this->client->get('/req/1')->send(); - $this->client->get('/req/2')->send(); - $this->client->get('/req/3')->send(); + $this->client->get('/req/0'); + $this->client->get('/req/1'); + $this->client->get('/req/2'); + $this->client->get('/req/3'); $this->assertSame( '/req/3', - $this->parseRequestFromResponse($this->client->get('/_request/last')->send())->getPath() + $this->parseRequestFromResponse($this->client->get('/_request/last'))->getUri()->getPath() ); $this->assertSame( '/req/0', - $this->parseRequestFromResponse($this->client->get('/_request/0')->send())->getPath() + $this->parseRequestFromResponse($this->client->get('/_request/0'))->getUri()->getPath() ); $this->assertSame( '/req/1', - $this->parseRequestFromResponse($this->client->get('/_request/1')->send())->getPath() + $this->parseRequestFromResponse($this->client->get('/_request/1'))->getUri()->getPath() ); $this->assertSame( '/req/2', - $this->parseRequestFromResponse($this->client->get('/_request/2')->send())->getPath() + $this->parseRequestFromResponse($this->client->get('/_request/2'))->getUri()->getPath() ); $this->assertSame( '/req/3', - $this->parseRequestFromResponse($this->client->get('/_request/3')->send())->getPath() + $this->parseRequestFromResponse($this->client->get('/_request/3'))->getUri()->getPath() ); - $this->assertSame(404, $this->client->get('/_request/4')->send()->getStatusCode()); + $this->assertSame(404, $this->client->get('/_request/4')->getStatusCode()); $this->assertSame( '/req/3', - $this->parseRequestFromResponse($this->client->delete('/_request/last')->send())->getPath() + $this->parseRequestFromResponse($this->client->delete('/_request/last'))->getUri()->getPath() ); $this->assertSame( '/req/0', - $this->parseRequestFromResponse($this->client->delete('/_request/first')->send())->getPath() + $this->parseRequestFromResponse($this->client->delete('/_request/first'))->getUri()->getPath() ); $this->assertSame( '/req/1', - $this->parseRequestFromResponse($this->client->get('/_request/0')->send())->getPath() + $this->parseRequestFromResponse($this->client->get('/_request/0'))->getUri()->getPath() ); $this->assertSame( '/req/2', - $this->parseRequestFromResponse($this->client->get('/_request/1')->send())->getPath() + $this->parseRequestFromResponse($this->client->get('/_request/1'))->getUri()->getPath() ); - $this->assertSame(404, $this->client->get('/_request/2')->send()->getStatusCode()); + $this->assertSame(404, $this->client->get('/_request/2')->getStatusCode()); } public function testErrorHandling() { - $this->client->delete('/_all')->send(); + $this->client->delete('/_all'); - $response = $this->client->post('/_expectation', null, ['matcher' => ''])->send(); + $tester = function($matcher, $response = null, $limiter = null) { + $payload = []; + if ($response === null) { + $payload['response'] = \GuzzleHttp\Psr7\str(new Response(200, [], 'foo')); + } elseif ($response !== false) { + $payload['response'] = $response; + } + if ($matcher === null) { + $matcher['matcher'] = serialize([new SerializableClosure(function() { return true; })]); + } elseif ($matcher !== false) { + $payload['matcher'] = $matcher; + } + + if ($limiter !== false && $limiter !== null) { + $payload['limiter'] = $limiter; + } + return $this->client->post('/_expectation', ['json' => $payload]); + }; + + $response = $tester('hi'); $this->assertSame(417, $response->getStatusCode()); $this->assertSame('POST data key "matcher" must be a serialized list of closures', (string) $response->getBody()); - $response = $this->client->post('/_expectation', null, ['matcher' => ['foo']])->send(); + $response = $tester(['foo']); $this->assertSame(417, $response->getStatusCode()); $this->assertSame('POST data key "matcher" must be a serialized list of closures', (string) $response->getBody()); - $response = $this->client->post('/_expectation', null, [])->send(); + $response = $tester(null, false); $this->assertSame(417, $response->getStatusCode()); $this->assertSame('POST data key "response" not found in POST data', (string) $response->getBody()); - $response = $this->client->post('/_expectation', null, ['response' => ''])->send(); + $response = $tester(null, 'foo'); $this->assertSame(417, $response->getStatusCode()); - $this->assertSame('POST data key "response" must be a serialized Symfony response', (string) $response->getBody()); + $this->assertSame('POST data key "response" must be an http response message in text form', (string) $response->getBody()); - $response = $this->client->post('/_expectation', null, ['response' => serialize(new Response()), 'limiter' => 'foo'])->send(); + $response = $tester(null, null, 'foo'); $this->assertSame(417, $response->getStatusCode()); $this->assertSame('POST data key "limiter" must be a serialized closure', (string) $response->getBody()); } @@ -160,13 +189,15 @@ public function testErrorHandling() public function testServerParamsAreRecorded() { $this->client - ->setUserAgent('CUSTOM UA') - ->get('/foo') - ->setAuth('username', 'password') - ->setProtocolVersion('1.0') - ->send(); + ->get('/foo', [ + 'headers' => [ + 'User-Agent' => 'CUSTOM UA' + ], + 'auth' => ['username', 'password'], + 'version' => '1.0' + ]); - $latestRequest = unserialize($this->client->get('/_request/latest')->send()->getBody()); + $latestRequest = unserialize($this->client->get('/_request/latest')->getBody()); $this->assertSame(HTTP_MOCK_HOST, $latestRequest['server']['SERVER_NAME']); $this->assertSame(HTTP_MOCK_PORT, $latestRequest['server']['SERVER_PORT']); @@ -180,31 +211,30 @@ public function testNewestExpectationsAreFirstEvaluated() { $this->client->post( '/_expectation', - null, - $this->createExpectationParams( + ['json' => $this->createExpectationParams( [ static function ($request) { - return $request instanceof Request; + return $request instanceof RequestInterface; } ], - new Response('first', 200) - ) - )->send(); - $this->assertSame('first', $this->client->get('/')->send()->getBody(true)); + new Response(200, [], 'first') + )] + ); + $this->assertSame('first', $this->client->get('/')->getBody()->getContents()); $this->client->post( '/_expectation', - null, + ['json' => $this->createExpectationParams( [ static function ($request) { - return $request instanceof Request; + return $request instanceof RequestInterface; } ], - new Response('second', 200) - ) - )->send(); - $this->assertSame('second', $this->client->get('/')->send()->getBody(true)); + new Response(200, [], 'second') + )] + ); + $this->assertSame('second', $this->client->get('/')->getBody()->getContents()); } public function testServerLogsAreNotInErrorOutput() @@ -225,11 +255,11 @@ public function testServerLogsAreNotInErrorOutput() self::$server1->clearErrorOutput(); } - private function parseRequestFromResponse(GuzzleResponse $response) + private function parseRequestFromResponse(Response $response) { $body = unserialize($response->getBody()); - return RequestFactory::getInstance()->fromMessage($body['request']); + return \GuzzleHttp\Psr7\parse_request($body['request']); } private function createExpectationParams(array $closures, Response $response) @@ -240,7 +270,7 @@ private function createExpectationParams(array $closures, Response $response) return [ 'matcher' => serialize($closures), - 'response' => serialize($response), + 'response' => \GuzzleHttp\Psr7\str($response) ]; } } diff --git a/tests/Fixtures/Request.php b/tests/Fixtures/Request.php index b6d746e..f38af08 100644 --- a/tests/Fixtures/Request.php +++ b/tests/Fixtures/Request.php @@ -1,10 +1,21 @@ requestUri = $requestUri; diff --git a/tests/Matcher/ExtractorFactoryTest.php b/tests/Matcher/ExtractorFactoryTest.php index c71dd42..098fc50 100644 --- a/tests/Matcher/ExtractorFactoryTest.php +++ b/tests/Matcher/ExtractorFactoryTest.php @@ -1,9 +1,9 @@ extractorFactory = new ExtractorFactory(); - $this->request = $this->createMock('Symfony\Component\HttpFoundation\Request'); } public function testGetMethod() { - $this->request - ->expects($this->once()) - ->method('getMethod') - ->will($this->returnValue('POST')); + $request = new Request( + 'POST', + '/' + ); $extractor = $this->extractorFactory->createMethodExtractor(); - $this->assertSame('POST', $extractor($this->request)); + $this->assertSame('POST', $extractor($request)); } public function testGetPath() { - $this->request - ->expects($this->once()) - ->method('getPathInfo') - ->will($this->returnValue('/foo/bar')); + $request = new Request( + 'GET', + '/foo/bar' + ); $extractor = $this->extractorFactory->createPathExtractor(); - $this->assertSame('/foo/bar', $extractor($this->request)); + $this->assertSame('/foo/bar', $extractor($request)); } public function testGetPathWithBasePath() { - $this->request - ->expects($this->once()) - ->method('getPathInfo') - ->will($this->returnValue('/foo/bar')); + $request = new Request( + 'GET', + '/foo/bar' + ); $extractorFactory = new ExtractorFactory('/foo'); $extractor = $extractorFactory->createPathExtractor(); - $this->assertSame('/bar', $extractor($this->request)); + $this->assertSame('/bar', $extractor($request)); } public function testGetPathWithBasePathTrailingSlash() { - $this->request - ->expects($this->once()) - ->method('getPathInfo') - ->will($this->returnValue('/foo/bar')); + $request = new Request( + 'GET', + '/foo/bar' + ); $extractorFactory = new ExtractorFactory('/foo/'); $extractor = $extractorFactory->createPathExtractor(); - $this->assertSame('/bar', $extractor($this->request)); + $this->assertSame('/bar', $extractor($request)); } public function testGetPathWithBasePathThatDoesNotMatch() { - $this->request - ->expects($this->once()) - ->method('getPathInfo') - ->will($this->returnValue('/bar')); + $request = new Request( + 'GET', + '/bar' + ); $extractorFactory = new ExtractorFactory('/foo'); $extractor = $extractorFactory->createPathExtractor(); - $this->assertSame('', $extractor($this->request)); + $this->assertSame('', $extractor($request)); } public function testGetHeaderWithExistingHeader() { $request = new Request( - [], - [], - [], - [], - [], - ['HTTP_CONTENT_TYPE' => 'application/json'] + 'GET', + '/', + ['Content-Type' => 'application/json'] ); $extractorFactory = new ExtractorFactory('/foo'); @@ -101,12 +97,9 @@ public function testGetHeaderWithExistingHeader() public function testGetHeaderWithNonExistingHeader() { $request = new Request( - [], - [], - [], - [], - [], - ['HTTP_X_FOO' => 'bar'] + 'GET', + '/', + ['X-Foo' => 'bar'] ); $extractorFactory = new ExtractorFactory('/foo'); @@ -118,12 +111,9 @@ public function testGetHeaderWithNonExistingHeader() public function testHeaderExistsWithExistingHeader() { $request = new Request( - [], - [], - [], - [], - [], - ['HTTP_CONTENT_TYPE' => 'application/json'] + 'GET', + '/', + ['Content-Type' => 'application/json'] ); $extractorFactory = new ExtractorFactory('/foo'); @@ -135,12 +125,9 @@ public function testHeaderExistsWithExistingHeader() public function testHeaderExistsWithNonExistingHeader() { $request = new Request( - [], - [], - [], - [], - [], - ['HTTP_X_FOO' => 'bar'] + 'GET', + '/', + ['X-Foo' => 'bar'] ); $extractorFactory = new ExtractorFactory('/foo'); diff --git a/tests/Matcher/StringMatcherTest.php b/tests/Matcher/StringMatcherTest.php index 32df60c..e0b688c 100644 --- a/tests/Matcher/StringMatcherTest.php +++ b/tests/Matcher/StringMatcherTest.php @@ -1,9 +1,9 @@ setExtractor(static function() { return 0; }); - self::assertTrue($matcher->getMatcher()(new Request())); + self::assertTrue($matcher->getMatcher()(new Request('GET', '/'))); } } diff --git a/tests/MockBuilderIntegrationTest.php b/tests/MockBuilderIntegrationTest.php index 9b64c27..b571579 100644 --- a/tests/MockBuilderIntegrationTest.php +++ b/tests/MockBuilderIntegrationTest.php @@ -1,16 +1,16 @@ pathIs('/foo') ->methodIs($this->matches->regex('/POST/')) ->callback(static function (Request $request) { - error_log('CLOSURE MATCHER: ' . $request->getMethod() . ' ' . $request->getPathInfo()); + error_log('CLOSURE MATCHER: ' . $request->getMethod() . ' ' . $request->getUri()->getPath()); return true; }) ->then() @@ -65,9 +65,7 @@ public function testCreateExpectation() /** @var Expectation $expectation */ $expectation = current($expectations); - $request = new TestRequest(); - $request->setMethod('POST'); - $request->setRequestUri('/foo'); + $request = new TestRequest('POST', '/foo'); $run = 0; $oldValue = ini_set('error_log', '/dev/null'); @@ -82,16 +80,11 @@ public function testCreateExpectation() ini_set('error_log', $oldValue); $this->assertSame(3, $run); - $expectation->getResponse()->setDate(new DateTime('2012-11-10 09:08:07', new DateTimeZone('UTC'))); - $response = "HTTP/1.0 401 Unauthorized\r\nCache-Control: no-cache, private\r\nDate: Sat, 10 Nov 2012 09:08:07 GMT\r\nX-Foo: Bar\r\n\r\nresponse body"; - $this->assertSame($response, (string)$expectation->getResponse()); - - $this->server->setUp($expectations); $client = $this->server->getClient(); - $this->assertSame('response body', (string) $client->post('/foo')->send()->getBody()); + $this->assertSame('response body', (string) $client->post('/foo')->getBody()); $this->assertContains('CLOSURE MATCHER: POST /foo', $this->server->getErrorOutput()); } @@ -118,9 +111,9 @@ public function testCreateTwoExpectationsAfterEachOther() ->end(); $this->server->setUp($this->builder->flushExpectations()); - $this->assertSame('POST 1', (string) $this->server->getClient()->post('/post-resource-1')->send()->getBody()); - $this->assertSame('POST 2', (string) $this->server->getClient()->post('/post-resource-2')->send()->getBody()); - $this->assertSame('POST 1', (string) $this->server->getClient()->post('/post-resource-1')->send()->getBody()); - $this->assertSame('POST 2', (string) $this->server->getClient()->post('/post-resource-2')->send()->getBody()); + $this->assertSame('POST 1', (string) $this->server->getClient()->post('/post-resource-1')->getBody()); + $this->assertSame('POST 2', (string) $this->server->getClient()->post('/post-resource-2')->getBody()); + $this->assertSame('POST 1', (string) $this->server->getClient()->post('/post-resource-1')->getBody()); + $this->assertSame('POST 2', (string) $this->server->getClient()->post('/post-resource-2')->getBody()); } } diff --git a/tests/PHPUnit/HttpMockMultiPHPUnitIntegrationTest.php b/tests/PHPUnit/HttpMockMultiPHPUnitIntegrationTest.php index d4561ef..b86ba44 100644 --- a/tests/PHPUnit/HttpMockMultiPHPUnitIntegrationTest.php +++ b/tests/PHPUnit/HttpMockMultiPHPUnitIntegrationTest.php @@ -1,9 +1,9 @@ end(); $this->http['firstNamedServer']->setUp(); - $this->assertSame($path . ' body', (string) $this->http['firstNamedServer']->client->get($path)->send()->getBody()); + $this->assertSame($path . ' body', (string) $this->http['firstNamedServer']->client->get($path)->getBody()); $request = $this->http['firstNamedServer']->requests->latest(); $this->assertSame('GET', $request->getMethod()); - $this->assertSame($path, $request->getPath()); + $this->assertSame($path, $request->getUri()->getPath()); $request = $this->http['firstNamedServer']->requests->last(); $this->assertSame('GET', $request->getMethod()); - $this->assertSame($path, $request->getPath()); + $this->assertSame($path, $request->getUri()->getPath()); $request = $this->http['firstNamedServer']->requests->first(); $this->assertSame('GET', $request->getMethod()); - $this->assertSame($path, $request->getPath()); + $this->assertSame($path, $request->getUri()->getPath()); $request = $this->http['firstNamedServer']->requests->at(0); $this->assertSame('GET', $request->getMethod()); - $this->assertSame($path, $request->getPath()); + $this->assertSame($path, $request->getUri()->getPath()); $request = $this->http['firstNamedServer']->requests->pop(); $this->assertSame('GET', $request->getMethod()); - $this->assertSame($path, $request->getPath()); + $this->assertSame($path, $request->getUri()->getPath()); - $this->assertSame($path . ' body', (string) $this->http['firstNamedServer']->client->get($path)->send()->getBody()); + $this->assertSame($path . ' body', (string) $this->http['firstNamedServer']->client->get($path)->getBody()); $request = $this->http['firstNamedServer']->requests->shift(); $this->assertSame('GET', $request->getMethod()); - $this->assertSame($path, $request->getPath()); + $this->assertSame($path, $request->getUri()->getPath()); $this->expectException('UnexpectedValueException'); @@ -96,7 +96,7 @@ public function testErrorLogOutput() ->end(); $this->http['firstNamedServer']->setUp(); - $this->http['firstNamedServer']->client->get('/foo')->send(); + $this->http['firstNamedServer']->client->get('/foo'); // Should fail during tear down as we have an error_log() on the server side try { @@ -109,7 +109,7 @@ public function testErrorLogOutput() public function testFailedRequest() { - $response = $this->http['firstNamedServer']->client->get('/foo')->send(); + $response = $this->http['firstNamedServer']->client->get('/foo'); $this->assertSame(404, $response->getStatusCode()); $this->assertSame('No matching expectation found', (string) $response->getBody()); } @@ -122,7 +122,7 @@ public function testStopServer() /** @depends testStopServer */ public function testHttpServerIsRestartedIfATestStopsIt() { - $response = $this->http['firstNamedServer']->client->get('/')->send(); + $response = $this->http['firstNamedServer']->client->get('/'); $this->assertSame(404, $response->getStatusCode()); } @@ -136,11 +136,11 @@ public function testLimitDurationOfAResponse() ->body('POST METHOD') ->end(); $this->http['firstNamedServer']->setUp(); - $firstResponse = $this->http['firstNamedServer']->client->post('/')->send(); + $firstResponse = $this->http['firstNamedServer']->client->post('/'); $this->assertSame(200, $firstResponse->getStatusCode()); - $secondResponse = $this->http['firstNamedServer']->client->post('/')->send(); + $secondResponse = $this->http['firstNamedServer']->client->post('/'); $this->assertSame(410, $secondResponse->getStatusCode()); - $this->assertSame('Expectation no longer applicable', $secondResponse->getBody(true)); + $this->assertSame('Expectation no longer applicable', $secondResponse->getBody()->getContents()); $this->http['firstNamedServer']->mock ->exactly(2) @@ -150,13 +150,13 @@ public function testLimitDurationOfAResponse() ->body('POST METHOD') ->end(); $this->http['firstNamedServer']->setUp(); - $firstResponse = $this->http['firstNamedServer']->client->post('/')->send(); + $firstResponse = $this->http['firstNamedServer']->client->post('/'); $this->assertSame(200, $firstResponse->getStatusCode()); - $secondResponse = $this->http['firstNamedServer']->client->post('/')->send(); + $secondResponse = $this->http['firstNamedServer']->client->post('/'); $this->assertSame(200, $secondResponse->getStatusCode()); - $thirdResponse = $this->http['firstNamedServer']->client->post('/')->send(); + $thirdResponse = $this->http['firstNamedServer']->client->post('/'); $this->assertSame(410, $thirdResponse->getStatusCode()); - $this->assertSame('Expectation no longer applicable', $thirdResponse->getBody(true)); + $this->assertSame('Expectation no longer applicable', (string)$thirdResponse->getBody()); $this->http['firstNamedServer']->mock ->any() @@ -166,11 +166,11 @@ public function testLimitDurationOfAResponse() ->body('POST METHOD') ->end(); $this->http['firstNamedServer']->setUp(); - $firstResponse = $this->http['firstNamedServer']->client->post('/')->send(); + $firstResponse = $this->http['firstNamedServer']->client->post('/'); $this->assertSame(200, $firstResponse->getStatusCode()); - $secondResponse = $this->http['firstNamedServer']->client->post('/')->send(); + $secondResponse = $this->http['firstNamedServer']->client->post('/'); $this->assertSame(200, $secondResponse->getStatusCode()); - $thirdResponse = $this->http['firstNamedServer']->client->post('/')->send(); + $thirdResponse = $this->http['firstNamedServer']->client->post('/'); $this->assertSame(200, $thirdResponse->getStatusCode()); } @@ -180,10 +180,10 @@ public function testCallbackOnResponse() ->when() ->methodIs('POST') ->then() - ->callback(static function(Response $response) {$response->setContent('CALLBACK');}) + ->callback(static function(Response $response) {return $response->withBody(\GuzzleHttp\Psr7\stream_for('CALLBACK'));}) ->end(); $this->http['firstNamedServer']->setUp(); - $this->assertSame('CALLBACK', $this->http['firstNamedServer']->client->post('/')->send()->getBody(true)); + $this->assertSame('CALLBACK', (string)$this->http['firstNamedServer']->client->post('/')->getBody()); } public function testComplexResponse() @@ -198,11 +198,16 @@ public function testComplexResponse() ->end(); $this->http['firstNamedServer']->setUp(); $response = $this->http['firstNamedServer']->client - ->post('/', ['x-client-header' => 'header-value'], ['post-key' => 'post-value'])->send(); - $this->assertSame('BODY', $response->getBody(true)); + ->post('/', [ + 'headers' => ['x-client-header' => 'header-value'], + 'form_params' => ['post-key' => 'post-value'] + ]); + $this->assertSame('BODY', (string)$response->getBody()); $this->assertSame(201, $response->getStatusCode()); - $this->assertSame('Bar', (string) $response->getHeader('X-Foo')); - $this->assertSame('post-value', $this->http['firstNamedServer']->requests->latest()->getPostField('post-key')); + $this->assertSame('Bar', (string) $response->getHeaderLine('X-Foo')); + + parse_str($this->http['firstNamedServer']->requests->latest()->getBody()->getContents(), $body); + $this->assertSame('post-value', $body['post-key']); } public function testPutRequest() @@ -217,11 +222,15 @@ public function testPutRequest() ->end(); $this->http['firstNamedServer']->setUp(); $response = $this->http['firstNamedServer']->client - ->put('/', ['x-client-header' => 'header-value'], ['put-key' => 'put-value'])->send(); - $this->assertSame('BODY', $response->getBody(true)); + ->put('/', [ + 'headers' => ['x-client-header' => 'header-value'], + 'form_params' => ['put-key' => 'put-value'] + ]); + $this->assertSame('BODY', (string)$response->getBody()); $this->assertSame(201, $response->getStatusCode()); - $this->assertSame('Bar', (string) $response->getHeader('X-Foo')); - $this->assertSame('put-value', $this->http['firstNamedServer']->requests->latest()->getPostField('put-key')); + $this->assertSame('Bar', (string) $response->getHeaderLine('X-Foo')); + parse_str($this->http['firstNamedServer']->requests->latest()->getBody()->getContents(), $body); + $this->assertSame('put-value', $body['put-key']); } public function testPostRequest() @@ -236,11 +245,15 @@ public function testPostRequest() ->end(); $this->http['firstNamedServer']->setUp(); $response = $this->http['firstNamedServer']->client - ->post('/', ['x-client-header' => 'header-value'], ['post-key' => 'post-value'])->send(); - $this->assertSame('BODY', $response->getBody(true)); + ->post('/', [ + 'headers' => ['x-client-header' => 'header-value'], + 'form_params' => ['post-key' => 'post-value'] + ]); + $this->assertSame('BODY', (string)$response->getBody()); $this->assertSame(201, $response->getStatusCode()); - $this->assertSame('Bar', (string) $response->getHeader('X-Foo')); - $this->assertSame('post-value', $this->http['firstNamedServer']->requests->latest()->getPostField('post-key')); + $this->assertSame('Bar', (string) $response->getHeaderLine('X-Foo')); + parse_str($this->http['firstNamedServer']->requests->latest()->getBody()->getContents(), $body); + $this->assertSame('post-value', $body['post-key']); } public function testFatalError() diff --git a/tests/PHPUnit/HttpMockPHPUnitIntegrationBasePathTest.php b/tests/PHPUnit/HttpMockPHPUnitIntegrationBasePathTest.php index 8cc8199..a379ca4 100644 --- a/tests/PHPUnit/HttpMockPHPUnitIntegrationBasePathTest.php +++ b/tests/PHPUnit/HttpMockPHPUnitIntegrationBasePathTest.php @@ -1,8 +1,8 @@ end(); $this->http->setUp(); - $this->assertSame('/foo body', (string) $this->http->client->get('/custom-base-path/foo')->send()->getBody()); + $this->assertSame('/foo body', (string) $this->http->client->get('/custom-base-path/foo')->getBody()); $request = $this->http->requests->latest(); $this->assertSame('GET', $request->getMethod()); - $this->assertSame('/custom-base-path/foo', $request->getPath()); + $this->assertSame('/custom-base-path/foo', $request->getUri()->getPath()); } } diff --git a/tests/PHPUnit/HttpMockPHPUnitIntegrationTest.php b/tests/PHPUnit/HttpMockPHPUnitIntegrationTest.php index 806e420..9b5893f 100644 --- a/tests/PHPUnit/HttpMockPHPUnitIntegrationTest.php +++ b/tests/PHPUnit/HttpMockPHPUnitIntegrationTest.php @@ -1,11 +1,12 @@ end(); $this->http->setUp(); - $this->assertSame($path . ' body', (string) $this->http->client->get($path)->send()->getBody()); + $this->assertSame($path . ' body', (string) $this->http->client->get($path)->getBody()); $request = $this->http->requests->latest(); $this->assertSame('GET', $request->getMethod()); - $this->assertSame($path, $request->getPath()); + $this->assertSame($path, $request->getUri()->getPath()); $request = $this->http->requests->last(); $this->assertSame('GET', $request->getMethod()); - $this->assertSame($path, $request->getPath()); + $this->assertSame($path, $request->getUri()->getPath()); $request = $this->http->requests->first(); $this->assertSame('GET', $request->getMethod()); - $this->assertSame($path, $request->getPath()); + $this->assertSame($path, $request->getUri()->getPath()); $request = $this->http->requests->at(0); $this->assertSame('GET', $request->getMethod()); - $this->assertSame($path, $request->getPath()); + $this->assertSame($path, $request->getUri()->getPath()); $request = $this->http->requests->pop(); $this->assertSame('GET', $request->getMethod()); - $this->assertSame($path, $request->getPath()); + $this->assertSame($path, $request->getUri()->getPath()); - $this->assertSame($path . ' body', (string) $this->http->client->get($path)->send()->getBody()); + $this->assertSame($path . ' body', (string) $this->http->client->get($path)->getBody()); $request = $this->http->requests->shift(); $this->assertSame('GET', $request->getMethod()); - $this->assertSame($path, $request->getPath()); + $this->assertSame($path, $request->getUri()->getPath()); $this->expectException('UnexpectedValueException'); @@ -96,7 +97,7 @@ public function testErrorLogOutput() ->end(); $this->http->setUp(); - $this->http->client->get('/foo')->send(); + $this->http->client->get('/foo'); // Should fail during tear down as we have an error_log() on the server side try { @@ -109,7 +110,7 @@ public function testErrorLogOutput() public function testFailedRequest() { - $response = $this->http->client->get('/foo')->send(); + $response = $this->http->client->get('/foo'); $this->assertSame(404, $response->getStatusCode()); $this->assertSame('No matching expectation found', (string) $response->getBody()); } @@ -122,7 +123,7 @@ public function testStopServer() /** @depends testStopServer */ public function testHttpServerIsRestartedIfATestStopsIt() { - $response = $this->http->client->get('/')->send(); + $response = $this->http->client->get('/'); $this->assertSame(404, $response->getStatusCode()); } @@ -136,11 +137,11 @@ public function testLimitDurationOfAResponse() ->body('POST METHOD') ->end(); $this->http->setUp(); - $firstResponse = $this->http->client->post('/')->send(); + $firstResponse = $this->http->client->post('/'); $this->assertSame(200, $firstResponse->getStatusCode()); - $secondResponse = $this->http->client->post('/')->send(); + $secondResponse = $this->http->client->post('/'); $this->assertSame(410, $secondResponse->getStatusCode()); - $this->assertSame('Expectation no longer applicable', $secondResponse->getBody(true)); + $this->assertSame('Expectation no longer applicable', (string)$secondResponse->getBody()); $this->http->mock ->exactly(2) @@ -150,13 +151,13 @@ public function testLimitDurationOfAResponse() ->body('POST METHOD') ->end(); $this->http->setUp(); - $firstResponse = $this->http->client->post('/')->send(); + $firstResponse = $this->http->client->post('/'); $this->assertSame(200, $firstResponse->getStatusCode()); - $secondResponse = $this->http->client->post('/')->send(); + $secondResponse = $this->http->client->post('/'); $this->assertSame(200, $secondResponse->getStatusCode()); - $thirdResponse = $this->http->client->post('/')->send(); + $thirdResponse = $this->http->client->post('/'); $this->assertSame(410, $thirdResponse->getStatusCode()); - $this->assertSame('Expectation no longer applicable', $thirdResponse->getBody(true)); + $this->assertSame('Expectation no longer applicable', (string)$thirdResponse->getBody()); $this->http->mock ->any() @@ -166,11 +167,11 @@ public function testLimitDurationOfAResponse() ->body('POST METHOD') ->end(); $this->http->setUp(); - $firstResponse = $this->http->client->post('/')->send(); + $firstResponse = $this->http->client->post('/'); $this->assertSame(200, $firstResponse->getStatusCode()); - $secondResponse = $this->http->client->post('/')->send(); + $secondResponse = $this->http->client->post('/'); $this->assertSame(200, $secondResponse->getStatusCode()); - $thirdResponse = $this->http->client->post('/')->send(); + $thirdResponse = $this->http->client->post('/'); $this->assertSame(200, $thirdResponse->getStatusCode()); } @@ -180,10 +181,12 @@ public function testCallbackOnResponse() ->when() ->methodIs('POST') ->then() - ->callback(static function(Response $response) {$response->setContent('CALLBACK');}) + ->callback(static function(Response $response) { + return $response->withBody(\GuzzleHttp\Psr7\stream_For('CALLBACK')); + }) ->end(); $this->http->setUp(); - $this->assertSame('CALLBACK', $this->http->client->post('/')->send()->getBody(true)); + $this->assertSame('CALLBACK', (string)$this->http->client->post('/')->getBody()); } public function testComplexResponse() @@ -198,11 +201,15 @@ public function testComplexResponse() ->end(); $this->http->setUp(); $response = $this->http->client - ->post('/', ['x-client-header' => 'header-value'], ['post-key' => 'post-value'])->send(); - $this->assertSame('BODY', $response->getBody(true)); + ->post('/', [ + 'headers' => ['x-client-header' => 'header-value'], + 'form_params' => ['post-key' => 'post-value'], + ]); + $this->assertSame('BODY', (string)$response->getBody()); $this->assertSame(201, $response->getStatusCode()); - $this->assertSame('Bar', (string) $response->getHeader('X-Foo')); - $this->assertSame('post-value', $this->http->requests->latest()->getPostField('post-key')); + $this->assertSame('Bar', (string) $response->getHeaderLine('X-Foo')); + parse_str($this->http->requests->latest()->getBody()->getContents(), $body); + $this->assertSame('post-value', $body['post-key']); } public function testPutRequest() @@ -217,11 +224,15 @@ public function testPutRequest() ->end(); $this->http->setUp(); $response = $this->http->client - ->put('/', ['x-client-header' => 'header-value'], ['put-key' => 'put-value'])->send(); - $this->assertSame('BODY', $response->getBody(true)); + ->put('/', [ + 'headers' => ['x-client-header' => 'header-value'], + 'form_params' => ['put-key' => 'put-value'] + ]); + $this->assertSame('BODY', (string)$response->getBody()); $this->assertSame(201, $response->getStatusCode()); - $this->assertSame('Bar', (string) $response->getHeader('X-Foo')); - $this->assertSame('put-value', $this->http->requests->latest()->getPostField('put-key')); + $this->assertSame('Bar', (string) $response->getHeaderLine('X-Foo')); + parse_str($this->http->requests->latest()->getBody()->getContents(), $body); + $this->assertSame('put-value', $body['put-key']); } public function testPostRequest() @@ -236,11 +247,15 @@ public function testPostRequest() ->end(); $this->http->setUp(); $response = $this->http->client - ->post('/', ['x-client-header' => 'header-value'], ['post-key' => 'post-value'])->send(); - $this->assertSame('BODY', $response->getBody(true)); + ->post('/', [ + 'headers' => ['x-client-header' => 'header-value'], + 'form_params' => ['post-key' => 'post-value'] + ]); + $this->assertSame('BODY', (string)$response->getBody()); $this->assertSame(201, $response->getStatusCode()); - $this->assertSame('Bar', (string) $response->getHeader('X-Foo')); - $this->assertSame('post-value', $this->http->requests->latest()->getPostField('post-key')); + $this->assertSame('Bar', (string) $response->getHeaderLine('X-Foo')); + parse_str($this->http->requests->latest()->getBody()->getContents(), $body); + $this->assertSame('post-value', $body['post-key']); } public function testCountRequests() @@ -254,7 +269,7 @@ public function testCountRequests() $this->http->setUp(); $this->assertCount(0, $this->http->requests); - $this->assertSame('resource body', (string) $this->http->client->get('/resource')->send()->getBody()); + $this->assertSame('resource body', (string) $this->http->client->get('/resource')->getBody()); $this->assertCount(1, $this->http->requests); } @@ -264,7 +279,8 @@ public function testMatchQueryString() ->when() ->callback( function (Request $request) { - return $request->query->has('key1'); + parse_str($request->getUri()->getQuery(), $query); + return isset($query['key1']); } ) ->methodIs('GET') @@ -273,10 +289,10 @@ function (Request $request) { ->end(); $this->http->setUp(); - $this->assertSame('query string', (string) $this->http->client->get('/?key1=')->send()->getBody()); + $this->assertSame('query string', (string) $this->http->client->get('/?key1=')->getBody()); - $this->assertEquals(Response::HTTP_NOT_FOUND, (string) $this->http->client->get('/')->send()->getStatusCode()); - $this->assertEquals(Response::HTTP_NOT_FOUND, (string) $this->http->client->post('/')->send()->getStatusCode()); + $this->assertEquals(StatusCode::HTTP_NOT_FOUND, (string) $this->http->client->get('/')->getStatusCode()); + $this->assertEquals(StatusCode::HTTP_NOT_FOUND, (string) $this->http->client->post('/')->getStatusCode()); } public function testMatchRegex() @@ -289,8 +305,8 @@ public function testMatchRegex() ->end(); $this->http->setUp(); - $this->assertSame('response', (string) $this->http->client->get('/')->send()->getBody()); - $this->assertSame('response', (string) $this->http->client->get('/')->send()->getBody()); + $this->assertSame('response', (string) $this->http->client->get('/')->getBody()); + $this->assertSame('response', (string) $this->http->client->get('/')->getBody()); } public function testMatchQueryParams() @@ -310,19 +326,19 @@ public function testMatchQueryParams() $this->assertSame( 'response', - (string) $this->http->client->get('/?p1=&p2=v2&p4=any&p5=v5&p6=v6')->send()->getBody() + (string) $this->http->client->get('/?p1=&p2=v2&p4=any&p5=v5&p6=v6')->getBody() ); $this->assertEquals( - Response::HTTP_NOT_FOUND, - (string) $this->http->client->get('/?p1=&p2=v2&p3=foo')->send()->getStatusCode() + StatusCode::HTTP_NOT_FOUND, + (string) $this->http->client->get('/?p1=&p2=v2&p3=foo')->getStatusCode() ); $this->assertEquals( - Response::HTTP_NOT_FOUND, - (string) $this->http->client->get('/?p1=')->send()->getStatusCode() + StatusCode::HTTP_NOT_FOUND, + (string) $this->http->client->get('/?p1=')->getStatusCode() ); $this->assertEquals( - Response::HTTP_NOT_FOUND, - (string) $this->http->client->get('/?p3=foo')->send()->getStatusCode() + StatusCode::HTTP_NOT_FOUND, + (string) $this->http->client->get('/?p3=foo')->getStatusCode() ); } diff --git a/tests/Request/UnifiedRequestTest.php b/tests/Request/UnifiedRequestTest.php deleted file mode 100644 index 479a384..0000000 --- a/tests/Request/UnifiedRequestTest.php +++ /dev/null @@ -1,134 +0,0 @@ -wrappedRequest = $this->createMock('Guzzle\Http\Message\RequestInterface'); - $this->wrappedEntityEnclosingRequest = $this->createMock('Guzzle\Http\Message\EntityEnclosingRequestInterface'); - $this->unifiedRequest = new UnifiedRequest($this->wrappedRequest); - $this->unifiedEnclosingEntityRequest = new UnifiedRequest($this->wrappedEntityEnclosingRequest); - } - - public static function provideMethods() - { - return [ - ['getParams'], - ['getHeaders'], - ['getHeaderLines'], - ['getRawHeaders'], - ['getQuery'], - ['getMethod'], - ['getScheme'], - ['getHost'], - ['getProtocolVersion'], - ['getPath'], - ['getPort'], - ['getUsername'], - ['getPassword'], - ['getUrl'], - ['getCookies'], - ['getHeader', ['header']], - ['hasHeader', ['header']], - ['getUrl', [false]], - ['getUrl', [true]], - ['getCookie', ['cookieName']], - ]; - } - - public static function provideEntityEnclosingInterfaceMethods() - { - return [ - ['getBody'], - ['getPostField', ['postField']], - ['getPostFields'], - ['getPostFiles'], - ['getPostFile', ['fileName']], - ]; - } - - /** @dataProvider provideMethods */ - public function testMethodsFromRequestInterface($method, array $params = []) - { - $this->wrappedRequest - ->expects($this->once()) - ->method($method) - ->will($this->returnValue('REQ')) - ->with(...$params); - $this->assertSame('REQ', call_user_func_array([$this->unifiedRequest, $method], $params)); - - - $this->wrappedEntityEnclosingRequest - ->expects($this->once()) - ->method($method) - ->will($this->returnValue('ENTITY_ENCL_REQ')) - ->with(...$params); - $this->assertSame( - 'ENTITY_ENCL_REQ', - call_user_func_array([$this->unifiedEnclosingEntityRequest, $method], $params) - ); - } - - /** @dataProvider provideEntityEnclosingInterfaceMethods */ - public function testEntityEnclosingInterfaceMethods($method, array $params = []) - { - $this->wrappedEntityEnclosingRequest - ->expects($this->once()) - ->method($method) - ->will($this->returnValue('ENTITY_ENCL_REQ')) - ->with(...$params); - - $this->assertSame( - 'ENTITY_ENCL_REQ', - call_user_func_array([$this->unifiedEnclosingEntityRequest, $method], $params) - ); - - $this->wrappedRequest - ->expects($this->any()) - ->method('getMethod') - ->will($this->returnValue('METHOD')); - $this->wrappedRequest - ->expects($this->any()) - ->method('getPath') - ->will($this->returnValue('/foo')); - - $this->expectException('BadMethodCallException'); - - $this->expectExceptionMessage( - - sprintf( - 'Cannot call method "%s" on a request that does not enclose an entity. Did you expect a POST/PUT request instead of METHOD /foo?', - $method - ) - - ); - call_user_func_array([$this->unifiedRequest, $method], $params); - } - - public function testUserAgent() - { - $this->assertNull($this->unifiedRequest->getUserAgent()); - - $unifiedRequest = new UnifiedRequest($this->wrappedRequest, ['userAgent' => 'UA']); - $this->assertSame('UA', $unifiedRequest->getUserAgent()); - } -} diff --git a/tests/RequestCollectionFacadeTest.php b/tests/RequestCollectionFacadeTest.php index e111263..40705c7 100644 --- a/tests/RequestCollectionFacadeTest.php +++ b/tests/RequestCollectionFacadeTest.php @@ -1,13 +1,15 @@ client = $this->createMock('Guzzle\Http\ClientInterface'); + $this->client = $this->createMock(Client::class); $this->facade = new RequestCollectionFacade($this->client); $this->request = new Request('GET', '/_request/last'); - $this->request->setClient($this->client); } public static function provideMethodAndUrls() @@ -48,7 +49,7 @@ public function testRequestingLatestRequest($method, $path, array $args = [], $h $request = call_user_func_array([$this->facade, $method], $args); $this->assertSame('POST', $request->getMethod()); - $this->assertSame('/foo', $request->getPath()); + $this->assertSame('/foo', $request->getUri()->getPath()); $this->assertSame('RECORDED=1', (string) $request->getBody()); } @@ -60,13 +61,11 @@ public function testRequestLatestResponseWithHttpAuth($method, $path, array $arg $request = call_user_func_array([$this->facade, $method], $args); $this->assertSame('POST', $request->getMethod()); - $this->assertSame('/foo', $request->getPath()); + $this->assertSame('/foo', $request->getUri()->getPath()); $this->assertSame('RECORDED=1', (string) $request->getBody()); - $this->assertSame('host', $request->getHost()); - $this->assertSame(1234, $request->getPort()); - $this->assertSame('username', $request->getUsername()); - $this->assertSame('password', $request->getPassword()); - $this->assertSame('CUSTOM UA', $request->getUserAgent()); + $this->assertSame('localhost', $request->getUri()->getHost()); + $this->assertSame(1234, $request->getUri()->getPort()); + $this->assertSame('CUSTOM UA', $request->getHeaderLine(('User-Agent'))); } /** @dataProvider provideMethodAndUrls */ @@ -117,23 +116,19 @@ private function mockClient($path, Response $response, $method) { $this->client ->expects($this->once()) - ->method($method) - ->with($path) - ->will($this->returnValue($this->request)); - - $this->client - ->expects($this->once()) - ->method('send') - ->with($this->request) + ->method('__call') + ->with($method, [$path]) ->will($this->returnValue($response)); } private function createSimpleResponse() { - $recordedRequest = new TestRequest(); - $recordedRequest->setMethod('POST'); - $recordedRequest->setRequestUri('/foo'); - $recordedRequest->setContent('RECORDED=1'); + $recordedRequest = new TestRequest( + 'POST', + 'http://localhost/foo', + [], + 'RECORDED=1' + ); return new Response( '200', @@ -141,7 +136,7 @@ private function createSimpleResponse() serialize( [ 'server' => [], - 'request' => (string) $recordedRequest, + 'request' => Util::serializePsrMessage($recordedRequest) ] ) ); @@ -149,27 +144,23 @@ private function createSimpleResponse() private function createComplexResponse() { - $recordedRequest = new TestRequest(); - $recordedRequest->setMethod('POST'); - $recordedRequest->setRequestUri('/foo'); - $recordedRequest->setContent('RECORDED=1'); - $recordedRequest->headers->set('Php-Auth-User', 'ignored'); - $recordedRequest->headers->set('Php-Auth-Pw', 'ignored'); - $recordedRequest->headers->set('User-Agent', 'ignored'); + $recordedRequest = new TestRequest( + 'POST', + 'http://localhost:1234/foo', + [ + 'Php-Auth-User' => 'username', + 'Php-Auth-Pw' => 'password', + 'User-Agent' => 'CUSTOM UA' + ], + 'RECORDED=1' + ); return new Response( '200', ['Content-Type' => 'text/plain; charset=UTF-8'], serialize( [ - 'server' => [ - 'HTTP_HOST' => 'host', - 'HTTP_PORT' => 1234, - 'PHP_AUTH_USER' => 'username', - 'PHP_AUTH_PW' => 'password', - 'HTTP_USER_AGENT' => 'CUSTOM UA', - ], - 'request' => (string) $recordedRequest, + 'request' => Util::serializePsrMessage($recordedRequest), ] ) );