From 1f998988dc8a40c18b32c7c894338003e78817c3 Mon Sep 17 00:00:00 2001 From: Vadym Borodavko Date: Fri, 5 Jan 2024 17:36:42 +0200 Subject: [PATCH] Add jms/serializer enum support (#2078) --- ModelDescriber/JMSModelDescriber.php | 9 +++++ .../Functional/Controller/JMSController81.php | 11 ++++++ Tests/Functional/JMSFunctionalTest.php | 34 +++++++++++++++++++ Tests/Functional/TestKernel.php | 6 ++++ phpunit-baseline.json | 15 ++++++++ 5 files changed, 75 insertions(+) diff --git a/ModelDescriber/JMSModelDescriber.php b/ModelDescriber/JMSModelDescriber.php index e88afc437..87e985ba3 100644 --- a/ModelDescriber/JMSModelDescriber.php +++ b/ModelDescriber/JMSModelDescriber.php @@ -285,6 +285,15 @@ public function describeItem(array $type, OA\Schema $property, Context $context) $property->type = 'string'; $property->format = 'date-time'; } else { + // See https://github.com/schmittjoh/serializer/blob/5a5a03a/src/Metadata/Driver/EnumPropertiesDriver.php#L51 + if ('enum' === $type['name'] + && isset($type['params'][0]) + && function_exists('enum_exists') + && enum_exists($type['params'][0]) + ) { + $type = ['name' => $type['params'][0]]; + } + $groups = $this->computeGroups($context, $type); $model = new Model(new Type(Type::BUILTIN_TYPE_OBJECT, false, $type['name']), $groups); diff --git a/Tests/Functional/Controller/JMSController81.php b/Tests/Functional/Controller/JMSController81.php index d875d1d57..6b0a81741 100644 --- a/Tests/Functional/Controller/JMSController81.php +++ b/Tests/Functional/Controller/JMSController81.php @@ -12,6 +12,7 @@ namespace Nelmio\ApiDocBundle\Tests\Functional\Controller; use Nelmio\ApiDocBundle\Annotation\Model; +use Nelmio\ApiDocBundle\Tests\Functional\Entity\Article81; use Nelmio\ApiDocBundle\Tests\Functional\Entity\JMSComplex81; use Nelmio\ApiDocBundle\Tests\Functional\Entity\JMSDualComplex; use Nelmio\ApiDocBundle\Tests\Functional\Entity\JMSNamingStrategyConstraints; @@ -119,4 +120,14 @@ public function minUserAction() public function minUserNestedAction() { } + + #[Route('/api/jms_enum', methods: ['GET'])] + #[OA\Response( + response: 200, + description: 'Success', + content: new Model(type: Article81::class)) + ] + public function enum() + { + } } diff --git a/Tests/Functional/JMSFunctionalTest.php b/Tests/Functional/JMSFunctionalTest.php index 306dfb8d8..5188ef097 100644 --- a/Tests/Functional/JMSFunctionalTest.php +++ b/Tests/Functional/JMSFunctionalTest.php @@ -335,6 +335,40 @@ public function testNamingStrategyWithConstraints() ], json_decode($this->getModel('JMSNamingStrategyConstraints')->toJson(), true)); } + /** + * @requires PHP >= 8.1 + */ + public function testEnumSupport() + { + $this->assertEquals([ + 'type' => 'object', + 'properties' => [ + 'id' => [ + 'type' => 'integer', + ], + 'type' => [ + '$ref' => '#/components/schemas/ArticleType81', + ], + 'int_backed_type' => [ + '$ref' => '#/components/schemas/ArticleType81IntBacked', + ], + 'not_backed_type' => [ + '$ref' => '#/components/schemas/ArticleType81NotBacked', + ], + ], + 'schema' => 'Article81', + ], json_decode($this->getModel('Article81')->toJson(), true)); + + $this->assertEquals([ + 'schema' => 'ArticleType81', + 'type' => 'string', + 'enum' => [ + 'draft', + 'final', + ], + ], json_decode($this->getModel('ArticleType81')->toJson(), true)); + } + protected static function createKernel(array $options = []): KernelInterface { return new TestKernel(TestKernel::USE_JMS); diff --git a/Tests/Functional/TestKernel.php b/Tests/Functional/TestKernel.php index f90cb8298..24742b14a 100644 --- a/Tests/Functional/TestKernel.php +++ b/Tests/Functional/TestKernel.php @@ -348,6 +348,12 @@ protected function configureContainer(ContainerBuilder $c, LoaderInterface $load ], ]); + if ($this->flags & self::USE_JMS && \PHP_VERSION_ID >= 80100) { + $c->loadFromExtension('jms_serializer', [ + 'enum_support' => true, + ]); + } + $def = new Definition(VirtualTypeClassDoesNotExistsHandlerDefinedDescriber::class); $def->addTag('nelmio_api_doc.model_describer'); $c->setDefinition('nelmio.test.jms.virtual_type.describer', $def); diff --git a/phpunit-baseline.json b/phpunit-baseline.json index f999c7fc4..1e3f7cec8 100644 --- a/phpunit-baseline.json +++ b/phpunit-baseline.json @@ -6799,6 +6799,21 @@ "message": "Since sensio/framework-extra-bundle 5.2: The \"sensio_framework_extra.routing.loader.annot_file\" service is deprecated since version 5.2", "count": 1 }, + { + "location": "Nelmio\\ApiDocBundle\\Tests\\Functional\\JMSFunctionalTest::testEnumSupport", + "message": "Since sensio/framework-extra-bundle 5.2: The \"sensio_framework_extra.routing.loader.annot_class\" service is deprecated since version 5.2", + "count": 1 + }, + { + "location": "Nelmio\\ApiDocBundle\\Tests\\Functional\\JMSFunctionalTest::testEnumSupport", + "message": "Since sensio/framework-extra-bundle 5.2: The \"sensio_framework_extra.routing.loader.annot_dir\" service is deprecated since version 5.2", + "count": 1 + }, + { + "location": "Nelmio\\ApiDocBundle\\Tests\\Functional\\JMSFunctionalTest::testEnumSupport", + "message": "Since sensio/framework-extra-bundle 5.2: The \"sensio_framework_extra.routing.loader.annot_file\" service is deprecated since version 5.2", + "count": 1 + }, { "location": "Nelmio\\ApiDocBundle\\Tests\\Functional\\SwaggerPHPApiComplianceTest::testAllContextsCopyRoot", "message": "Since sensio/framework-extra-bundle 5.2: The \"sensio_framework_extra.routing.loader.annot_class\" service is deprecated since version 5.2",