Completed
Push — master ( d40614...680e53 )
by Sébastien
10s
created

JsonContext::assert()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 8
rs 9.4285
c 0
b 0
f 0
nc 2
cc 2
eloc 5
nop 1
1
<?php
2
3
namespace Rezzza\RestApiBehatExtension\Json;
4
5
use mageekguy\atoum\asserter\generator as asserter;
6
use Behat\Behat\Context\Context;
7
use Behat\Behat\Context\SnippetAcceptingContext;
8
use Behat\Gherkin\Node\PyStringNode;
9
10
class JsonContext implements Context, SnippetAcceptingContext
0 ignored issues
show
Deprecated Code introduced by
The interface Behat\Behat\Context\SnippetAcceptingContext has been deprecated with message: will be removed in 4.0. Use --snippets-for CLI option instead

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the type will be removed from the class and what other constant to use instead.

Loading history...
11
{
12
    private $jsonInspector;
13
14
    private $asserter;
15
16
    private $jsonSchemaBaseUrl;
17
18
    public function __construct(JsonInspector $jsonInspector, $jsonSchemaBaseUrl = null)
19
    {
20
        $this->jsonInspector = $jsonInspector;
21
        $this->asserter = new asserter;
22
        $this->jsonSchemaBaseUrl = rtrim($jsonSchemaBaseUrl, '/');
23
    }
24
25
    /**
26
     * @When /^I load JSON:$/
27
     */
28
    public function iLoadJson(PyStringNode $jsonContent)
29
    {
30
        $this->jsonInspector->writeJson((string) $jsonContent);
31
    }
32
33
    /**
34
     * @Then /^the response should be in JSON$/
35
     */
36
    public function responseShouldBeInJson()
37
    {
38
        $this->jsonInspector->readJson();
39
    }
40
41
    /**
42
     * @Then /^the JSON node "(?P<jsonNode>[^"]*)" should be equal to "(?P<expectedValue>.*)"$/
43
     */
44
    public function theJsonNodeShouldBeEqualTo($jsonNode, $expectedValue)
45
    {
46
        $this->assert(function () use ($jsonNode, $expectedValue) {
47
            $realValue = $this->evaluateJsonNodeValue($jsonNode);
48
            $this->asserter->variable($realValue)->isEqualTo($expectedValue);
49
        });
50
    }
51
52
    /**
53
     * @Then /^the JSON node "(?P<jsonNode>[^"]*)" should have (?P<expectedNth>\d+) elements?$/
54
     * @Then /^the JSON array node "(?P<jsonNode>[^"]*)" should have (?P<expectedNth>\d+) elements?$/
55
     */
56
    public function theJsonNodeShouldHaveElements($jsonNode, $expectedNth)
57
    {
58
        $this->assert(function () use ($jsonNode, $expectedNth) {
59
            $realValue = $this->evaluateJsonNodeValue($jsonNode);
60
            $this->asserter->phpArray($realValue)->hasSize($expectedNth);
61
        });
62
    }
63
64
    /**
65
     * @Then /^the JSON array node "(?P<jsonNode>[^"]*)" should contain "(?P<expectedValue>.*)" element$/
66
     */
67 View Code Duplication
    public function theJsonArrayNodeShouldContainElements($jsonNode, $expectedValue)
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...
68
    {
69
        $this->assert(function () use ($jsonNode, $expectedValue) {
70
            $realValue = $this->evaluateJsonNodeValue($jsonNode);
71
            $this->asserter->phpArray($realValue)->contains($expectedValue);
72
        });
73
    }
74
75
    /**
76
     * @Then /^the JSON array node "(?P<jsonNode>[^"]*)" should not contain "(?P<expectedValue>.*)" element$/
77
     */
78
    public function theJsonArrayNodeShouldNotContainElements($jsonNode, $expectedValue)
79
    {
80
        $this->assert(function () use ($jsonNode, $expectedValue) {
81
            $realValue = $this->evaluateJsonNodeValue($jsonNode);
82
            $this->asserter->phpArray($realValue)->notContains($expectedValue);
83
        });
84
    }
85
86
    /**
87
     * @Then /^the JSON node "(?P<jsonNode>[^"]*)" should contain "(?P<expectedValue>.*)"$/
88
     */
89 View Code Duplication
    public function theJsonNodeShouldContain($jsonNode, $expectedValue)
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...
90
    {
91
        $this->assert(function () use ($jsonNode, $expectedValue) {
92
            $realValue = $this->evaluateJsonNodeValue($jsonNode);
93
            $this->asserter->string((string) $realValue)->contains($expectedValue);
94
        });
95
    }
96
97
    /**
98
     * Checks, that given JSON node does not contain given value
99
     *
100
     * @Then /^the JSON node "(?P<jsonNode>[^"]*)" should not contain "(?P<unexpectedValue>.*)"$/
101
     */
102 View Code Duplication
    public function theJsonNodeShouldNotContain($jsonNode, $unexpectedValue)
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...
103
    {
104
        $this->assert(function () use ($jsonNode, $unexpectedValue) {
105
            $realValue = $this->evaluateJsonNodeValue($jsonNode);
106
            $this->asserter->string((string) $realValue)->notContains($unexpectedValue);
107
        });
108
    }
109
110
    /**
111
     * Checks, that given JSON node exist
112
     *
113
     * @Given /^the JSON node "(?P<jsonNode>[^"]*)" should exist$/
114
     */
115
    public function theJsonNodeShouldExist($jsonNode)
116
    {
117
        try {
118
            $this->evaluateJsonNodeValue($jsonNode);
119
        } catch (\Exception $e) {
120
            throw new WrongJsonExpectation(sprintf("The node '%s' does not exist.", $jsonNode), $this->readJson(), $e);
121
        }
122
    }
123
124
    /**
125
     * Checks, that given JSON node does not exist
126
     *
127
     * @Given /^the JSON node "(?P<jsonNode>[^"]*)" should not exist$/
128
     */
129
    public function theJsonNodeShouldNotExist($jsonNode)
130
    {
131
        $e = null;
132
133
        try {
134
            $realValue = $this->evaluateJsonNodeValue($jsonNode);
135
        } catch (\Exception $e) {
136
            // If the node does not exist an exception should be throwed
137
        }
138
139
        if ($e === null) {
140
            throw new WrongJsonExpectation(
141
                sprintf("The node '%s' exists and contains '%s'.", $jsonNode, json_encode($realValue)),
142
                $this->readJson(),
143
                $e
144
            );
145
        }
146
    }
147
148
    /**
149
     * @Then /^the JSON should be valid according to this schema:$/
150
     */
151
    public function theJsonShouldBeValidAccordingToThisSchema(PyStringNode $jsonSchemaContent)
152
    {
153
        $tempFilename = tempnam(sys_get_temp_dir(), 'rae');
154
        file_put_contents($tempFilename, $jsonSchemaContent);
155
        $this->assert(function () use ($tempFilename) {
156
            $this->jsonInspector->validateJson(
157
                new JsonSchema($tempFilename)
158
            );
159
        });
160
        unlink($tempFilename);
161
    }
162
163
    /**
164
     * @Then /^the JSON should be valid according to the schema "(?P<filename>[^"]*)"$/
165
     */
166
    public function theJsonShouldBeValidAccordingToTheSchema($filename)
167
    {
168
        $filename = $this->resolveFilename($filename);
169
170
        $this->assert(function () use ($filename) {
171
            $this->jsonInspector->validateJson(
172
                new JsonSchema($filename)
173
            );
174
        });
175
    }
176
177
    /**
178
     * @Then /^the JSON should be equal to:$/
179
     */
180
    public function theJsonShouldBeEqualTo(PyStringNode $jsonContent)
181
    {
182
        $realJsonValue = $this->readJson();
183
184
        try {
185
            $expectedJsonValue = new Json($jsonContent);
186
        } catch (\Exception $e) {
187
            throw new \Exception('The expected JSON is not a valid');
188
        }
189
190
        $this->assert(function () use ($realJsonValue, $expectedJsonValue) {
191
            $this->asserter->castToString($realJsonValue)->isEqualTo((string) $expectedJsonValue);
192
        });
193
    }
194
195
    private function evaluateJsonNodeValue($jsonNode)
196
    {
197
        return $this->jsonInspector->readJsonNodeValue($jsonNode);
198
    }
199
200
    private function readJson()
201
    {
202
        return $this->jsonInspector->readJson();
203
    }
204
205
    private function resolveFilename($filename)
206
    {
207
        if (true === is_file($filename)) {
208
            return realpath($filename);
209
        }
210
211
        if (null === $this->jsonSchemaBaseUrl) {
212
            throw new \RuntimeException(sprintf(
213
                'The JSON schema file "%s" doesn\'t exist',
214
                $filename
215
            ));
216
        }
217
218
        $filename = $this->jsonSchemaBaseUrl . '/' . $filename;
219
220
        if (false === is_file($filename)) {
221
            throw new \RuntimeException(sprintf(
222
                'The JSON schema file "%s" doesn\'t exist',
223
                $filename
224
            ));
225
        }
226
227
        return realpath($filename);
228
    }
229
230
    private function assert(callable $assertion)
231
    {
232
        try {
233
            $assertion();
234
        } catch (\Exception $e) {
235
            throw new WrongJsonExpectation($e->getMessage(), $this->readJson(), $e);
236
        }
237
    }
238
}
239