From 0c0e344b5a9de48219500ea80bb6adac1d43abdb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adam=20Fi=C5=A1er?= Date: Sat, 1 Aug 2026 07:48:38 +0200 Subject: [PATCH] feat: support the querystring parameter location and query operation OpenAPI 3.2.0 added two constructs this library actively mishandled. A parameter with in: querystring, which treats the whole query string as one value, threw InvalidArgumentException because the location was not in the allowed list. Such a parameter must describe itself with content, which the previous commit made possible. A path item with a query operation lost it silently: setOperation() returns early for methods outside its allow list, so the operation vanished from toArray() without a word. Both are now known: Parameter::IN_QUERYSTRING and PathItem::OPERATION_QUERY. --- src/Schema/Parameter.php | 2 ++ src/Schema/PathItem.php | 2 ++ tests/Cases/Schema/ParameterTest.php | 18 ++++++++++++- tests/Cases/Schema/PathItemTest.php | 38 ++++++++++++++++++++++++++++ 4 files changed, 59 insertions(+), 1 deletion(-) create mode 100644 tests/Cases/Schema/PathItemTest.php diff --git a/src/Schema/Parameter.php b/src/Schema/Parameter.php index c92718a..5cc7729 100644 --- a/src/Schema/Parameter.php +++ b/src/Schema/Parameter.php @@ -11,12 +11,14 @@ class Parameter public const IN_HEADER = 'header'; public const IN_PATH = 'path'; public const IN_QUERY = 'query'; + public const IN_QUERYSTRING = 'querystring'; public const INS = [ self::IN_COOKIE, self::IN_HEADER, self::IN_PATH, self::IN_QUERY, + self::IN_QUERYSTRING, ]; private string $name; diff --git a/src/Schema/PathItem.php b/src/Schema/PathItem.php index 4287755..64fc1f4 100644 --- a/src/Schema/PathItem.php +++ b/src/Schema/PathItem.php @@ -13,6 +13,7 @@ class PathItem public const OPERATION_HEAD = 'head'; public const OPERATION_PATCH = 'patch'; public const OPERATION_TRACE = 'trace'; + public const OPERATION_QUERY = 'query'; /** @var string[] */ private static array $allowedOperations = [ @@ -24,6 +25,7 @@ class PathItem self::OPERATION_HEAD, self::OPERATION_PATCH, self::OPERATION_TRACE, + self::OPERATION_QUERY, ]; private ?string $summary = null; diff --git a/tests/Cases/Schema/ParameterTest.php b/tests/Cases/Schema/ParameterTest.php index 8246511..6e8f16e 100644 --- a/tests/Cases/Schema/ParameterTest.php +++ b/tests/Cases/Schema/ParameterTest.php @@ -98,11 +98,27 @@ public function testContent(): void Assert::same($expectedData, $parameter->toArray()); } + public function testQuerystringLocation(): void + { + $expectedData = [ + 'name' => 'query', + 'in' => 'querystring', + 'content' => [ + 'application/x-www-form-urlencoded' => ['schema' => ['type' => 'string']], + ], + ]; + + $parameter = Parameter::fromArray($expectedData); + + Assert::same(Parameter::IN_QUERYSTRING, $parameter->getIn()); + Assert::same($expectedData, $parameter->toArray()); + } + public function testInvalidIn(): void { Assert::exception(static function (): void { new Parameter('foo', 'invalid'); - }, InvalidArgumentException::class, 'Invalid value "invalid" for attribute "in" given. It must be one of "cookie, header, path, query".'); + }, InvalidArgumentException::class, 'Invalid value "invalid" for attribute "in" given. It must be one of "cookie, header, path, query, querystring".'); } public function testSchemaReference(): void diff --git a/tests/Cases/Schema/PathItemTest.php b/tests/Cases/Schema/PathItemTest.php new file mode 100644 index 0000000..a542d07 --- /dev/null +++ b/tests/Cases/Schema/PathItemTest.php @@ -0,0 +1,38 @@ + ['200' => ['description' => 'Success']]]; + + public function testOperations(): void + { + $expectedData = [ + 'get' => self::RESPONSES, + 'post' => self::RESPONSES, + ]; + + Assert::same($expectedData, PathItem::fromArray($expectedData)->toArray()); + } + + public function testQueryOperation(): void + { + $expectedData = [ + 'get' => self::RESPONSES, + 'query' => self::RESPONSES, + ]; + + Assert::same($expectedData, PathItem::fromArray($expectedData)->toArray()); + } + +} + +(new PathItemTest())->run();