ApiContext::getApiResponse()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 0
cts 4
cp 0
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 0
crap 2
1
<?php
2
3
namespace TreeHouse\BaseApiBundle\Behat;
4
5
use Behat\Gherkin\Node\PyStringNode;
6
use Behat\Gherkin\Node\TableNode;
7
use PHPUnit_Framework_Assert as Assert;
8
9
class ApiContext extends BaseFeatureContext
10
{
11
    /**
12
     * @var string
13
     */
14
    protected static $authToken;
15
16
    /**
17
     * @var string
18
     */
19
    protected static $userToken;
20
21
    /**
22
     * @BeforeScenario
23
     */
24
    public function onBefore()
25
    {
26
        static::$authToken = null;
27
        static::$userToken = null;
28
        static::$response = null;
29
    }
30
31
    /**
32
     * @When I get/GET to :path
33
     */
34
    public function iGetTo($path)
35
    {
36
        $this->request('GET', $path);
37
    }
38
39
    /**
40
     * @When I request the api with :method :path
41
     */
42
    public function iRequestTheApi($method, $path)
43
    {
44
        $this->request($method, $path);
45
    }
46
47
    /**
48
     * @When I head/HEAD to :path
49
     */
50
    public function iHeadTo($path)
51
    {
52
        $this->request('HEAD', $path);
53
    }
54
55
    /**
56
     * @When I post/POST to :path with:
57
     */
58
    public function iPostToWith($path, PyStringNode $string)
59
    {
60
        $this->request('POST', $path, trim($string));
61
    }
62
63
    /**
64
     * @When I put/PUT to :path with:
65
     */
66
    public function iPutToWith($path, PyStringNode $string)
67
    {
68
        $this->request('PUT', $path, trim($string));
69
    }
70
71
    /**
72
     * @When I delete/DELETE to :path
73
     */
74
    public function iDeleteTo($path)
75
    {
76
        $this->request('DELETE', $path);
77
    }
78
79
    /**
80
     * @Then the response should not contain :content
81
     */
82
    public function theResponseShouldNotContain($content)
83
    {
84
        Assert::assertNotContains($content, $this->getResponseContent());
85
    }
86
87
    /**
88
     * @Then the response status code should be :code
89
     */
90
    public function theResponseStatusCodeShouldBe($code)
91
    {
92
        Assert::assertEquals($code, static::$response->getStatusCode());
93
    }
94
95
    /**
96
     * @Then the response header :header should contain :value
97
     * @Then the response header :header contains :value
98
     */
99
    public function theResponseHeaderContains($header, $value)
100
    {
101
        if (false === static::$response->headers->has($header)) {
102
            throw new \Exception(
103
                sprintf('Request does not contain %d header', $header)
104
            );
105
        }
106
107
        Assert::assertContains($value, (string) static::$response->headers->get($header));
108
    }
109
110
    /**
111
     * @Then the response should contain :arg1
112
     * @Then the response contains :arg1
113
     */
114
    public function theResponseShouldContain($arg1)
115
    {
116
        Assert::assertContains($arg1, $this->getResponseContent());
117
    }
118
119
    /**
120
     * @Then the response should be xml/XML
121
     * @Then the response is xml/XML
122
     */
123
    public function theResponseIsXml()
124
    {
125
        $this->theResponseHeaderContains('Content-type', 'application/xml');
126
127
        if (false === simplexml_load_string($this->getResponseContent())) {
128
            throw new \Exception(
129
                sprintf(
130
                    'The response is not valid XML. This was the body: "%s"',
131
                    $this->getResponseContent()
132
                )
133
            );
134
        }
135
    }
136
137
    /**
138
     * @Then the response should be json/JSON
139
     * @Then the response is json/JSON
140
     */
141
    public function theResponseIsJson()
142
    {
143
        Assert::assertThat(
144
            static::$response->headers->get('Content-Type'),
145
            Assert::logicalOr(
146
                Assert::stringStartsWith('application/json'),
147
                Assert::stringStartsWith('text/javascript')
148
            )
149
        );
150
151
        Assert::assertJson($this->getResponseContent());
152
    }
153
154
    /**
155
     * @Then the response should contain the following json/JSON:
156
     * @Then the response contains the following json/JSON:
157
     */
158
    public function theResponseShouldContainJson($jsonData)
159
    {
160
        $json     = $this->getJsonData($jsonData);
161
        $response = $this->getJsonData($this->getResponseContent());
162
163
        Assert::assertEquals($json, $response);
164
    }
165
166
    /**
167
     * @Then the response should contain the following jsonp/JSONP:
168
     * @Then the response contains the following jsonp/JSONP:
169
     */
170
    public function theResponseShouldContainJsonp(PyStringNode $jsonData)
171
    {
172
        $json  = preg_replace('~\s~', '', $jsonData->getRaw());
173
        $jsonp = preg_replace(['~/\*\*/~', '~\s~'], '', $this->getResponseContent());
174
175
        Assert::assertEquals($json, $jsonp);
176
    }
177
178
    /**
179
     * @Given I have a valid token
180
     */
181
    public function iHaveAValidToken()
182
    {
183
        $this->iHaveAValidTokenForUsernameAndPassword('admin', '1234');
184
    }
185
186
    /**
187
     * @Given I have a valid token for :user with password :pass
188
     * @Given I have a valid token for username :user and password :pass
189
     */
190
    public function iHaveAValidTokenForUsernameAndPassword($user, $pass)
191
    {
192
        $server = [
193
            'HTTP_HOST' => $this->getContainer()->getParameter('tree_house.api.token_host')
194
        ];
195
196
        $data = [
197
            'auth' => [
198
                'passwordCredentials' => [
199
                    'username' => $user,
200
                    'password' => $pass,
201
                ]
202
            ]
203
        ];
204
205
        $response = parent::request('POST', '/tokens', json_encode($data), [], $server);
0 ignored issues
show
Comprehensibility Bug introduced by
It seems like you call parent on a different method (request() instead of iHaveAValidTokenForUsernameAndPassword()). Are you sure this is correct? If so, you might want to change this to $this->request().

This check looks for a call to a parent method whose name is different than the method from which it is called.

Consider the following code:

class Daddy
{
    protected function getFirstName()
    {
        return "Eidur";
    }

    protected function getSurName()
    {
        return "Gudjohnsen";
    }
}

class Son
{
    public function getFirstName()
    {
        return parent::getSurname();
    }
}

The getFirstName() method in the Son calls the wrong method in the parent class.

Loading history...
206
        $result   = json_decode($response->getContent(), true);
207
208
        static::$authToken = $result['access']['token']['id'];
209
    }
210
211
    /**
212
     * @Given I have a valid user token
213
     */
214
    public function iHaveAValidUserToken()
215
    {
216
        $this->iHaveAValidUserTokenForUsernameAndPassword('admin', '1234');
217
    }
218
219
    /** @Given I have a valid user token for username :user and password :pass
220
     */
221
    public function iHaveAValidUserTokenForUsernameAndPassword($user, $pass)
222
    {
223
        $data = [
224
            'username' => $user,
225
            'password' => $pass,
226
        ];
227
228
        $response = $this->request('POST', '/login/', json_encode($data));
229
        $result = json_decode($response->getContent(), true);
230
231
        static::$userToken = $result['result']['token'];
232
    }
233
234
    /**
235
     * @Then the api/API result should be ok
236
     */
237
    public function theResultShouldBeOk()
238
    {
239
        $this->theResponseIsJson();
240
241
        $response = $this->getApiResponse();
242
        Assert::assertArrayHasKey('ok', $response);
243
        Assert::assertTrue($response['ok']);
244
    }
245
246
    /**
247
     * @Then the api/API result should be not ok
248
     */
249
    public function theResultShouldBeNotOk()
250
    {
251
        $this->theResponseIsJson();
252
253
        $response = $this->getApiResponse();
254
        Assert::assertArrayHasKey('ok', $response);
255
        Assert::assertFalse($response['ok']);
256
    }
257
258
    /**
259
     * @Then the api/API result should contain :count item(s)
260
     * @Then the api/API result contains :count item(s)
261
     */
262
    public function theResultContainsExactlyItems($count)
263
    {
264
        $result = $this->getApiResult();
265
266
        Assert::assertContainsOnly('array', $result);
267
        Assert::assertEquals($count, count($result));
268
    }
269
270
    /**
271
     * @Then the api/API result should contain at least :count item(s)
272
     * @Then the api/API result contains at least :count item(s)
273
     */
274
    public function theResultContainsAtLeastItems($count)
275
    {
276
        $result = $this->getApiResult();
277
278
        Assert::assertContainsOnly('array', $result);
279
        Assert::assertGreaterThanOrEqual($count, count($result));
280
    }
281
282
    /**
283
     * @Then the api/API result should contain key :key
284
     */
285
    public function theResultShouldContainKey($key)
286
    {
287
        $result = $this->getApiResult();
288
        Assert::assertArrayHasKey($key, $result);
289
    }
290
291
    /**
292
     * @Then the api/API result key :key should not equal null
293
     */
294
    public function theResultKeyShouldNotEqualNull($key)
295
    {
296
        $result = $this->getApiResult();
297
        Assert::assertArrayHasKey($key, $result);
298
        Assert::assertNotNull($result[$key]);
299
    }
300
301
    /**
302
     * @Then the api/API result key :key should equal :value
303
     */
304
    public function theResultKeyShouldEqual($key, $value)
305
    {
306
        $result = $this->getApiResult();
307
        Assert::assertArrayHasKey($key, $result);
308
        Assert::assertEquals($value, $result[$key]);
309
    }
310
311
    /**
312
     * @Then the api/API result key :key should equal:
313
     */
314
    public function theResultKeyShouldEqualNode($key, $node)
315
    {
316
        $json = $this->getJsonData($node);
317
318
        $result = $this->getApiResult();
319
        Assert::assertArrayHasKey($key, $result);
320
        Assert::assertEquals($json, $result[$key]);
321
    }
322
323
    /**
324
     * @Then the api/API error should contain :text
325
     */
326
    public function theApiErrorShouldContain($text)
327
    {
328
        $error = $this->getApiError();
329
        Assert::assertContains($text, $error);
330
    }
331
332
    /**
333
     * @Then the api/API error should be:
334
     */
335
    public function theApiErrorShouldEqual(PyStringNode $node)
336
    {
337
        $error = $this->getApiError();
338
        Assert::assertEquals($node->getRaw(), trim($error));
339
    }
340
341
    /**
342
     * @Then the api/API result should contain a key with:
343
     */
344
    public function theResultShouldContainNode($node)
345
    {
346
        $json = $this->getJsonData($node);
347
348
        $result = $this->getApiResult();
349
        foreach ($result as $value) {
350
            if ($value == $json) {
351
                return;
352
            }
353
        }
354
355
        Assert::fail(sprintf('No result was found containing: %s', json_encode($json, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT)));
356
    }
357
358
    /**
359
     * @param string|PyStringNode|TableNode $data
360
     *
361
     * @throws \InvalidArgumentException
362
     *
363
     * @return array
364
     */
365
    protected function getJsonData($data)
366
    {
367
        $json = null;
368
369
        if ($data instanceof PyStringNode) {
370
            $json = json_decode($data->getRaw(), true);
371
        }
372
373
        if ($data instanceof TableNode) {
374
            $json = $data->getRowsHash();
375
        }
376
377
        if (is_string($data)) {
378
            $json = json_decode($data, true);
379
        }
380
381
        if (null === $json) {
382
            throw new \InvalidArgumentException(sprintf(
383
                'Invalid json data class ("%s")',
384
                get_class($data)
385
            ));
386
        }
387
388
        return $json;
389
    }
390
391
    /**
392
     * @inheritdoc
393
     */
394
    protected function request($method, $uri, $data = null, array $headers = [], array $server = [])
395
    {
396
        if (!array_key_exists('HTTP_HOST', $server)) {
397
            $server['HTTP_HOST'] = $this->getContainer()->getParameter('tree_house.api.host');
398
        }
399
400
        if (null !== static::$authToken) {
401
            $headers['X-Auth-Token'] = static::$authToken;
402
        }
403
404
        if (null !== static::$userToken) {
405
            $headers['X-User-Token'] = static::$userToken;
406
        }
407
408
        return parent::request($method, $uri, $data, $headers, $server);
409
    }
410
411
    /**
412
     * Returns the complete response from the last api call, decoded to an array.
413
     *
414
     * @return array
415
     */
416
    protected function getApiResponse()
417
    {
418
        return json_decode($this->getResponseContent(), true);
419
    }
420
421
    /**
422
     * Returns the "result" key of the last api response, json decoded.
423
     *
424
     * @return mixed
425
     */
426
    protected function getApiResult()
427
    {
428
        $response = $this->getApiResponse();
429
430
        Assert::assertArrayHasKey('result', $response);
431
432
        return $response['result'];
433
    }
434
435
    /**
436
     * Returns the "error" key of the last api response.
437
     *
438
     * @return mixed
439
     */
440
    protected function getApiError()
441
    {
442
        $response = $this->getApiResponse();
443
444
        Assert::assertArrayHasKey('error', $response);
445
446
        return $response['error'];
447
    }
448
}
449