Passed
Pull Request — master (#50)
by Joao
12:18
created

AbstractRequester::send()   C

Complexity

Conditions 10
Paths 64

Size

Total Lines 75

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 75
rs 6.6787
c 0
b 0
f 0
cc 10
nc 64
nop 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace ByJG\ApiTools;
4
5
use ByJG\ApiTools\Base\Schema;
6
use ByJG\ApiTools\Exception\NotMatchedException;
7
use ByJG\ApiTools\Exception\StatusCodeNotMatchedException;
8
use ByJG\Util\Psr7\MessageException;
9
use ByJG\Util\Psr7\Request;
10
use ByJG\Util\Uri;
11
use MintWare\Streams\MemoryStream;
12
use Psr\Http\Message\RequestInterface;
13
use Psr\Http\Message\ResponseInterface;
14
15
/**
16
 * Abstract baseclass for request handlers.
17
 *
18
 * The baseclass provides processing and verification of request and response.
19
 * It only delegates the actual message exchange to the derived class. For the
20
 * messages, it uses the PSR-7 implementation from Guzzle.
21
 *
22
 * This is an implementation of the Template Method Patttern
23
 * (https://en.wikipedia.org/wiki/Template_method_pattern).
24
 */
25
abstract class AbstractRequester
26
{
27
    protected $method = 'get';
28
    protected $path = '/';
29
    protected $requestHeader = [];
30
    protected $query = [];
31
    protected $requestBody = null;
32
    /**
33
     * @var Schema
34
     */
35
    protected $schema = null;
36
37
    protected $statusExpected = 200;
38
    protected $assertHeader = [];
39
40
    /**
41
     * abstract function to be implemented by derived classes
42
     *
43
     * This function must be implemented by derived classes. It should process
44
     * the given request and return an according response.
45
     *
46
     * @param RequestInterface $request
47
     * @return ResponseInterface
48
     */
49
    abstract protected function handleRequest(RequestInterface $request);
50
51
    /**
52
     * @param Schema $schema
53
     * @return $this
54
     */
55
    public function withSchema($schema)
56
    {
57
        $this->schema = $schema;
58
59
        return $this;
60
    }
61
62
    /**
63
     * @return bool
64
     */
65
    public function hasSchema()
66
    {
67
        return !empty($this->schema);
68
    }
69
70
    /**
71
     * @param string $method
72
     * @return $this
73
     */
74
    public function withMethod($method)
75
    {
76
        $this->method = $method;
77
78
        return $this;
79
    }
80
81
    /**
82
     * @param string $path
83
     * @return $this
84
     */
85
    public function withPath($path)
86
    {
87
        $this->path = $path;
88
89
        return $this;
90
    }
91
92
    /**
93
     * @param array $requestHeader
94
     * @return $this
95
     */
96
    public function withRequestHeader($requestHeader)
97
    {
98
        if (is_null($requestHeader)) {
99
            $this->requestHeader = [];
100
            return $this;
101
        }
102
103
        $this->requestHeader = array_merge($this->requestHeader, $requestHeader);
104
105
        return $this;
106
    }
107
108
    /**
109
     * @param array $query
110
     * @return $this
111
     */
112
    public function withQuery($query)
113
    {
114
        if (is_null($query)) {
115
            $this->query = [];
116
            return $this;
117
        }
118
119
        $this->query = array_merge($this->query, $query);
120
121
        return $this;
122
    }
123
124
    /**
125
     * @param null $requestBody
126
     * @return $this
127
     */
128
    public function withRequestBody($requestBody)
129
    {
130
        $this->requestBody = $requestBody;
131
132
        return $this;
133
    }
134
135
    public function assertResponseCode($code)
136
    {
137
        $this->statusExpected = $code;
138
139
        return $this;
140
    }
141
142
    public function assertHeaderContains($header, $contains)
143
    {
144
        $this->assertHeader[$header] = $contains;
145
146
        return $this;
147
    }
148
149
    /**
150
     * @return mixed
151
     * @throws Exception\DefinitionNotFoundException
152
     * @throws Exception\GenericSwaggerException
153
     * @throws Exception\HttpMethodNotFoundException
154
     * @throws Exception\InvalidDefinitionException
155
     * @throws Exception\PathNotFoundException
156
     * @throws NotMatchedException
157
     * @throws StatusCodeNotMatchedException
158
     * @throws MessageException
159
     */
160
    public function send()
161
    {
162
        // Preparing Parameters
163
        $paramInQuery = null;
164
        if (!empty($this->query)) {
165
            $paramInQuery = '?' . http_build_query($this->query);
166
        }
167
168
        // Preparing Header
169
        if (empty($this->requestHeader)) {
170
            $this->requestHeader = [];
171
        }
172
        $header = array_merge(
173
            [
174
                'Accept' => 'application/json'
175
            ],
176
            $this->requestHeader
177
        );
178
179
        // Defining Variables
180
        $serverUrl = $this->schema->getServerUrl();
181
        $basePath = $this->schema->getBasePath();
182
        $pathName = $this->path;
183
184
        // Check if the body is the expected before request
185
        $bodyRequestDef = $this->schema->getRequestParameters("$basePath$pathName", $this->method);
186
        $bodyRequestDef->match($this->requestBody);
187
188
        // Make the request
189
        $request = Request::getInstance(Uri::getInstanceFromString($serverUrl . $pathName . $paramInQuery))
190
            ->withMethod($this->method);
191
192
        if (!empty($this->requestBody)) {
193
            $request->withBody(new MemoryStream(json_encode($this->requestBody)));
194
        }
195
196
        foreach ($header as $key => $value) {
197
            $request->withHeader($key, $value);
198
        }
199
200
        $statusReturned = null;
0 ignored issues
show
Unused Code introduced by
$statusReturned is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
201
202
        $response = $this->handleRequest($request);
203
        $responseHeader = $response->getHeaders();
204
        $responseBody = json_decode((string) $response->getBody(), true);
205
        $statusReturned = $response->getStatusCode();
206
207
        // Assert results
208
        if ($this->statusExpected != $statusReturned) {
209
            throw new StatusCodeNotMatchedException(
210
                "Status code not matched: Expected {$this->statusExpected}, got {$statusReturned}",
211
                $responseBody
212
            );
213
        }
214
215
        $bodyResponseDef = $this->schema->getResponseParameters(
216
            "$basePath$pathName",
217
            $this->method,
218
            $this->statusExpected
219
        );
220
        $bodyResponseDef->match($responseBody);
221
222
        if (count($this->assertHeader) > 0) {
223
            foreach ($this->assertHeader as $key => $value) {
224
                if (!isset($responseHeader[$key]) || strpos($responseHeader[$key][0], $value) === false) {
225
                    throw new NotMatchedException(
226
                        "Does not exists header '$key' with value '$value'",
227
                        $responseHeader
228
                    );
229
                }
230
            }
231
        }
232
233
        return $responseBody;
234
    }
235
}
236