1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
/** |
4
|
|
|
* File containing a test class. |
5
|
|
|
* |
6
|
|
|
* @copyright Copyright (C) eZ Systems AS. All rights reserved. |
7
|
|
|
* @license For full copyright and license information view LICENSE file distributed with this source code. |
8
|
|
|
*/ |
9
|
|
|
namespace eZ\Publish\Core\REST\Server\Tests\Output\ValueObjectVisitor; |
10
|
|
|
|
11
|
|
|
use DOMDocument; |
12
|
|
|
use DOMXPath; |
13
|
|
|
use eZ\Publish\Core\REST\Common\Output\Generator; |
14
|
|
|
use eZ\Publish\Core\REST\Common\Output\ValueObjectVisitor; |
15
|
|
|
use eZ\Publish\Core\REST\Server\Output\ValueObjectVisitor\Exception as ExceptionValueObjectVisitor; |
16
|
|
|
use eZ\Publish\Core\REST\Common\Tests\Output\ValueObjectVisitorBaseTest; |
17
|
|
|
use Symfony\Component\Translation\TranslatorInterface; |
18
|
|
|
|
19
|
|
|
class ExceptionTest extends ValueObjectVisitorBaseTest |
20
|
|
|
{ |
21
|
|
|
const NON_VERBOSE_ERROR_DESCRIPTION = 'An error has occurred. Please try again later or contact your Administrator.'; |
22
|
|
|
|
23
|
|
|
/** @var \Symfony\Component\Translation\TranslatorInterface|\PHPUnit\Framework\MockObject\MockObject */ |
24
|
|
|
private $translatorMock; |
25
|
|
|
|
26
|
|
|
/** |
27
|
|
|
* Test the Exception visitor. |
28
|
|
|
* |
29
|
|
|
* @return string |
30
|
|
|
*/ |
31
|
|
|
public function testVisit() |
32
|
|
|
{ |
33
|
|
|
$visitor = $this->getVisitor(); |
34
|
|
|
$generator = $this->getGenerator(); |
35
|
|
|
|
36
|
|
|
$result = $this->generateDocument($generator, $visitor); |
37
|
|
|
|
38
|
|
|
$this->assertNotNull($result); |
39
|
|
|
|
40
|
|
|
return $result; |
41
|
|
|
} |
42
|
|
|
|
43
|
|
|
public function testVisitNonVerbose() |
44
|
|
|
{ |
45
|
|
|
$this->getTranslatorMock()->method('trans') |
46
|
|
|
->with('non_verbose_error', [], 'repository_exceptions') |
47
|
|
|
->willReturn(self::NON_VERBOSE_ERROR_DESCRIPTION); |
48
|
|
|
|
49
|
|
|
$visitor = $this->internalGetNonDebugVisitor(); |
50
|
|
|
$visitor->setRequestParser($this->getRequestParser()); |
|
|
|
|
51
|
|
|
$visitor->setRouter($this->getRouterMock()); |
|
|
|
|
52
|
|
|
$visitor->setTemplateRouter($this->getTemplatedRouterMock()); |
|
|
|
|
53
|
|
|
|
54
|
|
|
$generator = $this->getGenerator(); |
55
|
|
|
|
56
|
|
|
$result = $this->generateDocument($generator, $visitor); |
57
|
|
|
|
58
|
|
|
$this->assertNotNull($result); |
59
|
|
|
|
60
|
|
|
return $result; |
61
|
|
|
} |
62
|
|
|
|
63
|
|
|
/** |
64
|
|
|
* Test if result contains ErrorMessage element and error code. |
65
|
|
|
* |
66
|
|
|
* @param string $result |
67
|
|
|
* |
68
|
|
|
* @depends testVisit |
69
|
|
|
*/ |
70
|
|
|
public function testResultContainsErrorCode($result) |
71
|
|
|
{ |
72
|
|
|
$this->assertXMLTag( |
73
|
|
|
[ |
74
|
|
|
'tag' => 'ErrorMessage', |
75
|
|
|
'descendant' => [ |
76
|
|
|
'tag' => 'errorCode', |
77
|
|
|
'content' => (string)$this->getExpectedStatusCode(), |
78
|
|
|
], |
79
|
|
|
], |
80
|
|
|
$result, |
81
|
|
|
'Invalid <ErrorMessage> element.' |
82
|
|
|
); |
83
|
|
|
} |
84
|
|
|
|
85
|
|
|
/** |
86
|
|
|
* Test if result contains ErrorMessage element. |
87
|
|
|
* |
88
|
|
|
* @param string $result |
89
|
|
|
* |
90
|
|
|
* @depends testVisit |
91
|
|
|
*/ |
92
|
|
|
public function testResultContainsErrorMessage($result) |
93
|
|
|
{ |
94
|
|
|
$this->assertXMLTag( |
95
|
|
|
[ |
96
|
|
|
'tag' => 'ErrorMessage', |
97
|
|
|
'descendant' => [ |
98
|
|
|
'tag' => 'errorMessage', |
99
|
|
|
'content' => $this->getExpectedMessage(), |
100
|
|
|
], |
101
|
|
|
], |
102
|
|
|
$result, |
103
|
|
|
'Invalid <ErrorMessage> element.' |
104
|
|
|
); |
105
|
|
|
} |
106
|
|
|
|
107
|
|
|
/** |
108
|
|
|
* Test if result contains ErrorMessage element and description. |
109
|
|
|
* |
110
|
|
|
* @param string $result |
111
|
|
|
* |
112
|
|
|
* @depends testVisit |
113
|
|
|
*/ |
114
|
|
|
public function testResultContainsErrorDescription($result) |
115
|
|
|
{ |
116
|
|
|
$this->assertXMLTag( |
117
|
|
|
[ |
118
|
|
|
'tag' => 'ErrorMessage', |
119
|
|
|
'descendant' => [ |
120
|
|
|
'tag' => 'errorDescription', |
121
|
|
|
], |
122
|
|
|
], |
123
|
|
|
$result, |
124
|
|
|
'Invalid <ErrorMessage> element.' |
125
|
|
|
); |
126
|
|
|
} |
127
|
|
|
|
128
|
|
|
/** |
129
|
|
|
* @depends testVisitNonVerbose |
130
|
|
|
*/ |
131
|
|
|
public function testNonVerboseErrorDescription($result) |
132
|
|
|
{ |
133
|
|
|
$document = new DOMDocument(); |
134
|
|
|
$document->loadXML($result); |
135
|
|
|
$xpath = new DOMXPath($document); |
136
|
|
|
|
137
|
|
|
$nodeList = $xpath->query('//ErrorMessage/errorDescription'); |
138
|
|
|
$errorDescriptionNode = $nodeList->item(0); |
139
|
|
|
|
140
|
|
|
$this->assertEquals(self::NON_VERBOSE_ERROR_DESCRIPTION, $errorDescriptionNode->textContent); |
141
|
|
|
} |
142
|
|
|
|
143
|
|
|
/** |
144
|
|
|
* Test if ErrorMessage element contains required attributes. |
145
|
|
|
* |
146
|
|
|
* @param string $result |
147
|
|
|
* |
148
|
|
|
* @depends testVisit |
149
|
|
|
*/ |
150
|
|
|
public function testResultContainsExceptionAttributes($result) |
151
|
|
|
{ |
152
|
|
|
$this->assertXMLTag( |
153
|
|
|
[ |
154
|
|
|
'tag' => 'ErrorMessage', |
155
|
|
|
'attributes' => [ |
156
|
|
|
'media-type' => 'application/vnd.ez.api.ErrorMessage+xml', |
157
|
|
|
], |
158
|
|
|
], |
159
|
|
|
$result, |
160
|
|
|
'Invalid <ErrorMessage> attributes.' |
161
|
|
|
); |
162
|
|
|
} |
163
|
|
|
|
164
|
|
|
/** |
165
|
|
|
* Test if result contains ErrorMessage element. |
166
|
|
|
* |
167
|
|
|
* @depends testVisit |
168
|
|
|
*/ |
169
|
|
|
public function testResultContainsPreviousError($result) |
170
|
|
|
{ |
171
|
|
|
$dom = new \DOMDocument(); |
172
|
|
|
$dom->loadXml($result); |
173
|
|
|
|
174
|
|
|
$this->assertXPath( |
175
|
|
|
$dom, |
176
|
|
|
'/ErrorMessage/Previous[@media-type="application/vnd.ez.api.ErrorMessage+xml"]' |
177
|
|
|
); |
178
|
|
|
} |
179
|
|
|
|
180
|
|
|
/** |
181
|
|
|
* Get expected status code. |
182
|
|
|
* |
183
|
|
|
* @return int |
184
|
|
|
*/ |
185
|
|
|
protected function getExpectedStatusCode() |
186
|
|
|
{ |
187
|
|
|
return 500; |
188
|
|
|
} |
189
|
|
|
|
190
|
|
|
/** |
191
|
|
|
* Get expected message. |
192
|
|
|
* |
193
|
|
|
* @return string |
194
|
|
|
*/ |
195
|
|
|
protected function getExpectedMessage() |
196
|
|
|
{ |
197
|
|
|
return 'Internal Server Error'; |
198
|
|
|
} |
199
|
|
|
|
200
|
|
|
/** |
201
|
|
|
* Gets the exception. |
202
|
|
|
* |
203
|
|
|
* @return \Exception |
204
|
|
|
*/ |
205
|
|
|
protected function getException() |
206
|
|
|
{ |
207
|
|
|
return new \Exception('Test'); |
208
|
|
|
} |
209
|
|
|
|
210
|
|
|
/** |
211
|
|
|
* Gets the exception visitor. |
212
|
|
|
* |
213
|
|
|
* @return \eZ\Publish\Core\REST\Server\Output\ValueObjectVisitor\Exception |
214
|
|
|
*/ |
215
|
|
|
protected function internalGetVisitor() |
216
|
|
|
{ |
217
|
|
|
return new ExceptionValueObjectVisitor(true, $this->getTranslatorMock()); |
218
|
|
|
} |
219
|
|
|
|
220
|
|
|
/** |
221
|
|
|
* Gets the exception visitor. |
222
|
|
|
* |
223
|
|
|
* @return \eZ\Publish\Core\REST\Server\Output\ValueObjectVisitor\Exception |
224
|
|
|
*/ |
225
|
|
|
protected function internalGetNonDebugVisitor() |
226
|
|
|
{ |
227
|
|
|
return new ExceptionValueObjectVisitor(false, $this->getTranslatorMock()); |
228
|
|
|
} |
229
|
|
|
|
230
|
|
|
protected function getTranslatorMock() |
231
|
|
|
{ |
232
|
|
|
if (!isset($this->translatorMock)) { |
233
|
|
|
$this->translatorMock = $this->getMockBuilder(TranslatorInterface::class) |
234
|
|
|
->disableOriginalConstructor() |
235
|
|
|
->getMock(); |
236
|
|
|
} |
237
|
|
|
|
238
|
|
|
return $this->translatorMock; |
239
|
|
|
} |
240
|
|
|
|
241
|
|
|
private function generateDocument(Generator\Xml $generator, ValueObjectVisitor $visitor) |
242
|
|
|
{ |
243
|
|
|
$generator->startDocument(null); |
244
|
|
|
|
245
|
|
|
$previousException = new \Exception('Sub-test'); |
246
|
|
|
$exception = new \Exception('Test', 0, $previousException); |
247
|
|
|
|
248
|
|
|
$this |
249
|
|
|
->getVisitorMock() |
250
|
|
|
->expects($this->once()) |
251
|
|
|
->method('visitValueObject') |
252
|
|
|
->with($previousException); |
253
|
|
|
|
254
|
|
|
$visitor->visit( |
255
|
|
|
$this->getVisitorMock(), |
|
|
|
|
256
|
|
|
$generator, |
257
|
|
|
$exception |
258
|
|
|
); |
259
|
|
|
|
260
|
|
|
return $generator->endDocument(null); |
261
|
|
|
} |
262
|
|
|
} |
263
|
|
|
|
This check looks at variables that are passed out again to other methods.
If the outgoing method call has stricter type requirements than the method itself, an issue is raised.
An additional type check may prevent trouble.