Passed
Push — master ( 96dec0...c2a174 )
by San
02:27
created

theJsonShouldBeInvalidAccordingToThisSchema()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 16
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 16
rs 9.4285
c 0
b 0
f 0
cc 3
eloc 9
nc 4
nop 1
1
<?php
2
3
namespace Behatch\Context;
4
5
use Behat\Gherkin\Node\PyStringNode;
6
7
use Behat\Gherkin\Node\TableNode;
8
use Behat\Mink\Exception\ExpectationException;
9
use Behatch\Json\Json;
10
use Behatch\Json\JsonSchema;
11
use Behatch\Json\JsonInspector;
12
use Behatch\HttpCall\HttpCallResultPool;
13
14
class JsonContext extends BaseContext
15
{
16
    protected $inspector;
17
18
    protected $httpCallResultPool;
19
20
    public function __construct(HttpCallResultPool $httpCallResultPool, $evaluationMode = 'javascript')
21
    {
22
        $this->inspector = new JsonInspector($evaluationMode);
23
        $this->httpCallResultPool = $httpCallResultPool;
24
    }
25
26
    /**
27
     * Checks, that the response is correct JSON
28
     *
29
     * @Then the response should be in JSON
30
     */
31
    public function theResponseShouldBeInJson()
32
    {
33
        $this->getJson();
34
    }
35
36
    /**
37
     * Checks, that the response is not correct JSON
38
     *
39
     * @Then the response should not be in JSON
40
     */
41
    public function theResponseShouldNotBeInJson()
42
    {
43
        $this->not(
44
            [$this, 'theResponseShouldBeInJson'],
45
            'The response is in JSON'
46
        );
47
    }
48
49
    /**
50
     * Checks, that given JSON node is equal to given value
51
     *
52
     * @Then the JSON node :node should be equal to :text
53
     */
54 View Code Duplication
    public function theJsonNodeShouldBeEqualTo($node, $text)
55
    {
56
        $json = $this->getJson();
57
58
        $actual = $this->inspector->evaluate($json, $node);
59
60
        if ($actual != $text) {
61
            throw new \Exception(
62
                sprintf("The node value is '%s'", json_encode($actual))
63
            );
64
        }
65
    }
66
67
    /**
68
     * Checks, that given JSON nodes are equal to givens values
69
     *
70
     * @Then the JSON nodes should be equal to:
71
     */
72
    public function theJsonNodesShouldBeEqualTo(TableNode $nodes)
73
    {
74
        foreach ($nodes->getRowsHash() as $node => $text) {
75
            $this->theJsonNodeShouldBeEqualTo($node, $text);
76
        }
77
    }
78
79
    public function theJsonNodesShoudBeEqualTo(TableNode $nodes)
80
    {
81
        trigger_error(
82
            sprintf('The %s function is deprecated since version 2.7 and will be removed in 3.0. Use the %s::theJsonNodesShouldBeEqualTo function instead.', __METHOD__, __CLASS__),
83
            E_USER_DEPRECATED
84
        );
85
        return $this->theJsonNodesShouldBeEqualTo($nodes);
86
    }
87
88
    /**
89
     * Checks, that given JSON node is null
90
     *
91
     * @Then the JSON node :node should be null
92
     */
93
    public function theJsonNodeShouldBeNull($node)
94
    {
95
        $json = $this->getJson();
96
97
        $actual = $this->inspector->evaluate($json, $node);
98
99
        if (null !== $actual) {
100
            throw new \Exception(
101
                sprintf('The node value is `%s`', json_encode($actual))
102
            );
103
        }
104
    }
105
106
    /**
107
     * Checks, that given JSON node is not null.
108
     *
109
     * @Then the JSON node :node should not be null
110
     */
111
    public function theJsonNodeShouldNotBeNull($name)
112
    {
113
        $this->not(function () use ($name) {
114
            return $this->theJsonNodeShouldBeNull($name);
115
        }, sprintf('The node %s should not be null', $name));
116
    }
117
118
    /**
119
     * Checks, that given JSON node is true
120
     *
121
     * @Then the JSON node :node should be true
122
     */
123
    public function theJsonNodeShouldBeTrue($node)
124
    {
125
        $json = $this->getJson();
126
127
        $actual = $this->inspector->evaluate($json, $node);
128
129
        if (true !== $actual) {
130
            throw new \Exception(
131
                sprintf('The node value is `%s`', json_encode($actual))
132
            );
133
        }
134
    }
135
136
    /**
137
     * Checks, that given JSON node is false
138
     *
139
     * @Then the JSON node :node should be false
140
     */
141
    public function theJsonNodeShouldBeFalse($node)
142
    {
143
        $json = $this->getJson();
144
145
        $actual = $this->inspector->evaluate($json, $node);
146
147
        if (false !== $actual) {
148
            throw new \Exception(
149
                sprintf('The node value is `%s`', json_encode($actual))
150
            );
151
        }
152
    }
153
154
    /**
155
     * Checks, that given JSON node is equal to the given string
156
     *
157
     * @Then the JSON node :node should be equal to the string :text
158
     */
159 View Code Duplication
    public function theJsonNodeShouldBeEqualToTheString($node, $text)
160
    {
161
        $json = $this->getJson();
162
163
        $actual = $this->inspector->evaluate($json, $node);
164
165
        if ($actual !== $text) {
166
            throw new \Exception(
167
                sprintf('The node value is `%s`', json_encode($actual))
168
            );
169
        }
170
    }
171
172
    /**
173
     * Checks, that given JSON node is equal to the given number
174
     *
175
     * @Then the JSON node :node should be equal to the number :number
176
     */
177 View Code Duplication
    public function theJsonNodeShouldBeEqualToTheNumber($node, $number)
178
    {
179
        $json = $this->getJson();
180
181
        $actual = $this->inspector->evaluate($json, $node);
182
183
        if ($actual !== (float) $number && $actual !== (int) $number) {
184
            throw new \Exception(
185
                sprintf('The node value is `%s`', json_encode($actual))
186
            );
187
        }
188
    }
189
190
    /**
191
     * Checks, that given JSON node has N element(s)
192
     *
193
     * @Then the JSON node :node should have :count element(s)
194
     */
195
    public function theJsonNodeShouldHaveElements($node, $count)
196
    {
197
        $json = $this->getJson();
198
199
        $actual = $this->inspector->evaluate($json, $node);
200
201
        $this->assertSame($count, sizeof((array) $actual));
202
    }
203
204
    /**
205
     * Checks, that given JSON node contains given value
206
     *
207
     * @Then the JSON node :node should contain :text
208
     */
209 View Code Duplication
    public function theJsonNodeShouldContain($node, $text)
210
    {
211
        $json = $this->getJson();
212
213
        $actual = $this->inspector->evaluate($json, $node);
214
215
        $this->assertContains($text, (string) $actual);
216
    }
217
218
    /**
219
     * Checks, that given JSON nodes contains values
220
     *
221
     * @Then the JSON nodes should contain:
222
     */
223
    public function theJsonNodesShouldContain(TableNode $nodes)
224
    {
225
        foreach ($nodes->getRowsHash() as $node => $text) {
226
            $this->theJsonNodeShouldContain($node, $text);
227
        }
228
    }
229
230
    public function theJsonNodesShoudContain(TableNode $nodes)
231
    {
232
        trigger_error(
233
            sprintf('The %s function is deprecated since version 2.7 and will be removed in 3.0. Use the %s::theJsonNodesShouldContain function instead.', __METHOD__, __CLASS__),
234
            E_USER_DEPRECATED
235
        );
236
        return $this->theJsonNodesShouldBeEqualTo($nodes);
237
    }
238
239
    /**
240
     * Checks, that given JSON node does not contain given value
241
     *
242
     * @Then the JSON node :node should not contain :text
243
     */
244 View Code Duplication
    public function theJsonNodeShouldNotContain($node, $text)
245
    {
246
        $json = $this->getJson();
247
248
        $actual = $this->inspector->evaluate($json, $node);
249
250
        $this->assertNotContains($text, (string) $actual);
251
    }
252
253
    /**
254
     * Checks, that given JSON nodes does not contain given value
255
     *
256
     * @Then the JSON nodes should not contain:
257
     */
258
    public function theJsonNodesShouldNotContain(TableNode $nodes)
259
    {
260
        foreach ($nodes->getRowsHash() as $node => $text) {
261
            $this->theJsonNodeShouldNotContain($node, $text);
262
        }
263
    }
264
265
    public function theJsonNodesShoudNotContain(TableNode $nodes)
266
    {
267
        trigger_error(
268
            sprintf('The %s function is deprecated since version 2.7 and will be removed in 3.0. Use the %s::theJsonNodesShouldNotContain function instead.', __METHOD__, __CLASS__),
269
            E_USER_DEPRECATED
270
        );
271
        return $this->theJsonNodesShouldBeEqualTo($nodes);
272
    }
273
274
    /**
275
     * Checks, that given JSON node exist
276
     *
277
     * @Given the JSON node :name should exist
278
     */
279
    public function theJsonNodeShouldExist($name)
280
    {
281
        $json = $this->getJson();
282
283
        try {
284
            $node = $this->inspector->evaluate($json, $name);
285
        }
286
        catch (\Exception $e) {
287
            throw new \Exception("The node '$name' does not exist.");
288
        }
289
        return $node;
290
    }
291
292
    /**
293
     * Checks, that given JSON node does not exist
294
     *
295
     * @Given the JSON node :name should not exist
296
     */
297
    public function theJsonNodeShouldNotExist($name)
298
    {
299
        $this->not(function () use($name) {
300
            return $this->theJsonNodeShouldExist($name);
301
        }, "The node '$name' exists.");
302
    }
303
304
    /**
305
     * @Then the JSON should be valid according to this schema:
306
     */
307
    public function theJsonShouldBeValidAccordingToThisSchema(PyStringNode $schema)
308
    {
309
        $this->inspector->validate(
310
            $this->getJson(),
311
            new JsonSchema($schema)
312
        );
313
    }
314
315
    /**
316
     * @Then the JSON should be invalid according to this schema:
317
     */
318
    public function theJsonShouldBeInvalidAccordingToThisSchema(PyStringNode $schema)
319
    {
320
        try {
321
            $isValid = $this->inspector->validate(
322
                $this->getJson(),
323
                new JsonSchema($schema)
324
            );
325
326
        } catch (\Exception $e) {
327
            $isValid = false;
328
        }
329
330
        if (true === $isValid) {
331
            throw new ExpectationException('Expected to receive invalid json, got valid one', $this->getSession());
332
        }
333
    }
334
335
    /**
336
     * @Then the JSON should be valid according to the schema :filename
337
     */
338
    public function theJsonShouldBeValidAccordingToTheSchema($filename)
339
    {
340
        $this->checkSchemaFile($filename);
341
342
        $this->inspector->validate(
343
            $this->getJson(),
344
            new JsonSchema(
345
                file_get_contents($filename),
346
                'file://' . realpath($filename)
347
            )
348
        );
349
    }
350
351
    /**
352
     * @Then the JSON should be invalid according to the schema :filename
353
     */
354
    public function theJsonShouldBeInvalidAccordingToTheSchema($filename)
355
    {
356
        $this->checkSchemaFile($filename);
357
358
        $this->not(function () use($filename) {
359
            return $this->theJsonShouldBeValidAccordingToTheSchema($filename);
360
        }, "The schema was valid");
361
    }
362
363
    /**
364
     * @Then the JSON should be equal to:
365
     */
366
    public function theJsonShouldBeEqualTo(PyStringNode $content)
367
    {
368
        $actual = $this->getJson();
369
370
        try {
371
            $expected = new Json($content);
372
        }
373
        catch (\Exception $e) {
374
            throw new \Exception('The expected JSON is not a valid');
375
        }
376
377
        $this->assertSame(
378
            (string) $expected,
379
            (string) $actual,
380
            "The json is equal to:\n". $actual->encode()
381
        );
382
    }
383
384
    /**
385
     * @Then print last JSON response
386
     */
387
    public function printLastJsonResponse()
388
    {
389
        echo $this->getJson()
390
            ->encode();
391
    }
392
393
    protected function getJson()
394
    {
395
        return new Json($this->httpCallResultPool->getResult()->getValue());
396
    }
397
398
    private function checkSchemaFile($filename)
399
    {
400
        if (false === is_file($filename)) {
401
            throw new \RuntimeException(
402
                'The JSON schema doesn\'t exist'
403
            );
404
        }
405
    }
406
}
407