Passed
Pull Request — master (#259)
by
unknown
09:50
created

theJsonNodeShouldHaveMoreThanElements()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8

Duplication

Lines 8
Ratio 100 %

Importance

Changes 0
Metric Value
dl 8
loc 8
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 2
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
    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
    /**
80
     * Checks, that given JSON node matches given pattern
81
     *
82
     * @Then the JSON node :node should match :pattern
83
     */
84
    public function theJsonNodeShouldMatch($node, $pattern)
85
    {
86
        $json = $this->getJson();
87
88
        $actual = $this->inspector->evaluate($json, $node);
89
90
        if (preg_match($pattern, $actual) === 0) {
91
            throw new \Exception(
92
                sprintf("The node value is '%s'", json_encode($actual))
93
            );
94
        }
95
    }
96
97
    /**
98
     * Checks, that given JSON node is null
99
     *
100
     * @Then the JSON node :node should be null
101
     */
102
    public function theJsonNodeShouldBeNull($node)
103
    {
104
        $json = $this->getJson();
105
106
        $actual = $this->inspector->evaluate($json, $node);
107
108
        if (null !== $actual) {
109
            throw new \Exception(
110
                sprintf('The node value is `%s`', json_encode($actual))
111
            );
112
        }
113
    }
114
115
    /**
116
     * Checks, that given JSON node is not null.
117
     *
118
     * @Then the JSON node :node should not be null
119
     */
120
    public function theJsonNodeShouldNotBeNull($node)
121
    {
122
        $this->not(function () use ($node) {
123
            return $this->theJsonNodeShouldBeNull($node);
124
        }, sprintf('The node %s should not be null', $node));
125
    }
126
127
    /**
128
     * Checks, that given JSON node is true
129
     *
130
     * @Then the JSON node :node should be true
131
     */
132
    public function theJsonNodeShouldBeTrue($node)
133
    {
134
        $json = $this->getJson();
135
136
        $actual = $this->inspector->evaluate($json, $node);
137
138
        if (true !== $actual) {
139
            throw new \Exception(
140
                sprintf('The node value is `%s`', json_encode($actual))
141
            );
142
        }
143
    }
144
145
    /**
146
     * Checks, that given JSON node is false
147
     *
148
     * @Then the JSON node :node should be false
149
     */
150
    public function theJsonNodeShouldBeFalse($node)
151
    {
152
        $json = $this->getJson();
153
154
        $actual = $this->inspector->evaluate($json, $node);
155
156
        if (false !== $actual) {
157
            throw new \Exception(
158
                sprintf('The node value is `%s`', json_encode($actual))
159
            );
160
        }
161
    }
162
163
    /**
164
     * Checks, that given JSON node is equal to the given string
165
     *
166
     * @Then the JSON node :node should be equal to the string :text
167
     */
168 View Code Duplication
    public function theJsonNodeShouldBeEqualToTheString($node, $text)
169
    {
170
        $json = $this->getJson();
171
172
        $actual = $this->inspector->evaluate($json, $node);
173
174
        if ($actual !== $text) {
175
            throw new \Exception(
176
                sprintf('The node value is `%s`', json_encode($actual))
177
            );
178
        }
179
    }
180
181
    /**
182
     * Checks, that given JSON node is equal to the given number
183
     *
184
     * @Then the JSON node :node should be equal to the number :number
185
     */
186 View Code Duplication
    public function theJsonNodeShouldBeEqualToTheNumber($node, $number)
187
    {
188
        $json = $this->getJson();
189
190
        $actual = $this->inspector->evaluate($json, $node);
191
192
        if ($actual !== (float) $number && $actual !== (int) $number) {
193
            throw new \Exception(
194
                sprintf('The node value is `%s`', json_encode($actual))
195
            );
196
        }
197
    }
198
199
    /**
200
     * Checks, that given JSON node has N element(s)
201
     *
202
     * @Then the JSON node :node should have :count element(s)
203
     */
204 View Code Duplication
    public function theJsonNodeShouldHaveElements($node, $count)
205
    {
206
        $json = $this->getJson();
207
208
        $actual = $this->inspector->evaluate($json, $node);
209
210
        $this->assertSame($count, sizeof((array) $actual));
211
    }
212
213
    /**
214
     * Checks, that given JSON node has less than N element(s)
215
     *
216
     * @Then the JSON node :node should have less than :count element(s)
217
     */
218 View Code Duplication
    public function theJsonNodeShouldHaveLessThanElements($node, $count)
219
    {
220
        $json = $this->getJson();
221
222
        $actual = $this->inspector->evaluate($json, $node);
223
224
        $this->assertLessThan($count, sizeof((array) $actual));
225
    }
226
227
    /**
228
     * Checks, that given JSON node has more than N element(s)
229
     *
230
     * @Then the JSON node :node should have more than :count element(s)
231
     */
232 View Code Duplication
    public function theJsonNodeShouldHaveMoreThanElements($node, $count)
233
    {
234
        $json = $this->getJson();
235
236
        $actual = $this->inspector->evaluate($json, $node);
237
238
        $this->assertMoreThan($count, sizeof((array) $actual));
239
    }
240
241
    /**
242
     * Checks, that given JSON node contains given value
243
     *
244
     * @Then the JSON node :node should contain :text
245
     */
246 View Code Duplication
    public function theJsonNodeShouldContain($node, $text)
247
    {
248
        $json = $this->getJson();
249
250
        $actual = $this->inspector->evaluate($json, $node);
251
252
        $this->assertContains($text, (string) $actual);
253
    }
254
255
    /**
256
     * Checks, that given JSON nodes contains values
257
     *
258
     * @Then the JSON nodes should contain:
259
     */
260
    public function theJsonNodesShouldContain(TableNode $nodes)
261
    {
262
        foreach ($nodes->getRowsHash() as $node => $text) {
263
            $this->theJsonNodeShouldContain($node, $text);
264
        }
265
    }
266
267
    /**
268
     * Checks, that given JSON node does not contain given value
269
     *
270
     * @Then the JSON node :node should not contain :text
271
     */
272 View Code Duplication
    public function theJsonNodeShouldNotContain($node, $text)
273
    {
274
        $json = $this->getJson();
275
276
        $actual = $this->inspector->evaluate($json, $node);
277
278
        $this->assertNotContains($text, (string) $actual);
279
    }
280
281
    /**
282
     * Checks, that given JSON nodes does not contain given value
283
     *
284
     * @Then the JSON nodes should not contain:
285
     */
286
    public function theJsonNodesShouldNotContain(TableNode $nodes)
287
    {
288
        foreach ($nodes->getRowsHash() as $node => $text) {
289
            $this->theJsonNodeShouldNotContain($node, $text);
290
        }
291
    }
292
293
    /**
294
     * Checks, that given JSON node exist
295
     *
296
     * @Then the JSON node :name should exist
297
     */
298
    public function theJsonNodeShouldExist($name)
299
    {
300
        $json = $this->getJson();
301
302
        try {
303
            $node = $this->inspector->evaluate($json, $name);
304
        } catch (\Exception $e) {
305
            throw new \Exception("The node '$name' does not exist.");
306
        }
307
        return $node;
308
    }
309
310
    /**
311
     * Checks, that given JSON node does not exist
312
     *
313
     * @Then the JSON node :name should not exist
314
     */
315
    public function theJsonNodeShouldNotExist($name)
316
    {
317
        $this->not(function () use ($name) {
318
            return $this->theJsonNodeShouldExist($name);
319
        }, "The node '$name' exists.");
320
    }
321
322
    /**
323
     * @Then the JSON should be valid according to this schema:
324
     */
325
    public function theJsonShouldBeValidAccordingToThisSchema(PyStringNode $schema)
326
    {
327
        $this->inspector->validate(
328
            $this->getJson(),
329
            new JsonSchema($schema)
330
        );
331
    }
332
333
    /**
334
     * @Then the JSON should be invalid according to this schema:
335
     */
336
    public function theJsonShouldBeInvalidAccordingToThisSchema(PyStringNode $schema)
337
    {
338
        $this->not(function () use ($schema) {
339
            return $this->theJsonShouldBeValidAccordingToThisSchema($schema);
340
        }, 'Expected to receive invalid json, got valid one');
341
    }
342
343
    /**
344
     * @Then the JSON should be valid according to the schema :filename
345
     */
346
    public function theJsonShouldBeValidAccordingToTheSchema($filename)
347
    {
348
        $this->checkSchemaFile($filename);
349
350
        $this->inspector->validate(
351
            $this->getJson(),
352
            new JsonSchema(
353
                file_get_contents($filename),
354
                'file://' . realpath($filename)
355
            )
356
        );
357
    }
358
359
    /**
360
     * @Then the JSON should be invalid according to the schema :filename
361
     */
362
    public function theJsonShouldBeInvalidAccordingToTheSchema($filename)
363
    {
364
        $this->checkSchemaFile($filename);
365
366
        $this->not(function () use ($filename) {
367
            return $this->theJsonShouldBeValidAccordingToTheSchema($filename);
368
        }, "The schema was valid");
369
    }
370
371
    /**
372
     * @Then the JSON should be equal to:
373
     */
374
    public function theJsonShouldBeEqualTo(PyStringNode $content)
375
    {
376
        $actual = $this->getJson();
377
378
        try {
379
            $expected = new Json($content);
380
        } catch (\Exception $e) {
381
            throw new \Exception('The expected JSON is not a valid');
382
        }
383
384
        $this->assertSame(
385
            (string) $expected,
386
            (string) $actual,
387
            "The json is equal to:\n". $actual->encode()
388
        );
389
    }
390
391
    /**
392
     * @Then print last JSON response
393
     */
394
    public function printLastJsonResponse()
395
    {
396
        echo $this->getJson()
397
            ->encode();
398
    }
399
400
    /**
401
     * Checks, that response JSON matches with a swagger dump
402
     *
403
     * @Then the JSON should be valid according to swagger :dumpPath dump schema :schemaName
404
     */
405
    public function theJsonShouldBeValidAccordingToTheSwaggerSchema($dumpPath, $schemaName)
406
    {
407
        $this->checkSchemaFile($dumpPath);
408
409
        $dumpJson = file_get_contents($dumpPath);
410
        $schemas = json_decode($dumpJson, true);
411
        $definition = json_encode(
412
            $schemas['definitions'][$schemaName]
413
        );
414
        $this->inspector->validate(
415
            $this->getJson(),
416
            new JsonSchema(
417
                $definition
418
            )
419
        );
420
    }
421
    /**
422
     *
423
     * Checks, that response JSON not matches with a swagger dump
424
     *
425
     * @Then the JSON should not be valid according to swagger :dumpPath dump schema :schemaName
426
     */
427
    public function theJsonShouldNotBeValidAccordingToTheSwaggerSchema($dumpPath, $schemaName)
428
    {
429
        $this->not(function () use ($dumpPath, $schemaName) {
430
            return $this->theJsonShouldBeValidAccordingToTheSwaggerSchema($dumpPath, $schemaName);
431
        }, 'JSON Schema matches but it should not');
432
    }
433
434
435
436
    protected function getJson()
437
    {
438
        return new Json($this->httpCallResultPool->getResult()->getValue());
439
    }
440
441
    private function checkSchemaFile($filename)
442
    {
443
        if (false === is_file($filename)) {
444
            throw new \RuntimeException(
445
                'The JSON schema doesn\'t exist'
446
            );
447
        }
448
    }
449
}
450