Passed
Push — master ( 5745e7...6b622f )
by Baptiste
08:34
created

AbstractJson::theJsonPathShouldMatch()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 2
1
<?php
2
namespace Behapi\Context;
3
4
use stdClass;
5
use Datetime;
6
7
use Throwable;
8
use InvalidArgumentException;
9
10
use Behat\Behat\Context\Context;
11
use Behat\Gherkin\Node\PyStringNode;
12
13
use Symfony\Component\PropertyAccess\PropertyAccess;
14
use Symfony\Component\PropertyAccess\PropertyAccessor;
15
16
use Behapi\Extension\Tools\Assert;
17
18
abstract class AbstractJson implements Context
19
{
20
    /** @var PropertyAccessor */
21
    private $accessor;
22
23
    public function __construct()
24
    {
25
        $this->accessor = PropertyAccess::createPropertyAccessor();
26
    }
27
28
    /**
29
     * Get the latest json response
30
     *
31
     * @return stdClass decoded json into an object
32
     */
33
    abstract protected function getJson(): stdClass;
34
35
    /**
36
     * Get the value for a path
37
     *
38
     * @param string $path Path to parse
39
     *
40
     * @return mixed
41
     * @throws AccessException path not valid
42
     */
43
    protected function getValue(string $path)
44
    {
45
        return $this->accessor->getValue($this->getJson(), $path);
46
    }
47
48
    /**
49
     * @Then the response should be a valid json response
50
     *
51
     * ---
52
     *
53
     * This method is built-on the default php's json extension. You should
54
     * overwrite it if you want to add supplementary checks or use something
55
     * else instead (such as Seldaek's JsonLint package).
56
     */
57
    public function responseIsValidjson()
58
    {
59
        $this->getJson();
60
61
        Assert::same(json_last_error(), JSON_ERROR_NONE, 'The latest json response should be a valid json response');
62
    }
63
64
    /** @Then :path should be accessible in the latest json response */
65
    public function pathShouldBeReadable(string $path)
66
    {
67
        Assert::true($this->accessor->isReadable($this->getJson(), $path), "The path $path should be a valid path");
68
    }
69
70
    /** @Then :path should not exist in the latest json response */
71
    public function pathShouldNotBeReadable(string $path)
72
    {
73
        Assert::false($this->accessor->isReadable($this->getJson(), $path), "The path $path should not be a valid path");
74
    }
75
76
    /** @Then in the json, :path should be equal to :expected */
77
    public function theJsonPathShouldBeEqualTo(string $path, $expected)
78
    {
79
        Assert::eq($this->getValue($path), $expected);
80
    }
81
82
    /** @Then in the json, :path should not be equal to :expected */
83
    public function theJsonPathShouldNotBeEqualTo(string $path, $expected)
84
    {
85
        Assert::notEq($this->getValue($path), $expected);
86
    }
87
88
    /** @Then in the json, :path should be: */
89
    public function theJsonPathShouldBePyString(string $path, PyStringNode $expected)
90
    {
91
        Assert::same($this->getValue($path), $expected->getRaw());
92
    }
93
94
    /** @Then /^in the json, "(?P<path>(?:[^"]|\\")*)" should be (?P<expected>true|false)$/ */
95
    public function theJsonPathShouldBe(string $path, string $expected)
96
    {
97
        Assert::same($this->getValue($path), 'true' === $expected);
98
    }
99
100
    /** @Then /^in the json, "(?P<path>(?:[^"]|\\")*)" should not be (?P<expected>true|false)$/ */
101
    public function theJsonPathShouldNotBe(string $path, string $expected)
102
    {
103
        Assert::notSame($this->getValue($path), 'true' === $expected);
104
    }
105
106
    /** @Then in the json, :path should be null */
107
    public function theJsonPathShouldBeNull(string $path)
108
    {
109
        Assert::null($this->getValue($path));
110
    }
111
112
    /** @Then in the json, :path should not be null */
113
    public function theJsonPathShouldNotBeNull(string $path)
114
    {
115
        Assert::notNull($this->getValue($path));
116
    }
117
118
    /** @Then in the json, :path should be empty */
119
    public function theJsonPathShouldBeEmpty(string $path)
120
    {
121
        Assert::isEmpty($this->getValue($path));
122
    }
123
124
    /** @Then in the json, :path should not be empty */
125
    public function theJsonPathShouldNotBeEmpty(string $path)
126
    {
127
        Assert::notEmpty($this->getValue($path));
128
    }
129
130
    /** @Then in the json, :path should contain :expected */
131
    public function theJsonPathContains(string $path, $expected)
132
    {
133
        Assert::contains($this->getValue($path), $expected);
134
    }
135
136
    /** @Then /^in the json, :path should not contain :expected */
137
    public function theJsonPathNotContains(string $path, $expected)
138
    {
139
        Assert::notContains($this->getValue($path), $expected);
140
    }
141
142
    /** @Then in the json, :path collection should contain an element with :value equal to :expected */
143
    public function theJsonPathCollectionContains(string $path, string $value, $expected)
144
    {
145
        $collection = $this->accessor->getValue($this->getJson(), $path);
146
147
        foreach ($collection as $element) {
148
            if ($expected === $this->accessor->getValue($element, $value)) {
149
                return;
150
            }
151
        }
152
153
        throw new InvalidArgumentException("$path collection does not contain an element with $value equal to $expected");
154
    }
155
156
    /** @Then in the json, :path should be a valid date(time) */
157
    public function theJsonPathShouldBeAValidDate(string $path)
158
    {
159
        try {
160
            new Datetime($this->getValue($path));
161
        } catch (Throwable $t) {
162
            throw new InvalidArgumentException("$path does not contain a valid date");
163
        }
164
    }
165
166
    /** @Then in the json, :path should be greater than :expected */
167
    public function theJsonPathShouldBeGreaterThan(string $path, int $expected)
168
    {
169
        Assert::greaterThan($this->getValue($path), $expected);
170
    }
171
172
    /** @Then in the json, :path should be greater than or equal to :expected */
173
    public function theJsonPathShouldBeGreaterOrEqualThan(string $path, int $expected)
174
    {
175
        Assert::greaterThanEq($this->getValue($path), $expected);
176
    }
177
178
    /** @Then in the json, :path should be less than :expected */
179
    public function theJsonPathShouldBeLessThan(string $path, int $expected)
180
    {
181
        Assert::lessThan($this->getValue($path), $expected);
182
    }
183
184
    /** @Then in the json, :path should be less than or equal to :expected */
185
    public function theJsonPathShouldBeLessOrEqualThan(string $path, int $expected)
186
    {
187
        Assert::lessThanEq($this->getValue($path), $expected);
188
    }
189
190
    /** @Then in the json, :path should be an array */
191
    public function shouldBeAnArray(string $path)
192
    {
193
        Assert::isArray($this->getValue($path));
194
    }
195
196
    /** @Then in the json, :path should have at least :count element(s) */
197
    public function theJsonPathShouldHaveAtLeastElements(string $path, int $count)
198
    {
199
        $value = $this->getValue($path);
200
201
        Assert::isArray($value);
202
        Assert::greaterThanEq(count($value), $count);
203
    }
204
205
    /** @Then in the json, :path should have :count element(s) */
206
    public function theJsonPathShouldHaveElements(string $path, int $count)
207
    {
208
        Assert::count($this->getValue($path), $count);
209
    }
210
211
    /** @Then in the json, :path should have at most :count element(s) */
212
    public function theJsonPathShouldHaveAtMostElements(string $path, int $count)
213
    {
214
        $value = $this->getValue($path);
215
216
        Assert::isArray($value);
217
        Assert::lessThanEq(count($value), $count);
218
    }
219
220
    /** @Then in the json, :path should match :pattern */
221
    public function theJsonPathShouldMatch(string $path, string $pattern)
222
    {
223
        Assert::regex($this->getValue($path), $pattern);
224
    }
225
226
    /** @Then in the json, :path should not match :pattern */
227
    public function theJsonPathShouldNotMatch(string $path, string $pattern)
228
    {
229
        Assert::notRegex($this->getValue($path), $pattern);
230
    }
231
232
    /** @Then in the json, the root should be an array */
233
    public function rootShouldBeAnArray()
234
    {
235
        Assert::isArray($this->getJson());
236
    }
237
238
    /** @Then in the json, the root should have :count element(s) */
239
    public function theRootShouldHaveElements(int $count)
240
    {
241
        $value = $this->getJson();
242
243
        Assert::isArray($value);
244
        Assert::count($value, $count);
245
    }
246
247
    /** @Then in the json, the root should have at most :count element(s) */
248
    public function theRootShouldHaveAtMostElements(int $count)
249
    {
250
        $value = $this->getJson();
251
252
        Assert::isArray($value);
253
        Assert::lessThanEq($value, $count);
254
    }
255
256
    /** @Then in the json, :path should be a valid json encoded string */
257
    public function theJsonPathShouldBeAValidJsonEncodedString(string $path)
258
    {
259
        $value = json_decode($this->getValue($path));
260
261
        Assert::notNull($value);
262
        Assert::same(json_last_error(), JSON_ERROR_NONE);
263
    }
264
}
265