Skip to content

Commit b02886f

Browse files
authored
Merge pull request #52 from tyx/feature/php-http
📦 Move to php-http to replace egeloen/http-adapter
2 parents b227630 + 2b10927 commit b02886f

File tree

12 files changed

+80
-158
lines changed

12 files changed

+80
-158
lines changed

.travis.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
language: php
22

33
php:
4-
- 5.4
54
- 5.5
65
- 5.6
76
- 7.0

README.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,19 @@ default:
1717
rest:
1818
base_url: http://localhost:8888
1919
store_response: true
20-
adaptor_name: curl # Should be one of these adapters : https://github.com/egeloen/ivory-http-adapter/blob/master/doc/adapters.md#factory
2120
suites:
2221
default:
2322
contexts:
2423
- Rezzza\RestApiBehatExtension\RestApiContext
2524
- Rezzza\RestApiBehatExtension\Json\JsonContext
2625
```
2726
28-
Regarding the `adaptor_name` you choose, you will have to install the deps needed on your own.
27+
Then you will need to require in your composer the http client you want to use, and the message factory.
28+
29+
Example:
30+
```
31+
composer require --dev guzzlehttp/psr7 php-http/curl-client
32+
```
2933

3034
## Usage
3135
You can use directly the `JsonContext` or `RestApiContext` by loading them in your behat.yml or use the `RestApiBrowser` and `JsonInspector` by adding them in the construct of your own context.

behat.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,3 @@ default:
1212
rest:
1313
base_url: http://localhost:8888
1414
store_response: true
15-
adaptor_name: curl

composer.json

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,22 @@
1616
"psr-4": { "Rezzza\\RestApiBehatExtension\\": "src/" }
1717
},
1818
"require": {
19-
"php": ">=5.3.2",
19+
"php": ">=5.5.0",
2020
"behat/behat": "~3.0",
2121
"atoum/atoum": "~1.0|~2.0",
2222
"symfony/property-access": "~2.4|~3.0",
2323
"justinrainbow/json-schema": "^2.0",
24-
"egeloen/http-adapter": "^0.8.0"
24+
"psr/http-message": "^1.0",
25+
"php-http/discovery": "^1.0",
26+
"php-http/client-common": "^1.2",
27+
"php-http/message": "^1.3"
2528
},
2629
"require-dev": {
2730
"silex/silex": "~1.0",
28-
"symfony/process": "~2.1|~3.0"
31+
"symfony/process": "~2.1|~3.0",
32+
"guzzlehttp/psr7": "^1.3",
33+
"php-http/curl-client": "^1.5",
34+
"php-http/mock-client": "^0.3.2"
2935
},
3036
"config": {
3137
"bin-dir": "bin/"

features/json_inspection.feature

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ Feature: Test json inspection payload
3737
Scenario: Json array should contain specific values
3838
Then the JSON array node "fooarray" should contain "bar1" element
3939
And the JSON array node "fooarray" should contain "bar2" element
40-
40+
4141
Scenario: Json array should not contain specific values
4242
Then the JSON array node "fooarray" should not contain "bar3" element
4343

features/json_inspection_edge_case.feature

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ Feature: Test json inspection edge cases
1919
rest:
2020
base_url: http://localhost:8888
2121
store_response: true
22-
adaptor_name: curl
2322
"""
2423

2524
Scenario: Reading json before loading json

features/send_request.feature

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -25,25 +25,17 @@ Feature: Test send API request
2525
And the JSON node "username" should be equal to "pablo"
2626
And the JSON node "password" should be equal to "money"
2727

28-
Scenario: Sending POST request with form data
29-
When I send a POST request to "echo" with form data:
30-
| username | pablo |
31-
| password | money |
32-
Then the response status code should be 200
33-
And the JSON node "username" should be equal to "pablo"
34-
And the JSON node "password" should be equal to "money"
35-
3628
Scenario: Add same header 2 times
3729
Given I add "header" header equal to "value"
38-
Given I add "header" header equal to "value2"
30+
And I add "header" header equal to "value2"
3931
When I send a POST request to "echo"
4032
Then the response status code should be 200
4133
And the JSON node "headers.header" should have 1 element
4234
And the JSON node "headers.header[0]" should be equal to "value, value2"
4335

4436
Scenario: Set same header 2 times
4537
Given I set "header" header equal to "value"
46-
Given I set "header" header equal to "value2"
38+
And I set "header" header equal to "value2"
4739
When I send a POST request to "echo"
4840
Then the response status code should be 200
4941
And the JSON node "headers.header" should have 1 element

src/Extension.php

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ class Extension implements ExtensionInterface
1515
public function load(ContainerBuilder $container, array $config)
1616
{
1717
$container->setParameter('rezzza.json_api.rest.base_url', $config['rest']['base_url']);
18-
$container->setParameter('rezzza.json_api.rest.adaptor_name', $config['rest']['adaptor_name']);
1918
$loader = new XmlFileLoader($container, new FileLocator(__DIR__ . '/Resources'));
2019
$loader->load('services.xml');
2120

@@ -36,7 +35,6 @@ public function configure(ArrayNodeDefinition $builder)
3635
->scalarNode('base_url')->end()
3736
->booleanNode('store_response')
3837
->defaultTrue()->end()
39-
->scalarNode('adaptor_name')->end()
4038
->end()
4139
->end()
4240
->end()

src/Resources/services.xml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020

2121
<service id="rezzza.json_api.rest.rest_api_browser" class="Rezzza\RestApiBehatExtension\Rest\RestApiBrowser" public="false">
2222
<argument>%rezzza.json_api.rest.base_url%</argument>
23-
<argument>%rezzza.json_api.rest.adaptor_name%</argument>
2423
</service>
2524

2625
<service id="rezzza.json_api.rest.rest_api_browser.resolver" class="Rezzza\RestApiBehatExtension\Rest\RestApiBrowserResolver">

src/Rest/RestApiBrowser.php

Lines changed: 46 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,9 @@
22

33
namespace Rezzza\RestApiBehatExtension\Rest;
44

5-
use Ivory\HttpAdapter\HttpAdapterFactory;
6-
use Ivory\HttpAdapter\HttpAdapterInterface as HttpClient;
7-
use Ivory\HttpAdapter\HttpAdapterException;
8-
use Ivory\HttpAdapter\Message\Request;
9-
use Zend\Diactoros\Stream;
5+
use Http\Client\HttpClient;
6+
use Http\Discovery\HttpClientDiscovery;
7+
use Http\Discovery\MessageFactoryDiscovery;
108
use Psr\Http\Message\RequestInterface;
119
use Psr\Http\Message\ResponseInterface;
1210

@@ -27,23 +25,28 @@ class RestApiBrowser
2725
/** @var ResponseStorage */
2826
private $responseStorage;
2927

28+
/** @var string */
29+
private $host;
30+
31+
/** @var MessageFactoryDiscovery */
32+
private $messageFactory;
33+
3034
/**
31-
* @param string $base_url
32-
* @param string|null $adaptor_name
33-
* @throws HttpAdapterException
35+
* @param string $host
3436
*/
35-
public function __construct($base_url, $adaptor_name, HttpClient $httpClient = null)
37+
public function __construct($host, HttpClient $httpClient = null)
3638
{
37-
if (!is_null($httpClient) && $httpClient instanceof HttpClient) {
38-
$this->httpClient = $httpClient;
39-
} else {
40-
if (is_string($adaptor_name) && HttpAdapterFactory::capable($adaptor_name)) {
41-
$this->httpClient = HttpAdapterFactory::create($adaptor_name);
42-
} else {
43-
$this->httpClient = HttpAdapterFactory::guess();
44-
}
45-
$this->httpClient->getConfiguration()->setBaseUri($base_url);
46-
}
39+
$this->host = $host;
40+
$this->httpClient = $httpClient ?: HttpClientDiscovery::find();
41+
$this->messageFactory = MessageFactoryDiscovery::find();
42+
}
43+
44+
/**
45+
* Allow to override the httpClient to use yours with specific middleware for example
46+
*/
47+
public function useHttpClient(HttpClient $httpClient)
48+
{
49+
$this->httpClient = $httpClient;
4750
}
4851

4952
/**
@@ -54,7 +57,6 @@ public function enableResponseStorage(ResponseStorage $responseStorage)
5457
$this->responseStorage = $responseStorage;
5558
}
5659

57-
5860
/**
5961
* @return ResponseInterface
6062
*/
@@ -81,78 +83,46 @@ public function getRequestHeaders()
8183
return $this->requestHeaders;
8284
}
8385

84-
/**
85-
* @return HttpClient
86-
*/
87-
public function getHttpClient()
88-
{
89-
return $this->httpClient;
90-
}
91-
9286
/**
9387
* @param string $method
94-
* @param string $url
88+
* @param string $uri
9589
* @param string|array $body
9690
*/
97-
public function sendRequest($method, $url, $body = null)
91+
public function sendRequest($method, $uri, $body = null)
9892
{
99-
try {
100-
$this->send($method, $url, $body);
101-
} catch (HttpAdapterException $e) {
102-
if ($e->hasResponse()) {
103-
$this->response = $e->getResponse();
104-
}
105-
106-
if (null === $this->response) {
107-
throw $e;
108-
}
93+
if (false === $this->hasHost($uri)) {
94+
$uri = rtrim($this->host, '/').'/'.ltrim($uri, '/');
10995
}
11096

111-
if (null !== $this->responseStorage) {
112-
$this->responseStorage->writeRawContent($this->response->getBody()->getContents());
113-
}
114-
}
97+
$this->request = $this->messageFactory->createRequest($method, $uri, $this->requestHeaders, $body);
98+
$this->response = $this->httpClient->sendRequest($this->request);
11599

116-
/**
117-
* @param string $method
118-
* @param string $uri With or without host
119-
* @param string|array $body
120-
*/
121-
private function send($method, $uri, $body = null)
122-
{
123-
if (!$this->hasHost($uri)) {
124-
$uri = rtrim($this->httpClient->getConfiguration()->getBaseUri(), '/') . '/' . ltrim($uri, '/');
125-
}
126-
$body = is_array($body) ? http_build_query($body) : $body;
127-
$stream = new Stream('php://memory', 'rw');
128-
if (is_scalar($body)) {
129-
$stream->write($body);
100+
if (null !== $this->responseStorage) {
101+
$this->responseStorage->writeRawContent((string) $this->response->getBody());
130102
}
131-
132-
$this->request = new Request($uri, $method, $stream, $this->requestHeaders);
133-
$this->response = $this->httpClient->sendRequest($this->request);
134-
// Reset headers used for the HTTP request
135-
$this->requestHeaders = [];
136103
}
137104

138105
/**
139-
* @param string $uri
140-
*
141-
* @return bool
106+
* @param string $name
107+
* @param string $value
142108
*/
143-
private function hasHost($uri)
109+
public function setRequestHeader($name, $value)
144110
{
145-
return strpos($uri, '://') !== false;
111+
$this->removeRequestHeader($name);
112+
$this->addRequestHeader($name, $value);
146113
}
147114

148115
/**
149116
* @param string $name
150117
* @param string $value
151118
*/
152-
public function setRequestHeader($name, $value)
119+
public function addRequestHeader($name, $value)
153120
{
154-
$this->removeRequestHeader($name);
155-
$this->addRequestHeader($name, $value);
121+
if (isset($this->requestHeaders[$name])) {
122+
$this->requestHeaders[$name] .= ', '.$value;
123+
} else {
124+
$this->requestHeaders[$name] = $value;
125+
}
156126
}
157127

158128
/**
@@ -166,18 +136,12 @@ private function removeRequestHeader($headerName)
166136
}
167137

168138
/**
169-
* @param string $name
170-
* @param string $value
139+
* @param string $uri
140+
*
141+
* @return bool
171142
*/
172-
public function addRequestHeader($name, $value)
143+
private function hasHost($uri)
173144
{
174-
if (isset($this->requestHeaders[$name])) {
175-
if (!is_array($this->requestHeaders[$name])) {
176-
$this->requestHeaders[$name] = [$this->requestHeaders[$name]];
177-
}
178-
$this->requestHeaders[$name][] = $value;
179-
} else {
180-
$this->requestHeaders[$name] = $value;
181-
}
145+
return strpos($uri, '://') !== false;
182146
}
183147
}

0 commit comments

Comments
 (0)