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 |
|
|
|
|
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) |
|
|
|
|
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) |
|
|
|
|
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) |
|
|
|
|
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
|
|
|
private function evaluateJsonNodeValue($jsonNode) |
196
|
|
|
{ |
197
|
|
|
return $this->jsonInspector->readJsonNodeValue($jsonNode); |
198
|
|
|
} |
199
|
|
|
|
200
|
|
|
private function readJson() |
201
|
|
|
{ |
202
|
|
|
return $this->jsonInspector->readJson(); |
203
|
|
|
} |
204
|
|
|
|
205
|
|
|
private function resolveFilename($filename) |
206
|
|
|
{ |
207
|
|
|
if (true === is_file($filename)) { |
208
|
|
|
return realpath($filename); |
209
|
|
|
} |
210
|
|
|
|
211
|
|
|
if (null === $this->jsonSchemaBaseUrl) { |
212
|
|
|
throw new \RuntimeException(sprintf( |
213
|
|
|
'The JSON schema file "%s" doesn\'t exist', |
214
|
|
|
$filename |
215
|
|
|
)); |
216
|
|
|
} |
217
|
|
|
|
218
|
|
|
$filename = $this->jsonSchemaBaseUrl . '/' . $filename; |
219
|
|
|
|
220
|
|
|
if (false === is_file($filename)) { |
221
|
|
|
throw new \RuntimeException(sprintf( |
222
|
|
|
'The JSON schema file "%s" doesn\'t exist', |
223
|
|
|
$filename |
224
|
|
|
)); |
225
|
|
|
} |
226
|
|
|
|
227
|
|
|
return realpath($filename); |
228
|
|
|
} |
229
|
|
|
|
230
|
|
|
private function assert(callable $assertion) |
231
|
|
|
{ |
232
|
|
|
try { |
233
|
|
|
$assertion(); |
234
|
|
|
} catch (\Exception $e) { |
235
|
|
|
throw new WrongJsonExpectation($e->getMessage(), $this->readJson(), $e); |
236
|
|
|
} |
237
|
|
|
} |
238
|
|
|
} |
239
|
|
|
|
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.