Passed
Push — master ( b9fcd3...4705d6 )
by San
01:01
created

theJsonShouldBeValidAccordingToTheSwaggerSchema()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 16
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 16
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 10
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 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
    /**
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
    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 contains given value
215
     *
216
     * @Then the JSON node :node should contain :text
217
     */
218 View Code Duplication
    public function theJsonNodeShouldContain($node, $text)
219
    {
220
        $json = $this->getJson();
221
222
        $actual = $this->inspector->evaluate($json, $node);
223
224
        $this->assertContains($text, (string) $actual);
225
    }
226
227
    /**
228
     * Checks, that given JSON nodes contains values
229
     *
230
     * @Then the JSON nodes should contain:
231
     */
232
    public function theJsonNodesShouldContain(TableNode $nodes)
233
    {
234
        foreach ($nodes->getRowsHash() as $node => $text) {
235
            $this->theJsonNodeShouldContain($node, $text);
236
        }
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
    /**
266
     * Checks, that given JSON node exist
267
     *
268
     * @Given the JSON node :name should exist
269
     */
270
    public function theJsonNodeShouldExist($name)
271
    {
272
        $json = $this->getJson();
273
274
        try {
275
            $node = $this->inspector->evaluate($json, $name);
276
        } catch (\Exception $e) {
277
            throw new \Exception("The node '$name' does not exist.");
278
        }
279
        return $node;
280
    }
281
282
    /**
283
     * Checks, that given JSON node does not exist
284
     *
285
     * @Given the JSON node :name should not exist
286
     */
287
    public function theJsonNodeShouldNotExist($name)
288
    {
289
        $this->not(function () use ($name) {
290
            return $this->theJsonNodeShouldExist($name);
291
        }, "The node '$name' exists.");
292
    }
293
294
    /**
295
     * @Then the JSON should be valid according to this schema:
296
     */
297
    public function theJsonShouldBeValidAccordingToThisSchema(PyStringNode $schema)
298
    {
299
        $this->inspector->validate(
300
            $this->getJson(),
301
            new JsonSchema($schema)
302
        );
303
    }
304
305
    /**
306
     * @Then the JSON should be invalid according to this schema:
307
     */
308
    public function theJsonShouldBeInvalidAccordingToThisSchema(PyStringNode $schema)
309
    {
310
        $this->not(function () use ($schema) {
311
            return $this->theJsonShouldBeValidAccordingToThisSchema($schema);
312
        }, 'Expected to receive invalid json, got valid one');
313
    }
314
315
    /**
316
     * @Then the JSON should be valid according to the schema :filename
317
     */
318
    public function theJsonShouldBeValidAccordingToTheSchema($filename)
319
    {
320
        $this->checkSchemaFile($filename);
321
322
        $this->inspector->validate(
323
            $this->getJson(),
324
            new JsonSchema(
325
                file_get_contents($filename),
326
                'file://' . realpath($filename)
327
            )
328
        );
329
    }
330
331
    /**
332
     * @Then the JSON should be invalid according to the schema :filename
333
     */
334
    public function theJsonShouldBeInvalidAccordingToTheSchema($filename)
335
    {
336
        $this->checkSchemaFile($filename);
337
338
        $this->not(function () use ($filename) {
339
            return $this->theJsonShouldBeValidAccordingToTheSchema($filename);
340
        }, "The schema was valid");
341
    }
342
343
    /**
344
     * @Then the JSON should be equal to:
345
     */
346
    public function theJsonShouldBeEqualTo(PyStringNode $content)
347
    {
348
        $actual = $this->getJson();
349
350
        try {
351
            $expected = new Json($content);
352
        } catch (\Exception $e) {
353
            throw new \Exception('The expected JSON is not a valid');
354
        }
355
356
        $this->assertSame(
357
            (string) $expected,
358
            (string) $actual,
359
            "The json is equal to:\n". $actual->encode()
360
        );
361
    }
362
363
    /**
364
     * @Then print last JSON response
365
     */
366
    public function printLastJsonResponse()
367
    {
368
        echo $this->getJson()
369
            ->encode();
370
    }
371
372
    /**
373
     * Checks, that response JSON matches with a swagger dump
374
     *
375
     * @Then the JSON should be valid according to swagger :dumpPath dump schema :schemaName
376
     */
377
    public function theJsonShouldBeValidAccordingToTheSwaggerSchema($dumpPath, $schemaName)
378
    {
379
        $this->checkSchemaFile($dumpPath);
380
381
        $dumpJson = file_get_contents($dumpPath);
382
        $schemas = json_decode($dumpJson, true);
383
        $definition = json_encode(
384
            $schemas['definitions'][$schemaName]
385
        );
386
        $this->inspector->validate(
387
            $this->getJson(),
388
            new JsonSchema(
389
                $definition
390
            )
391
        );
392
    }
393
    /**
394
     *
395
     * Checks, that response JSON not matches with a swagger dump
396
     *
397
     * @Then the JSON should not be valid according to swagger :dumpPath dump schema :schemaName
398
     */
399
    public function theJsonShouldNotBeValidAccordingToTheSwaggerSchema($dumpPath, $schemaName)
400
    {
401
        $this->not(function () use ($dumpPath, $schemaName) {
402
            return $this->theJsonShouldBeValidAccordingToTheSwaggerSchema($dumpPath, $schemaName);
403
        }, 'JSON Schema matches but it should not');
404
    }
405
406
407
408
    protected function getJson()
409
    {
410
        return new Json($this->httpCallResultPool->getResult()->getValue());
411
    }
412
413
    private function checkSchemaFile($filename)
414
    {
415
        if (false === is_file($filename)) {
416
            throw new \RuntimeException(
417
                'The JSON schema doesn\'t exist'
418
            );
419
        }
420
    }
421
}
422