Completed
Pull Request — master (#11)
by Joao
04:44 queued 01:02
created

SwaggerRequester   A

Complexity

Total Complexity 20

Size/Duplication

Total Lines 199
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 10

Importance

Changes 0
Metric Value
wmc 20
lcom 1
cbo 10
dl 0
loc 199
c 0
b 0
f 0
rs 10

10 Methods

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