Completed
Push — master ( 0c2a73...853a48 )
by Sébastien
11s
created

RestApiBrowser   A

Complexity

Total Complexity 18

Size/Duplication

Total Lines 151
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 10

Importance

Changes 0
Metric Value
wmc 18
lcom 1
cbo 10
dl 0
loc 151
rs 10
c 0
b 0
f 0

13 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 6 2
A useHttpClient() 0 4 1
A enableResponseStorage() 0 4 1
A getResponse() 0 4 1
A setResponse() 0 4 1
A getRequest() 0 4 1
A getRequestHeaders() 0 4 1
A sendRequest() 0 13 3
A sendRequestUntil() 0 13 1
A setRequestHeader() 0 5 1
A addRequestHeader() 0 8 2
A removeRequestHeader() 0 6 2
A hasHost() 0 4 1
1
<?php
2
3
namespace Rezzza\RestApiBehatExtension\Rest;
4
5
use Http\Client\HttpClient;
6
use Http\Discovery\HttpClientDiscovery;
7
use Http\Discovery\MessageFactoryDiscovery;
8
use Psr\Http\Message\RequestInterface;
9
use Psr\Http\Message\ResponseInterface;
10
use Tolerance\Operation\Callback;
11
use Tolerance\Operation\Runner\RetryOperationRunner;
12
use Tolerance\Operation\Runner\CallbackOperationRunner;
13
use Tolerance\Waiter\SleepWaiter;
14
use Rezzza\RestApiBehatExtension\Tolerance\ExecutionTimeLimited;
15
16
class RestApiBrowser
17
{
18
    /** @var HttpClient */
19
    private $httpClient;
20
21
    /** @var RequestInterface */
22
    private $request;
23
24
    /** @var ResponseInterface */
25
    private $response;
26
27
    /** @var array */
28
    private $requestHeaders = [];
29
30
    /** @var ResponseStorage */
31
    private $responseStorage;
32
33
    /** @var string */
34
    private $host;
35
36
    /** @var MessageFactoryDiscovery */
37
    private $messageFactory;
38
39
    /**
40
     * @param string $host
41
     */
42
    public function __construct($host, HttpClient $httpClient = null)
43
    {
44
        $this->host = $host;
45
        $this->httpClient = $httpClient ?: HttpClientDiscovery::find();
46
        $this->messageFactory = MessageFactoryDiscovery::find();
0 ignored issues
show
Documentation Bug introduced by
It seems like \Http\Discovery\MessageFactoryDiscovery::find() of type object<Http\Message\MessageFactory> is incompatible with the declared type object<Http\Discovery\MessageFactoryDiscovery> of property $messageFactory.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
47
    }
48
49
    /**
50
     * Allow to override the httpClient to use yours with specific middleware for example
51
     */
52
    public function useHttpClient(HttpClient $httpClient)
53
    {
54
        $this->httpClient = $httpClient;
55
    }
56
57
    /**
58
     * @param ResponseStorage $responseStorage
59
     */
60
    public function enableResponseStorage(ResponseStorage $responseStorage)
61
    {
62
        $this->responseStorage = $responseStorage;
63
    }
64
65
    /**
66
     * @return ResponseInterface
67
     */
68
    public function getResponse()
69
    {
70
        return $this->response;
71
    }
72
73
    /**
74
     * @param ResponseInterface $response
75
     */
76
    public function setResponse(ResponseInterface $response)
77
    {
78
        $this->response = $response;
79
    }
80
81
    public function getRequest()
82
    {
83
        return $this->request;
84
    }
85
86
    public function getRequestHeaders()
87
    {
88
        return $this->requestHeaders;
89
    }
90
91
    /**
92
     * @param string $method
93
     * @param string $uri
94
     * @param string|array $body
95
     */
96
    public function sendRequest($method, $uri, $body = null)
97
    {
98
        if (false === $this->hasHost($uri)) {
99
            $uri = rtrim($this->host, '/').'/'.ltrim($uri, '/');
100
        }
101
102
        $this->request = $this->messageFactory->createRequest($method, $uri, $this->requestHeaders, $body);
0 ignored issues
show
Bug introduced by
The method createRequest() does not seem to exist on object<Http\Discovery\MessageFactoryDiscovery>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
103
        $this->response = $this->httpClient->sendRequest($this->request);
104
105
        if (null !== $this->responseStorage) {
106
            $this->responseStorage->writeRawContent((string) $this->response->getBody());
107
        }
108
    }
109
110
    public function sendRequestUntil($method, $uri, $body, callable $assertion, $maxExecutionTime = 10)
111
    {
112
        $runner = new RetryOperationRunner(
113
            new CallbackOperationRunner(),
114
            new ExecutionTimeLimited(new SleepWaiter(), $maxExecutionTime)
115
        );
116
        $restApiBrowser = $this;
117
        $runner->run(new Callback(function () use ($restApiBrowser, $method, $uri, $body, $assertion) {
118
            $restApiBrowser->sendRequest($method, $uri, $body);
119
120
            return $assertion();
121
        }));
122
    }
123
124
    /**
125
     * @param string $name
126
     * @param string $value
127
     */
128
    public function setRequestHeader($name, $value)
129
    {
130
        $this->removeRequestHeader($name);
131
        $this->addRequestHeader($name, $value);
132
    }
133
134
    /**
135
     * @param string $name
136
     * @param string $value
137
     */
138
    public function addRequestHeader($name, $value)
139
    {
140
        if (isset($this->requestHeaders[$name])) {
141
            $this->requestHeaders[$name] .= ', '.$value;
142
        } else {
143
            $this->requestHeaders[$name] = $value;
144
        }
145
    }
146
147
    /**
148
     * @param string $headerName
149
     */
150
    private function removeRequestHeader($headerName)
151
    {
152
        if (array_key_exists($headerName, $this->requestHeaders)) {
153
            unset($this->requestHeaders[$headerName]);
154
        }
155
    }
156
157
    /**
158
     * @param string $uri
159
     *
160
     * @return bool
161
     */
162
    private function hasHost($uri)
163
    {
164
        return strpos($uri, '://') !== false;
165
    }
166
}
167