Completed
Pull Request — master (#75)
by
unknown
01:19
created

WebApiContext::theResponseShouldNotContain()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7

Duplication

Lines 7
Ratio 100 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 1
dl 7
loc 7
rs 10
c 0
b 0
f 0
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 as PsrClientExceptionInterface;
18
use Psr\Http\Message\RequestInterface;
19
use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface as SymfonyClientExceptionInterface;
20
21
/**
22
 * Provides web API description definitions.
23
 *
24
 * @author Konstantin Kudryashov <[email protected]>
25
 * @author Keyclic team <[email protected]>
26
 */
27
class WebApiContext extends ApiClientContext implements ApiClientContextInterface
28
{
29
    /**
30
     * Adds Basic Authentication header to next request.
31
     *
32
     * @param string $username
33
     * @param string $password
34
     *
35
     * @Given /^I am basic authenticating as "([^"]*)" with "([^"]*)" password$/
36
     */
37
    public function iAmBasicAuthenticatingAs($username, $password): void
38
    {
39
        $authorization = base64_encode($username.':'.$password);
40
41
        $this->removeHeader('Authorization');
42
        $this->addHeader('Authorization', 'Basic '.$authorization);
43
    }
44
45
    /**
46
     * Sets a HTTP Header.
47
     *
48
     * @param string $name  header name
49
     * @param string $value header value
50
     *
51
     * @Given /^I set header "([^"]*)" with value "([^"]*)"$/
52
     */
53
    public function iSetHeaderWithValue($name, $value): void
54
    {
55
        $this->addHeader($name, $value);
56
    }
57
58
    /**
59
     * Sends HTTP request to specific relative URL.
60
     *
61
     * @param string $method request method
62
     * @param string $url    relative url
63
     *
64
     * @throws PsrClientExceptionInterface
65
     * @throws SymfonyClientExceptionInterface
66
     *
67
     * @When /^(?:I )?send a ([A-Z]+) request to "([^"]+)"$/
68
     */
69
    public function iSendARequest($method, $url): void
70
    {
71
        $url = $this->prepareUrl($url);
72
73
        $this->sendRequest($method, $url, $this->getHeaders());
74
    }
75
76
    /**
77
     * Sends HTTP request to specific URL with field values from Table.
78
     *
79
     * @param string    $method request method
80
     * @param string    $url    relative url
81
     * @param TableNode $values table of post values
82
     *
83
     * @throws PsrClientExceptionInterface
84
     * @throws SymfonyClientExceptionInterface
85
     *
86
     * @When /^(?:I )?send a ([A-Z]+) request to "([^"]+)" with values:$/
87
     */
88
    public function iSendARequestWithValues($method, $url, TableNode $values): void
89
    {
90
        $url = $this->prepareUrl($url);
91
92
        $body = array_map(function ($value) {
93
            return $this->replacePlaceHolder($value);
94
        }, $values->getRowsHash());
95
96
        $body = json_encode($body);
97
98
        $this->sendRequest($method, $url, $this->getHeaders(), $body);
99
    }
100
101
    /**
102
     * Sends HTTP request to specific URL with raw body from PyString.
103
     *
104
     * @param string       $method request method
105
     * @param string       $url    relative url
106
     * @param PyStringNode $body   request body
107
     *
108
     * @throws PsrClientExceptionInterface
109
     * @throws SymfonyClientExceptionInterface
110
     *
111
     * @When /^(?:I )?send a ([A-Z]+) request to "([^"]+)" with body:$/
112
     */
113
    public function iSendARequestWithBody($method, $url, PyStringNode $body): void
114
    {
115
        $url = $this->prepareUrl($url);
116
        $body = $this->replacePlaceHolder(trim($body));
117
118
        $this->sendRequest($method, $url, $this->getHeaders(), $body);
119
    }
120
121
    /**
122
     * Sends HTTP request to specific URL with form data from PyString.
123
     *
124
     * @param string       $method request method
125
     * @param string       $url    relative url
126
     * @param PyStringNode $body   request body
127
     *
128
     * @throws PsrClientExceptionInterface
129
     * @throws SymfonyClientExceptionInterface
130
     *
131
     * @When /^(?:I )?send a ([A-Z]+) request to "([^"]+)" with form data:$/
132
     */
133
    public function iSendARequestWithFormData($method, $url, PyStringNode $body): void
134
    {
135
        $url = $this->prepareUrl($url);
136
        $body = $this->replacePlaceHolder(trim($body));
137
138
        $fields = [];
139
        parse_str(implode('&', explode("\n", $body)), $fields);
140
        $body = http_build_query($fields, null, '&');
141
142
        $this->addHeader('Content-Type', 'application/x-www-form-urlencoded');
143
144
        $this->sendRequest($method, $url, $this->getHeaders(), $body);
145
    }
146
147
    /**
148
     * Checks that response has specific status code.
149
     *
150
     * @param string $code status code
151
     *
152
     * @Then /^(?:the )?response code should be (\d+)$/
153
     */
154
    public function theResponseCodeShouldBe($code): void
155
    {
156
        $expected = intval($code);
157
        $statusCode = intval($this->getResponse()->getStatusCode());
158
159
        Assert::assertSame($expected, $statusCode);
160
    }
161
162
    /**
163
     * Checks that response body contains specific text.
164
     *
165
     * @param string $text
166
     *
167
     * @Then /^(?:the )?response should contain "([^"]*)"$/
168
     */
169 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...
170
    {
171
        $expectedRegexp = '/'.preg_quote($text).'/i';
172
        $bodyResponse = (string) $this->getResponse()->getBody();
173
174
        Assert::assertRegExp($expectedRegexp, $bodyResponse);
175
    }
176
177
    /**
178
     * Checks that response body doesn't contains specific text.
179
     *
180
     * @param string $text
181
     *
182
     * @Then /^(?:the )?response should not contain "([^"]*)"$/
183
     */
184 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...
185
    {
186
        $expectedRegexp = '/'.preg_quote($text).'/';
187
        $bodyResponse = (string) $this->getResponse()->getBody();
188
189
        Assert::assertNotRegExp($expectedRegexp, $bodyResponse);
190
    }
191
192
    /**
193
     * Checks that response body contains JSON from PyString.
194
     *
195
     * Do not check that the response body /only/ contains the JSON from PyString,
196
     *
197
     * @param PyStringNode $jsonString
198
     *
199
     * @throws \RuntimeException
200
     *
201
     * @Then /^(?:the )?response should contain json:$/
202
     */
203
    public function theResponseShouldContainJson(PyStringNode $jsonString): void
204
    {
205
        $rawJsonString = $this->replacePlaceHolder($jsonString->getRaw());
206
207
        $expected = json_decode($rawJsonString, true);
208
        $actual = json_decode((string) $this->getResponse()->getBody(), true);
209
210
        Assert::assertNotNull($expected, 'Can not convert expected to json:\n'.$rawJsonString);
211
        Assert::assertNotNull($actual, 'Can not convert body response to json:\n'.$this->getResponse()->getBody());
212
213
        Assert::assertGreaterThanOrEqual(count($expected), count($actual));
214
215
        foreach ($expected as $key => $needle) {
216
            Assert::assertArrayHasKey($key, $actual);
217
            Assert::assertEquals($expected[$key], $actual[$key]);
218
        }
219
    }
220
221
    /**
222
     * Check if the response header has a specific value.
223
     *
224
     * @param string $name
225
     * @param string $expected
226
     *
227
     * @Then /^the response "([^"]*)" header should be "([^"]*)"$/
228
     */
229
    public function theResponseHeaderShouldBe($name, $expected): void
230
    {
231
        $actual = $this->getResponse()->getHeaderLine($name);
232
        Assert::assertEquals($expected, $actual);
233
    }
234
235
    /**
236
     * Prints last response body.
237
     *
238
     * @Then print response
239
     */
240
    public function printResponse(): void
241
    {
242
        $request = '';
243
        if ($this->getRequest() instanceof RequestInterface) {
244
            $request = sprintf(
245
                '%s %s',
246
                $this->getRequest()->getMethod(),
247
                (string) $this->getRequest()->getUri()
248
            );
249
        }
250
251
        $response = sprintf(
252
            "%d:\n%s",
253
            $this->getResponse()->getStatusCode(),
254
            (string) $this->getResponse()->getContent(false)
0 ignored issues
show
Bug introduced by
The method getContent() does not seem to exist on object<Psr\Http\Message\ResponseInterface>.

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...
255
        );
256
257
        echo sprintf('%s => %s', $request, $response);
258
    }
259
}
260