diff --git a/src/JsonApi.php b/src/JsonApi.php index 2f04eca..12c9c23 100644 --- a/src/JsonApi.php +++ b/src/JsonApi.php @@ -115,6 +115,8 @@ final class JsonApi implements RequestHandlerInterface { // $this->validateRequest($request); + $this->validateQueryParameters($request); + $context = new Context($this, $request); foreach ($this->extensions as $extension) { @@ -151,6 +153,18 @@ final class JsonApi implements RequestHandlerInterface throw new BadRequestException(); } + private function validateQueryParameters(Request $request): void + { + foreach ($request->getQueryParams() as $key => $value) { + if ( + ! preg_match('/[^a-z]/', $key) + && ! in_array($key, ['include', 'fields', 'filter', 'page', 'sort']) + ) { + throw (new BadRequestException('Invalid query parameter: '.$key))->setSourceParameter($key); + } + } + } + private function validateRequest(Request $request): void { // TODO diff --git a/tests/specification/QueryParametersTest.php b/tests/specification/QueryParametersTest.php index 8ab7989..9288c7c 100644 --- a/tests/specification/QueryParametersTest.php +++ b/tests/specification/QueryParametersTest.php @@ -11,6 +11,7 @@ namespace Tobyz\Tests\JsonApiServer\specification; +use Tobyz\JsonApiServer\Exception\BadRequestException; use Tobyz\JsonApiServer\JsonApi; use Tobyz\Tests\JsonApiServer\AbstractTestCase; use Tobyz\Tests\JsonApiServer\MockAdapter; @@ -25,20 +26,29 @@ class QueryParametersTest extends AbstractTestCase */ private $api; - /** - * @var MockAdapter - */ - private $adapter; - public function setUp(): void { $this->api = new JsonApi('http://example.com'); - - $this->adapter = new MockAdapter(); + $this->api->resourceType('users', new MockAdapter()); } public function test_bad_request_error_if_unknown_query_parameters() { - $this->markTestIncomplete(); + $request = $this->buildRequest('GET', '/users/1') + ->withQueryParams(['unknown' => 'value']); + + $this->expectException(BadRequestException::class); + + $this->api->handle($request); + } + + public function test_supports_custom_query_parameters() + { + $request = $this->buildRequest('GET', '/users/1') + ->withQueryParams(['camelCase' => 'value']); + + $response = $this->api->handle($request); + + $this->assertEquals(200, $response->getStatusCode()); } }