Completed
Pull Request — master (#75)
by
unknown
05:48
created

WebApiContext   A

Complexity

Total Complexity 14

Size/Duplication

Total Lines 229
Duplicated Lines 6.11 %

Coupling/Cohesion

Components 1
Dependencies 6

Importance

Changes 0
Metric Value
wmc 14
lcom 1
cbo 6
dl 14
loc 229
rs 10
c 0
b 0
f 0

12 Methods

Rating   Name   Duplication   Size   Complexity  
A iAmBasicAuthenticatingAs() 0 7 1
A iSetHeaderWithValue() 0 4 1
A iSendARequest() 0 6 1
A iSendARequestWithValues() 0 12 1
A iSendARequestWithBody() 0 7 1
A iSendARequestWithFormData() 0 13 1
A theResponseCodeShouldBe() 0 7 1
A theResponseShouldContain() 7 7 1
A theResponseShouldNotContain() 7 7 1
A theResponseShouldContainJson() 0 17 2
A theResponseHeaderShouldBe() 0 5 1
A printResponse() 0 19 2

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
<?php
2
3
/*
4
 * This file is part of the Behat WebApiExtension.
5
 *
6
 * (c) Konstantin Kudryashov <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Behat\WebApiExtension\Context;
13
14
use Behat\Gherkin\Node\PyStringNode;
15
use Behat\Gherkin\Node\TableNode;
16
use PHPUnit\Framework\Assert;
17
use Psr\Http\Client\ClientExceptionInterface;
18
use Psr\Http\Message\RequestInterface;
19
20
/**
21
 * Provides web API description definitions.
22
 *
23
 * @author Konstantin Kudryashov <[email protected]>
24
 * @author Keyclic team <[email protected]>
25
 */
26
class WebApiContext extends ApiClientContext implements ApiClientContextInterface
27
{
28
    /**
29
     * Adds Basic Authentication header to next request.
30
     *
31
     * @param string $username
32
     * @param string $password
33
     *
34
     * @Given /^I am basic authenticating as "([^"]*)" with "([^"]*)" password$/
35
     */
36
    public function iAmBasicAuthenticatingAs($username, $password): void
37
    {
38
        $authorization = base64_encode($username.':'.$password);
39
40
        $this->removeHeader('Authorization');
41
        $this->addHeader('Authorization', 'Basic '.$authorization);
42
    }
43
44
    /**
45
     * Sets a HTTP Header.
46
     *
47
     * @param string $name  header name
48
     * @param string $value header value
49
     *
50
     * @Given /^I set header "([^"]*)" with value "([^"]*)"$/
51
     */
52
    public function iSetHeaderWithValue($name, $value): void
53
    {
54
        $this->addHeader($name, $value);
55
    }
56
57
    /**
58
     * Sends HTTP request to specific relative URL.
59
     *
60
     * @param string $method request method
61
     * @param string $url    relative url
62
     *
63
     * @throws ClientExceptionInterface
64
     *
65
     * @When /^(?:I )?send a ([A-Z]+) request to "([^"]+)"$/
66
     */
67
    public function iSendARequest($method, $url): void
68
    {
69
        $url = $this->prepareUrl($url);
70
71
        $this->sendRequest($method, $url, $this->getHeaders());
72
    }
73
74
    /**
75
     * Sends HTTP request to specific URL with field values from Table.
76
     *
77
     * @param string    $method request method
78
     * @param string    $url    relative url
79
     * @param TableNode $values table of post values
80
     *
81
     * @throws ClientExceptionInterface
82
     *
83
     * @When /^(?:I )?send a ([A-Z]+) request to "([^"]+)" with values:$/
84
     */
85
    public function iSendARequestWithValues($method, $url, TableNode $values): void
86
    {
87
        $url = $this->prepareUrl($url);
88
89
        $body = array_map(function ($value) {
90
            return $this->replacePlaceHolder($value);
91
        }, $values->getRowsHash());
92
93
        $body = json_encode($body);
94
95
        $this->sendRequest($method, $url, $this->getHeaders(), $body);
96
    }
97
98
    /**
99
     * Sends HTTP request to specific URL with raw body from PyString.
100
     *
101
     * @param string       $method request method
102
     * @param string       $url    relative url
103
     * @param PyStringNode $body   request body
104
     *
105
     * @throws ClientExceptionInterface
106
     *
107
     * @When /^(?:I )?send a ([A-Z]+) request to "([^"]+)" with body:$/
108
     */
109
    public function iSendARequestWithBody($method, $url, PyStringNode $body): void
110
    {
111
        $url = $this->prepareUrl($url);
112
        $body = $this->replacePlaceHolder(trim($body));
113
114
        $this->sendRequest($method, $url, $this->getHeaders(), $body);
115
    }
116
117
    /**
118
     * Sends HTTP request to specific URL with form data from PyString.
119
     *
120
     * @param string       $method request method
121
     * @param string       $url    relative url
122
     * @param PyStringNode $body   request body
123
     *
124
     * @throws ClientExceptionInterface
125
     *
126
     * @When /^(?:I )?send a ([A-Z]+) request to "([^"]+)" with form data:$/
127
     */
128
    public function iSendARequestWithFormData($method, $url, PyStringNode $body): void
129
    {
130
        $url = $this->prepareUrl($url);
131
        $body = $this->replacePlaceHolder(trim($body));
132
133
        $fields = [];
134
        parse_str(implode('&', explode("\n", $body)), $fields);
135
        $body = http_build_query($fields, null, '&');
136
137
        $this->addHeader('Content-Type', 'application/x-www-form-urlencoded');
138
139
        $this->sendRequest($method, $url, $this->getHeaders(), $body);
140
    }
141
142
    /**
143
     * Checks that response has specific status code.
144
     *
145
     * @param string $code status code
146
     *
147
     * @Then /^(?:the )?response code should be (\d+)$/
148
     */
149
    public function theResponseCodeShouldBe($code): void
150
    {
151
        $expected = intval($code);
152
        $statusCode = intval($this->getResponse()->getStatusCode());
153
154
        Assert::assertSame($expected, $statusCode);
155
    }
156
157
    /**
158
     * Checks that response body contains specific text.
159
     *
160
     * @param string $text
161
     *
162
     * @Then /^(?:the )?response should contain "([^"]*)"$/
163
     */
164 View Code Duplication
    public function theResponseShouldContain($text): void
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
165
    {
166
        $expectedRegexp = '/'.preg_quote($text).'/i';
167
        $bodyResponse = (string) $this->getResponse()->getBody();
168
169
        Assert::assertRegExp($expectedRegexp, $bodyResponse);
170
    }
171
172
    /**
173
     * Checks that response body doesn't contains specific text.
174
     *
175
     * @param string $text
176
     *
177
     * @Then /^(?:the )?response should not contain "([^"]*)"$/
178
     */
179 View Code Duplication
    public function theResponseShouldNotContain($text): void
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
180
    {
181
        $expectedRegexp = '/'.preg_quote($text).'/';
182
        $bodyResponse = (string) $this->getResponse()->getBody();
183
184
        Assert::assertNotRegExp($expectedRegexp, $bodyResponse);
185
    }
186
187
    /**
188
     * Checks that response body contains JSON from PyString.
189
     *
190
     * Do not check that the response body /only/ contains the JSON from PyString,
191
     *
192
     * @param PyStringNode $jsonString
193
     *
194
     * @throws \RuntimeException
195
     *
196
     * @Then /^(?:the )?response should contain json:$/
197
     */
198
    public function theResponseShouldContainJson(PyStringNode $jsonString): void
199
    {
200
        $rawJsonString = $this->replacePlaceHolder($jsonString->getRaw());
201
202
        $expected = json_decode($rawJsonString, true);
203
        $actual = json_decode((string) $this->getResponse()->getBody(), true);
204
205
        Assert::assertNotNull($expected, 'Can not convert expected to json:\n'.$rawJsonString);
206
        Assert::assertNotNull($actual, 'Can not convert body response to json:\n'.$this->getResponse()->getBody());
207
208
        Assert::assertGreaterThanOrEqual(count($expected), count($actual));
209
210
        foreach ($expected as $key => $needle) {
211
            Assert::assertArrayHasKey($key, $actual);
212
            Assert::assertEquals($expected[$key], $actual[$key]);
213
        }
214
    }
215
216
    /**
217
     * Check if the response header has a specific value.
218
     *
219
     * @param string $name
220
     * @param string $expected
221
     *
222
     * @Then /^the response "([^"]*)" header should be "([^"]*)"$/
223
     */
224
    public function theResponseHeaderShouldBe($name, $expected): void
225
    {
226
        $actual = $this->getResponse()->getHeaderLine($name);
227
        Assert::assertEquals($expected, $actual);
228
    }
229
230
    /**
231
     * Prints last response body.
232
     *
233
     * @Then print response
234
     */
235
    public function printResponse(): void
236
    {
237
        $request = '';
238
        if ($this->getRequest() instanceof RequestInterface) {
239
            $request = sprintf(
240
                '%s %s',
241
                $this->getRequest()->getMethod(),
242
                (string) $this->getRequest()->getUri()
243
            );
244
        }
245
246
        $response = sprintf(
247
            "%d:\n%s",
248
            $this->getResponse()->getStatusCode(),
249
            (string) $this->getResponse()->getBody()
250
        );
251
252
        echo sprintf('%s => %s', $request, $response);
253
    }
254
}
255