From c1a95945fae31d4910659c052731bb79e682cb7e Mon Sep 17 00:00:00 2001 From: indexxd Date: Tue, 4 Jun 2024 23:01:17 +0200 Subject: [PATCH 1/2] Add callback option to enums --- src/RouteDescriber/FosRestDescriber.php | 8 ++++++ tests/RouteDescriber/FosRestDescriberTest.php | 26 +++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/src/RouteDescriber/FosRestDescriber.php b/src/RouteDescriber/FosRestDescriber.php index 3ee28847d..3ab863da9 100644 --- a/src/RouteDescriber/FosRestDescriber.php +++ b/src/RouteDescriber/FosRestDescriber.php @@ -149,6 +149,14 @@ private function getFormat($requirements): ?string private function getEnum($requirements): ?array { if ($requirements instanceof Choice) { + if ($requirements->callback) { + if (!\is_callable($choices = $requirements->callback)) { + return null; + } + + return $choices(); + } + return $requirements->choices; } diff --git a/tests/RouteDescriber/FosRestDescriberTest.php b/tests/RouteDescriber/FosRestDescriberTest.php index 51da37a65..318eb5558 100644 --- a/tests/RouteDescriber/FosRestDescriberTest.php +++ b/tests/RouteDescriber/FosRestDescriberTest.php @@ -47,4 +47,30 @@ public function testQueryParamWithChoiceConstraintIsAddedAsEnum(): void self::assertSame($choices, $api->paths[0]->get->parameters[0]->schema->enum); } + + public function testQueryParamWithChoiceConstraintCallbackIsAddedAsEnum() + { + $queryParam = new QueryParam(); + $choice = new Choice(); + $choice->callback = function () { + return ['foo', 'bar']; + }; + + $queryParam->requirements = $choice; + $readerMock = $this->createMock(Reader::class); + $readerMock->method('getMethodAnnotations')->willReturn([ + $queryParam, + ]); + + $fosRestDescriber = new FosRestDescriber($readerMock, []); + $api = new OpenApi([]); + + $fosRestDescriber->describe( + $api, + new Route('/'), + $this->createMock(\ReflectionMethod::class) + ); + + $this->assertSame(['foo', 'bar'], $api->paths[0]->get->parameters[0]->schema->enum); + } } From 655e1431d00a802fd65744fc8e7cb36a203a94ab Mon Sep 17 00:00:00 2001 From: indexxd Date: Tue, 4 Jun 2024 23:49:39 +0200 Subject: [PATCH 2/2] Add arrays of enums in QueryParam using the multiple option --- src/RouteDescriber/FosRestDescriber.php | 11 +++++-- tests/RouteDescriber/FosRestDescriberTest.php | 31 +++++++++++++++++-- 2 files changed, 38 insertions(+), 4 deletions(-) diff --git a/src/RouteDescriber/FosRestDescriber.php b/src/RouteDescriber/FosRestDescriber.php index 3ab863da9..2c6df5451 100644 --- a/src/RouteDescriber/FosRestDescriber.php +++ b/src/RouteDescriber/FosRestDescriber.php @@ -149,7 +149,7 @@ private function getFormat($requirements): ?string private function getEnum($requirements): ?array { if ($requirements instanceof Choice) { - if ($requirements->callback) { + if (null != $requirements->callback) { if (!\is_callable($choices = $requirements->callback)) { return null; } @@ -225,7 +225,14 @@ private function describeCommonSchemaFromAnnotation(OA\Schema $schema, AbstractS $enum = $this->getEnum($annotation->requirements); if (null !== $enum) { - $schema->enum = $enum; + if ($annotation->requirements instanceof Choice) { + if ($annotation->requirements->multiple) { + $schema->type = 'array'; + $schema->items = Util::createChild($schema, OA\Items::class, ['type' => 'string', 'enum' => $enum]); + } else { + $schema->enum = $enum; + } + } } } diff --git a/tests/RouteDescriber/FosRestDescriberTest.php b/tests/RouteDescriber/FosRestDescriberTest.php index 318eb5558..65c3c91b3 100644 --- a/tests/RouteDescriber/FosRestDescriberTest.php +++ b/tests/RouteDescriber/FosRestDescriberTest.php @@ -48,7 +48,7 @@ public function testQueryParamWithChoiceConstraintIsAddedAsEnum(): void self::assertSame($choices, $api->paths[0]->get->parameters[0]->schema->enum); } - public function testQueryParamWithChoiceConstraintCallbackIsAddedAsEnum() + public function testQueryParamWithChoiceConstraintCallbackIsAddedAsEnum(): void { $queryParam = new QueryParam(); $choice = new Choice(); @@ -71,6 +71,33 @@ public function testQueryParamWithChoiceConstraintCallbackIsAddedAsEnum() $this->createMock(\ReflectionMethod::class) ); - $this->assertSame(['foo', 'bar'], $api->paths[0]->get->parameters[0]->schema->enum); + self::assertSame(['foo', 'bar'], $api->paths[0]->get->parameters[0]->schema->enum); + } + + public function testQueryParamWithChoiceConstraintAsArray(): void + { + $choices = ['foo', 'bar']; + + $queryParam = new QueryParam(); + $choice = new Choice($choices); + $choice->multiple = true; + $queryParam->requirements = $choice; + + $readerMock = $this->createMock(Reader::class); + $readerMock->method('getMethodAnnotations')->willReturn([ + $queryParam, + ]); + + $fosRestDescriber = new FosRestDescriber($readerMock, []); + $api = new OpenApi([]); + + $fosRestDescriber->describe( + $api, + new Route('/'), + $this->createMock(\ReflectionMethod::class) + ); + + self::assertEquals('array', $api->paths[0]->get->parameters[0]->schema->type); + self::assertSame($choices, $api->paths[0]->get->parameters[0]->schema->items->enum); } }