Test Failed
Pull Request — master (#33)
by Joao
01:54
created

ApiRequester::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
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\ApiTools\Swagger\SwaggerSchema;
9
use GuzzleHttp\Client;
10
use GuzzleHttp\ClientInterface;
11
use GuzzleHttp\Exception\BadResponseException;
12
use GuzzleHttp\Exception\GuzzleException;
13
use GuzzleHttp\Psr7\Request;
14
15
class ApiRequester
16
{
17
    protected $method = 'get';
18
    protected $path = '/';
19
    protected $requestHeader = [];
20
    protected $query = [];
21
    protected $requestBody = null;
22
    /**
23
     * @var Schema
24
     */
25
    protected $swaggerSchema = null;
26
27
    protected $statusExpected = 200;
28
    protected $assertHeader = [];
29
30
    /**
31
     * @var ClientInterface
32
     */
33
    protected $guzzleHttpClient;
34
35
    public function __construct()
36
    {
37
        $this->guzzleHttpClient = new Client(['headers' => ['User-Agent' => 'Swagger Test']]);
38
    }
39
40
    /**
41
     * @param Schema $schema
42
     * @return $this
43
     */
44
    public function withSwaggerSchema($schema)
45
    {
46
        $this->swaggerSchema = $schema;
47
48
        return $this;
49
    }
50
51
    /**
52
     * @return bool
53
     */
54
    public function hasSwaggerSchema()
55
    {
56
        return !empty($this->swaggerSchema);
57
    }
58
59
    /**
60
     * @param string $method
61
     * @return ApiRequester
62
     */
63
    public function withMethod($method)
64
    {
65
        $this->method = $method;
66
67
        return $this;
68
    }
69
70
    /**
71
     * @param string $path
72
     * @return ApiRequester
73
     */
74
    public function withPath($path)
75
    {
76
        $this->path = $path;
77
78
        return $this;
79
    }
80
81
    /**
82
     * @param array $requestHeader
83
     * @return ApiRequester
84
     */
85
    public function withRequestHeader($requestHeader)
86
    {
87
        if (is_null($requestHeader)) {
88
            $this->requestHeader = [];
89
            return $this;
90
        }
91
92
        $this->requestHeader = array_merge($this->requestHeader, $requestHeader);
93
94
        return $this;
95
    }
96
97
    /**
98
     * @param array $query
99
     * @return ApiRequester
100
     */
101
    public function withQuery($query)
102
    {
103
        if (is_null($query)) {
104
            $this->query = [];
105
            return $this;
106
        }
107
108
        $this->query = array_merge($this->query, $query);
109
110
        return $this;
111
    }
112
113
    /**
114
     * @param null $requestBody
115
     * @return ApiRequester
116
     */
117
    public function withRequestBody($requestBody)
118
    {
119
        $this->requestBody = $requestBody;
120
121
        return $this;
122
    }
123
124
    public function assertResponseCode($code)
125
    {
126
        $this->statusExpected = $code;
127
128
        return $this;
129
    }
130
131
    public function assertHeaderContains($header, $contains)
132
    {
133
        $this->assertHeader[$header] = $contains;
134
135
        return $this;
136
    }
137
138
    /**
139
     * @return mixed
140
     * @throws Exception\DefinitionNotFoundException
141
     * @throws Exception\HttpMethodNotFoundException
142
     * @throws Exception\InvalidDefinitionException
143
     * @throws Exception\PathNotFoundException
144
     * @throws GuzzleException
145
     * @throws NotMatchedException
146
     * @throws StatusCodeNotMatchedException
147
     */
148
    public function send()
149
    {
150
        // Preparing Parameters
151
        $paramInQuery = null;
152
        if (!empty($this->query)) {
153
            $paramInQuery = '?' . http_build_query($this->query);
154
        }
155
156
        // Preparing Header
157
        if (empty($this->requestHeader)) {
158
            $this->requestHeader = [];
159
        }
160
        $header = array_merge(
161
            [
162
                'Accept' => 'application/json'
163
            ],
164
            $this->requestHeader
165
        );
166
167
        // Defining Variables
168
        $serverUrl = $this->swaggerSchema->getServerUrl() . $paramInQuery;
169
        $basePath = $this->swaggerSchema->getBasePath();
170
        $pathName = $this->path;
171
172
        // Check if the body is the expected before request
173
        $bodyRequestDef = $this->swaggerSchema->getRequestParameters("$basePath$pathName", $this->method);
174
        $bodyRequestDef->match($this->requestBody);
175
176
        // Make the request
177
        $request = new Request(
178
            $this->method,
179
            $serverUrl . $pathName . $paramInQuery,
180
            $header,
181
            json_encode($this->requestBody)
182
        );
183
184
        $statusReturned = null;
185
        try {
186
            $response = $this->guzzleHttpClient->send($request, ['allow_redirects' => false]);
187
            $responseHeader = $response->getHeaders();
188
            $responseBody = json_decode((string) $response->getBody(), true);
189
            $statusReturned = $response->getStatusCode();
190
        } catch (BadResponseException $ex) {
191
            $responseHeader = $ex->getResponse()->getHeaders();
192
            $responseBody = json_decode((string) $ex->getResponse()->getBody(), true);
193
            $statusReturned = $ex->getResponse()->getStatusCode();
194
        }
195
196
        // Assert results
197
        if ($this->statusExpected != $statusReturned) {
198
            throw new StatusCodeNotMatchedException(
199
                "Status code not matched $statusReturned",
200
                $responseBody
201
            );
202
        }
203
204
        $bodyResponseDef = $this->swaggerSchema->getResponseParameters(
205
            "$basePath$pathName",
206
            $this->method,
207
            $this->statusExpected
208
        );
209
        $bodyResponseDef->match($responseBody);
210
211
        if (count($this->assertHeader) > 0) {
212
            foreach ($this->assertHeader as $key => $value) {
213
                if (!isset($responseHeader[$key]) || strpos($responseHeader[$key][0], $value) === false) {
214
                    throw new NotMatchedException(
215
                        "Does not exists header '$key' with value '$value'",
216
                        $responseHeader
217
                    );
218
                }
219
            }
220
        }
221
222
        return $responseBody;
223
    }
224
}
225