From 517e46c8ef89fe875ec78eeadf530ddd5a0300b1 Mon Sep 17 00:00:00 2001 From: Sullivan SENECHAL Date: Tue, 6 Oct 2015 17:28:33 +0200 Subject: [PATCH 1/2] Guzzle 6 support --- composer.json | 2 +- src/Context/WebApiContext.php | 77 ++++++++++++++++-------- src/ServiceContainer/WebApiExtension.php | 13 ++++ 3 files changed, 67 insertions(+), 25 deletions(-) diff --git a/composer.json b/composer.json index 48d3658..fd79253 100644 --- a/composer.json +++ b/composer.json @@ -19,7 +19,7 @@ "require": { "php": ">=5.4", "behat/behat": "~3.0", - "guzzlehttp/guzzle": "4 - 5", + "guzzlehttp/guzzle": "4 - 6", "phpunit/phpunit": "4 - 5" }, diff --git a/src/Context/WebApiContext.php b/src/Context/WebApiContext.php index f21b24b..fa008df 100644 --- a/src/Context/WebApiContext.php +++ b/src/Context/WebApiContext.php @@ -14,7 +14,10 @@ use Behat\Gherkin\Node\TableNode; use GuzzleHttp\ClientInterface; use GuzzleHttp\Exception\RequestException; +use GuzzleHttp\Psr7\Request; use PHPUnit_Framework_Assert as Assertions; +use Psr\Http\Message\RequestInterface; +use Psr\Http\Message\ResponseInterface; /** * Provides web API description definitions. @@ -39,12 +42,12 @@ class WebApiContext implements ApiClientAwareContext private $headers = array(); /** - * @var \GuzzleHttp\Message\RequestInterface + * @var \GuzzleHttp\Message\RequestInterface|RequestInterface */ private $request; /** - * @var \GuzzleHttp\Message\ResponseInterface + * @var \GuzzleHttp\Message\ResponseInterface|ResponseInterface */ private $response; @@ -97,9 +100,14 @@ public function iSetHeaderWithValue($name, $value) public function iSendARequest($method, $url) { $url = $this->prepareUrl($url); - $this->request = $this->getClient()->createRequest($method, $url); - if (!empty($this->headers)) { - $this->request->addHeaders($this->headers); + + if (version_compare(ClientInterface::VERSION, '6.0', '>=')) { + $this->request = new Request($method, $url, $this->headers); + } else { + $this->request = $this->getClient()->createRequest($method, $url); + if (!empty($this->headers)) { + $this->request->addHeaders($this->headers); + } } $this->sendRequest(); @@ -126,9 +134,14 @@ public function iSendARequestWithValues($method, $url, TableNode $post) $bodyOption = array( 'body' => json_encode($fields), ); - $this->request = $this->getClient()->createRequest($method, $url, $bodyOption); - if (!empty($this->headers)) { - $this->request->addHeaders($this->headers); + + if (version_compare(ClientInterface::VERSION, '6.0', '>=')) { + $this->request = new Request($method, $url, $this->headers, $bodyOption['body']); + } else { + $this->request = $this->getClient()->createRequest($method, $url, $bodyOption); + if (!empty($this->headers)) { + $this->request->addHeaders($this->headers); + } } $this->sendRequest(); @@ -148,14 +161,19 @@ public function iSendARequestWithBody($method, $url, PyStringNode $string) $url = $this->prepareUrl($url); $string = $this->replacePlaceHolder(trim($string)); - $this->request = $this->getClient()->createRequest( - $method, - $url, - array( - 'headers' => $this->getHeaders(), - 'body' => $string, - ) - ); + if (version_compare(ClientInterface::VERSION, '6.0', '>=')) { + $this->request = new Request($method, $url, $this->headers, $string); + } else { + $this->request = $this->getClient()->createRequest( + $method, + $url, + array( + 'headers' => $this->getHeaders(), + 'body' => $string, + ) + ); + } + $this->sendRequest(); } @@ -175,11 +193,16 @@ public function iSendARequestWithFormData($method, $url, PyStringNode $body) $fields = array(); parse_str(implode('&', explode("\n", $body)), $fields); - $this->request = $this->getClient()->createRequest($method, $url); - /** @var \GuzzleHttp\Post\PostBodyInterface $requestBody */ - $requestBody = $this->request->getBody(); - foreach ($fields as $key => $value) { - $requestBody->setField($key, $value); + + if (version_compare(ClientInterface::VERSION, '6.0', '>=')) { + $this->request = new Request($method, $url, ['Content-Type' => 'application/x-www-form-urlencoded'], http_build_query($fields, null, '&')); + } else { + $this->request = $this->getClient()->createRequest($method, $url); + /** @var \GuzzleHttp\Post\PostBodyInterface $requestBody */ + $requestBody = $this->request->getBody(); + foreach ($fields as $key => $value) { + $requestBody->setField($key, $value); + } } $this->sendRequest(); @@ -241,7 +264,7 @@ public function theResponseShouldNotContain($text) public function theResponseShouldContainJson(PyStringNode $jsonString) { $etalon = json_decode($this->replacePlaceHolder($jsonString->getRaw()), true); - $actual = $this->response->json(); + $actual = json_decode($this->response->getBody(), true); if (null === $etalon) { throw new \RuntimeException( @@ -249,6 +272,12 @@ public function theResponseShouldContainJson(PyStringNode $jsonString) ); } + if (null === $actual) { + throw new \RuntimeException( + "Can not convert actual to json:\n" . $this->replacePlaceHolder((string) $this->response->getBody()) + ); + } + Assertions::assertGreaterThanOrEqual(count($etalon), count($actual)); foreach ($etalon as $key => $needle) { Assertions::assertArrayHasKey($key, $actual); @@ -269,9 +298,9 @@ public function printResponse() echo sprintf( "%s %s => %d:\n%s", $request->getMethod(), - $request->getUrl(), + (string) ($request instanceof RequestInterface ? $request->getUri() : $request->getUrl()), $response->getStatusCode(), - $response->getBody() + (string) $response->getBody() ); } diff --git a/src/ServiceContainer/WebApiExtension.php b/src/ServiceContainer/WebApiExtension.php index 5418b78..e322543 100644 --- a/src/ServiceContainer/WebApiExtension.php +++ b/src/ServiceContainer/WebApiExtension.php @@ -13,6 +13,7 @@ use Behat\Behat\Context\ServiceContainer\ContextExtension; use Behat\Testwork\ServiceContainer\Extension as ExtensionInterface; use Behat\Testwork\ServiceContainer\ExtensionManager; +use GuzzleHttp\ClientInterface; use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Definition; @@ -68,6 +69,18 @@ public function load(ContainerBuilder $container, array $config) private function loadClient(ContainerBuilder $container, $config) { + // Guzzle 6 BC bridge + if (version_compare(ClientInterface::VERSION, '6.0', '>=')) { + $config['base_uri'] = $config['base_url']; + unset($config['bar_url']); + + if (isset($config['defaults'])) { + $defaults = $config['defaults']; + unset($config['defaults']); + $config = array_merge($config, $defaults); + } + } + $definition = new Definition('GuzzleHttp\Client', array($config)); $container->setDefinition(self::CLIENT_ID, $definition); } From 0422549d3682fea7d1decad93ec355a03690be3c Mon Sep 17 00:00:00 2001 From: Sullivan SENECHAL Date: Tue, 6 Oct 2015 17:41:05 +0200 Subject: [PATCH 2/2] Multiple Guzzle versions on Travis --- .travis.yml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.travis.yml b/.travis.yml index e1950dc..b5c0d14 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,12 +7,19 @@ php: - 7.0 - hhvm +matrix: + fast_finish: true + include: + - php: 5.6 + env: GUZZLE_VERSION=4.* + before_install: # start a web server on port 8080, running in the background - bin/start_server.sh before_script: - composer self-update + - if [ "$GUZZLE_VERSION" != "" ]; then composer require "guzzlehttp/guzzle:${GUZZLE_VERSION}" --no-update; fi; - composer install --prefer-source - export LANG=C - export PATH=vendor/bin:$PATH