8000 Close #185 · rzenkov/json-api@6d49cef · GitHub
[go: up one dir, main page]

Skip to content

Commit 6d49cef

Browse files
committed
Close neomerx#185
1 parent a599881 commit 6d49cef

File tree

4 files changed

+120
-21
lines changed

4 files changed

+120
-21
lines changed

src/Http/Headers/HeaderParametersParser.php

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
use \InvalidArgumentException;
2020
use \Psr\Log\LoggerAwareTrait;
2121
use \Psr\Log\LoggerAwareInterface;
22+
use \Neomerx\JsonApi\Document\Error;
23+
use \Neomerx\JsonApi\I18n\Translator as T;
2224
use \Psr\Http\Message\ServerRequestInterface;
2325
use \Neomerx\JsonApi\Exceptions\JsonApiException as E;
2426
use \Neomerx\JsonApi\Contracts\Http\HttpFactoryInterface;
@@ -62,15 +64,19 @@ public function parse(ServerRequestInterface $request, $checkContentType = true)
6264
$header = $this->getHeader($request, HeaderInterface::HEADER_CONTENT_TYPE);
6365
$contentTypeHeader = Header::parse($header, HeaderInterface::HEADER_CONTENT_TYPE);
6466
} catch (InvalidArgumentException $exception) {
65-
E::throwException(new E([], E::HTTP_CODE_BAD_REQUEST, $exception));
67+
$title = T::t('Invalid ' . HeaderInterface::HEADER_CONTENT_TYPE . ' header.');
68+
$error = new Error(null, null, null, null, $title);
69+
E::throwException(new E([$error], E::HTTP_CODE_BAD_REQUEST, $exception));
6670
}
6771
}
6872

6973
try {
7074
$header = $this->getHeader($request, HeaderInterface::HEADER_ACCEPT);
7175
$acceptHeader = AcceptHeader::parse($header);
7276
} catch (InvalidArgumentException $exception) {
73-
E::throwException(new E([], E::HTTP_CODE_BAD_REQUEST, $exception));
77+
$title = T::t('Invalid ' . HeaderInterface::HEADER_ACCEPT . ' header.');
78+
$error = new Error(null, null, null, null, $title);
79+
E::throwException(new E([$error], E::HTTP_CODE_BAD_REQUEST, $exception));
7480
}
7581

7682
$method = $request->getMethod();

src/Http/Query/QueryParametersParser.php

Lines changed: 65 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818

1919
use \Psr\Log\LoggerAwareTrait;
2020
use \Psr\Log\LoggerAwareInterface;
21+
use \Neomerx\JsonApi\Document\Error;
22+
use \Neomerx\JsonApi\I18n\Translator as T;
2123
use \Psr\Http\Message\ServerRequestInterface;
2224
use \Neomerx\JsonApi\Exceptions\JsonApiException as E;
2325
use \Neomerx\JsonApi\Contracts\Http\HttpFactoryInterface;
@@ -89,7 +91,10 @@ private function getFieldSets(array $parameters)
8991
if (empty($fieldSets) === false && is_array($fieldSets)) {
9092
foreach ($fieldSets as $type => $fields) {
9193
// We expect fields to be comma separated or empty strings. Multi-dimension arrays are not allowed.
92-
is_string($fields) ?: E::throwException(new E([], E::HTTP_CODE_BAD_REQUEST));
94+
if (is_string($fields) === false) {
95+
$detail = T::t(self::PARAM_FIELDS . ' parameter values should be comma separated strings.');
96+
throw new E($this->createInvalidQueryErrors($detail), E::HTTP_CODE_BAD_REQUEST);
97+
}
9398
$result[$type] = (empty($fields) === true ? [] : explode(',', $fields));
9499
}
95100
} else {
@@ -112,11 +117,16 @@ protected function getSortParameters(array $parameters)
112117
$sortParam = $this->getStringParamOrNull($parameters, self::PARAM_SORT);
113118
if ($sortParam !== null) {
114119
foreach (explode(',', $sortParam) as $param) {
115-
$isDesc = false;
116-
empty($param) === false ?
117-
$isDesc = ($param[0] === '-') : E::throwException(new E([], E::HTTP_CODE_BAD_REQUEST));
120+
if (empty($param) === true) {
121+
$detail = T::t('Parameter ' . self::PARAM_SORT . ' should have valid value specified.');
122+
throw new E($this->createInvalidQueryErrors($detail), E::HTTP_CODE_BAD_REQUEST);
123+
}
124+
$isDesc = $isDesc = ($param[0] === '-');
118125
$sortField = ltrim($param, '+-');
119-
empty($sortField) === false ?: E::throwException(new E([], E::HTTP_CODE_BAD_REQUEST));
126+
if (empty($sortField) === true) {
127+
$detail = T::t('Parameter ' . self::PARAM_SORT . ' should have valid name specified.');
128+
throw new E($this->createInvalidQueryErrors($detail), E::HTTP_CODE_BAD_REQUEST);
129+
}
120130
$sortParams[] = $this->factory->createSortParam($sortField, $isDesc === false);
121131
}
122132
}
@@ -173,8 +183,10 @@ private function getArrayParamOrNull(array $parameters, $name)
173183
{
174184
$value = $this->getParamOrNull($parameters, $name);
175185

176-
$isArrayOrNull = ($value === null || is_array($value) === true);
177-
$isArrayOrNull === true ?: E::throwException(new E([], E::HTTP_CODE_BAD_REQUEST));
186+
if ($value !== null && is_array($value) === false) {
187+
$detail = T::t('Value should be either an array or null.');
188+
throw new E($this->createParamErrors($name, $detail), E::HTTP_CODE_BAD_REQUEST);
189+
}
178190

179191
return $value;
180192
}
@@ -191,8 +203,10 @@ private function getStringParamOrNull(array $parameters, $name)
191203
{
192204
$value = $this->getParamOrNull($parameters, $name);
193205

194-
$isStringOrNull = ($value === null || is_string($value) === true);
195-
$isStringOrNull === true ?: E::throwException(new E([], E::HTTP_CODE_BAD_REQUEST));
206+
if ($value !== null && is_string($value) === false) {
207+
$detail = T::t('Value should be either a string or null.');
208+
throw new E($this->createParamErrors($name, $detail), E::HTTP_CODE_BAD_REQUEST);
209+
}
196210

197211
return $value;
198212
}
@@ -207,4 +221,46 @@ private function getParamOrNull(array $parameters, $name)
207221
{
208222
return isset($parameters[$name]) === true ? $parameters[$name] : null;
209223
}
224+
225+
/**
226+
* @param string $detail
227+
*
228+
* @return Error[]
229+
*
230+
* @SuppressWarnings(PHPMD.StaticAccess)
231+
*/
232+
protected function createInvalidQueryErrors($detail)
233+
{
234+
// NOTE: external libraries might expect this method to exist and have certain signature
235+
// @see https://github.com/neomerx/json-api/issues/185#issuecomment-329135390
236+
237+
$title = T::t('Invalid query.');
238+
239+
return [
240+
new Error(null, null, null, null, $title, $detail),
241+
];
242+
}
243+
244+
/**
245+
* @param string $name
246+
* @param string $detail
247+
*
248+
* @return Error[]
249+
*
250+
* @SuppressWarnings(PHPMD.StaticAccess)
251+
*/
252+
protected function createParamErrors($name, $detail)
253+
{
254+
// NOTE: external libraries might expect this method to exist and have certain signature
255+
// @see https://github.com/neomerx/json-api/issues/185#issuecomment-329135390
256+
257+
$title = T::t('Invalid query parameter.');
258+
$source = [
259+
Error::SOURCE_PARAMETER => $name,
260+
];
261+
262+
return [
263+
new Error(null, null, null, null, $title, $detail, $source),
264+
];
265+
}
210266
}

tests/Http/Headers/HeaderParametersParserTest.php

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
use \Neomerx\JsonApi\Factories\Factory;
2222
use \Neomerx\Tests\JsonApi\BaseTestCase;
2323
use \Psr\Http\Message\ServerRequestInterface;
24+
use \Neomerx\JsonApi\Exceptions\JsonApiException;
2425
use \Neomerx\JsonApi\Contracts\Http\Headers\HeaderInterface;
2526
use \Neomerx\JsonApi\Contracts\Http\Headers\MediaTypeInterface;
2627
use \Neomerx\JsonApi\Contracts\Http\Headers\HeaderParametersParserInterface;
@@ -183,22 +184,32 @@ public function testParseWithEmptyAcceptHeader()
183184

184185
/**
185186
* Test parse invalid headers.
186-
*
187-
* @expectedException \Neomerx\JsonApi\Exceptions\JsonApiException
188187
*/
189188
public function testParseIvalidHeaders1()
190189
{
191-
$this->parser->parse($this->prepareRequest('POST', self::TYPE.';foo', self::TYPE, 1, 0));
190+
$exception = null;
191+
try {
192+
$this->parser->parse($this->prepareRequest('POST', self::TYPE . ';foo', self::TYPE, 1, 0));
193+
} catch (JsonApiException $exception) {
194+
}
195+
196+
$this->assertNotNull($exception);
197+
$this->assertNotEmpty($exception->getErrors());
192198
}
193199

194200
/**
195201
* Test parse invalid headers.
196-
*
197-
* @expectedException \Neomerx\JsonApi\Exceptions\JsonApiException
198202
*/
199203
public function testParseIvalidHeaders2()
200204
{
201-
$this->parser->parse($this->prepareRequest('POST', self::TYPE, self::TYPE.';foo', 1, 1));
205+
$exception = null;
206+
try {
207+
$this->parser->parse($this->prepareRequest('POST', self::TYPE, self::TYPE.';foo', 1, 1));
208+
} catch (JsonApiException $exception) {
209+
}
210+
211+
$this->assertNotNull($exception);
212+
$this->assertNotEmpty($exception->getErrors());
202213
}
203214

204215
/**

tests/Http/Query/ParameterParserTest.php

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
use \Neomerx\JsonApi\Factories\Factory;
2222
use \Neomerx\Tests\JsonApi\BaseTestCase;
2323
use \Psr\Http\Message\ServerRequestInterface;
24+
use \Neomerx\JsonApi\Exceptions\JsonApiException;
2425
use \Neomerx\JsonApi\Contracts\Http\Query\QueryParametersParserInterface;
2526

2627
/**
@@ -140,15 +141,40 @@ public function testSortParamsStringConversion()
140141

141142
/**
142143
* Test miss field in sort params.
143-
*
144-
* @expectedException \Neomerx\JsonApi\Exceptions\JsonApiException
145144
*/
146-
public function testSendIncorrectSortParams()
145+
public function testSendIncorrectSortParams1()
147146
{
148147
$input = [
149148
'sort' => '-created,,name'
150149
];
151-
$this->parser->parse($this->prepareRequest($input));
150+
151+
$exception = null;
152+
try {
153+
$this->parser->parse($this->prepareRequest($input));
154+
} catch (JsonApiException $exception) {
155+
}
156+
157+
$this->assertNotNull($exception);
158+
$this->assertNotEmpty($exception->getErrors());
159+
}
160+
161+
/**
162+
* Test miss field in sort params.
163+
*/
164+
public function testSendIncorrectSortParams2()
165+
{
166+
$input = [
167+
'sort' => '-created,+,name'
168+
];
169+
170+
$exception = null;
171+
try {
172+
$this->parser->parse($this->prepareRequest($input));
173+
} catch (JsonApiException $exception) {
174+
}
175+
176+
$this->assertNotNull($exception);
177+
$this->assertNotEmpty($exception->getErrors());
152178
}
153179

154180
/**

0 commit comments

Comments
 (0)
0