From a6f25da106eebf6ef93ecb1270f545ef3846ba44 Mon Sep 17 00:00:00 2001 From: Guilhem Niot Date: Fri, 10 Jun 2022 22:41:24 +0200 Subject: [PATCH] Detect when a model is used for a form type (#1834) * Detect when a model is used for a form type * typo * Add a test + Fix implementation * CS --- ModelDescriber/FormModelDescriber.php | 8 ++++- .../Functional/Controller/ApiController80.php | 13 ++++++++ Tests/Functional/Form/FormWithModel.php | 32 +++++++++++++++++++ Tests/Functional/FunctionalTest.php | 11 +++++++ 4 files changed, 63 insertions(+), 1 deletion(-) create mode 100644 Tests/Functional/Form/FormWithModel.php diff --git a/ModelDescriber/FormModelDescriber.php b/ModelDescriber/FormModelDescriber.php index 4a0e511..0928aec 100644 --- a/ModelDescriber/FormModelDescriber.php +++ b/ModelDescriber/FormModelDescriber.php @@ -16,7 +16,9 @@ use Nelmio\ApiDocBundle\Describer\ModelRegistryAwareInterface; use Nelmio\ApiDocBundle\Describer\ModelRegistryAwareTrait; use Nelmio\ApiDocBundle\Model\Model; use Nelmio\ApiDocBundle\ModelDescriber\Annotations\AnnotationsReader; +use Nelmio\ApiDocBundle\OpenApiPhp\ModelRegister; use Nelmio\ApiDocBundle\OpenApiPhp\Util; +use OpenApi\Analysis; use OpenApi\Annotations as OA; use OpenApi\Generator; use Symfony\Component\Form\AbstractType; @@ -103,9 +105,13 @@ final class FormModelDescriber implements ModelDescriberInterface, ModelRegistry if ($config->hasOption('documentation')) { $property->mergeProperties($config->getOption('documentation')); + + // Parse inner @Model annotations + $modelRegister = new ModelRegister($this->modelRegistry, $this->mediaTypes); + $modelRegister->__invoke(new Analysis([$property], Util::createContext())); } - if (Generator::UNDEFINED !== $property->type) { + if (Generator::UNDEFINED !== $property->type || Generator::UNDEFINED !== $property->ref) { continue; // Type manually defined } diff --git a/Tests/Functional/Controller/ApiController80.php b/Tests/Functional/Controller/ApiController80.php index 3d74a53..bb7031c 100644 --- a/Tests/Functional/Controller/ApiController80.php +++ b/Tests/Functional/Controller/ApiController80.php @@ -25,6 +25,7 @@ use Nelmio\ApiDocBundle\Tests\Functional\Entity\SymfonyDiscriminator; use Nelmio\ApiDocBundle\Tests\Functional\Entity\User; use Nelmio\ApiDocBundle\Tests\Functional\Form\DummyType; use Nelmio\ApiDocBundle\Tests\Functional\Form\FormWithAlternateSchemaType; +use Nelmio\ApiDocBundle\Tests\Functional\Form\FormWithModel; use Nelmio\ApiDocBundle\Tests\Functional\Form\FormWithRefType; use Nelmio\ApiDocBundle\Tests\Functional\Form\UserType; use OpenApi\Annotations as OA; @@ -158,6 +159,18 @@ class ApiController80 { } + /** + * @Route("/form-model", methods={"POST"}) + * @OA\RequestBody( + * description="Request content", + * @Model(type=FormWithModel::class)) + * ) + * @OA\Response(response="201", description="") + */ + public function formWithModelAction() + { + } + /** * @Route("/security") * @OA\Response(response="201", description="") diff --git a/Tests/Functional/Form/FormWithModel.php b/Tests/Functional/Form/FormWithModel.php new file mode 100644 index 0000000..ecf0291 --- /dev/null +++ b/Tests/Functional/Form/FormWithModel.php @@ -0,0 +1,32 @@ +add('quz', TextType::class, ['documentation' => ['ref' => new Model(['type' => User::class])]]); + } + + public function configureOptions(OptionsResolver $resolver) + { + } +} diff --git a/Tests/Functional/FunctionalTest.php b/Tests/Functional/FunctionalTest.php index 617a98d..587780b 100644 --- a/Tests/Functional/FunctionalTest.php +++ b/Tests/Functional/FunctionalTest.php @@ -343,6 +343,17 @@ class FunctionalTest extends WebTestCase 'required' => ['foo', 'foz', 'password'], 'schema' => 'DummyType', ], json_decode($this->getModel('DummyType')->toJson(), true)); + + $this->assertEquals([ + 'type' => 'object', + 'properties' => [ + 'quz' => [ + '$ref' => '#/components/schemas/User', + ], + ], + 'required' => ['quz'], + 'schema' => 'FormWithModel', + ], json_decode($this->getModel('FormWithModel')->toJson(), true)); } /**