Completed
Push — master ( eb9cdf...a7ed36 )
by Timothée
10s
created

theJsonPathExpressionShouldBeEqualToJson()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

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