Completed
Push — master ( 7565cc...eb9cdf )
by Timothée
12s
created

JsonContext::theJsonNodeShouldNotExist()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 18
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 18
rs 9.4285
c 0
b 0
f 0
nc 4
cc 3
eloc 10
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
    /**
196
     * @Then the JSON path expression :pathExpression should be equal to:
197
     */
198
    public function theJsonExpressionShouldBeEqualTo($pathExpression, PyStringNode $expectedJson)
199
    {
200
        $actualJson = Json::fromRawContent($this->jsonInspector->searchJsonPath($pathExpression));
201
202
        $this->asserter->castToString($actualJson)->isEqualTo((string) $expectedJson);
203
    }
204
205
    private function evaluateJsonNodeValue($jsonNode)
206
    {
207
        return $this->jsonInspector->readJsonNodeValue($jsonNode);
208
    }
209
210
    private function readJson()
211
    {
212
        return $this->jsonInspector->readJson();
213
    }
214
215
    private function resolveFilename($filename)
216
    {
217
        if (true === is_file($filename)) {
218
            return realpath($filename);
219
        }
220
221
        if (null === $this->jsonSchemaBaseUrl) {
222
            throw new \RuntimeException(sprintf(
223
                'The JSON schema file "%s" doesn\'t exist',
224
                $filename
225
            ));
226
        }
227
228
        $filename = $this->jsonSchemaBaseUrl . '/' . $filename;
229
230
        if (false === is_file($filename)) {
231
            throw new \RuntimeException(sprintf(
232
                'The JSON schema file "%s" doesn\'t exist',
233
                $filename
234
            ));
235
        }
236
237
        return realpath($filename);
238
    }
239
240
    private function assert(callable $assertion)
241
    {
242
        try {
243
            $assertion();
244
        } catch (\Exception $e) {
245
            throw new WrongJsonExpectation($e->getMessage(), $this->readJson(), $e);
246
        }
247
    }
248
}
249