From 530311c489c95675e4294221a6e65771e39e882d Mon Sep 17 00:00:00 2001 From: Christopher Davis Date: Wed, 10 Feb 2021 10:33:55 -0600 Subject: [PATCH] Check Min and Max in Length Constraints Before Setting in Schemas Sometimes folks will set a `min` length without a max, for instance and the generated open api schema would previously have been nonsense: ``` "property": { "type":"string", "maxLength":0, "minLength":1 } ``` --- .../SymfonyConstraintAnnotationReader.php | 8 +++- .../SymfonyConstraintAnnotationReaderTest.php | 48 +++++++++++++++++++ 2 files changed, 54 insertions(+), 2 deletions(-) diff --git a/ModelDescriber/Annotations/SymfonyConstraintAnnotationReader.php b/ModelDescriber/Annotations/SymfonyConstraintAnnotationReader.php index dfd10c2..57ec897 100644 --- a/ModelDescriber/Annotations/SymfonyConstraintAnnotationReader.php +++ b/ModelDescriber/Annotations/SymfonyConstraintAnnotationReader.php @@ -69,8 +69,12 @@ class SymfonyConstraintAnnotationReader $this->schema->required = array_values(array_unique($existingRequiredFields)); } elseif ($annotation instanceof Assert\Length) { - $property->minLength = (int) $annotation->min; - $property->maxLength = (int) $annotation->max; + if (isset($annotation->min)) { + $property->minLength = (int) $annotation->min; + } + if (isset($annotation->max)) { + $property->maxLength = (int) $annotation->max; + } } elseif ($annotation instanceof Assert\Regex) { $this->appendPattern($property, $annotation->getHtmlPattern()); } elseif ($annotation instanceof Assert\Count) { diff --git a/Tests/ModelDescriber/Annotations/SymfonyConstraintAnnotationReaderTest.php b/Tests/ModelDescriber/Annotations/SymfonyConstraintAnnotationReaderTest.php index fd1b245..876f75b 100644 --- a/Tests/ModelDescriber/Annotations/SymfonyConstraintAnnotationReaderTest.php +++ b/Tests/ModelDescriber/Annotations/SymfonyConstraintAnnotationReaderTest.php @@ -105,4 +105,52 @@ class SymfonyConstraintAnnotationReaderTest extends TestCase // expect enum to be numeric array with sequential keys (not [1 => "active", 2 => "active"]) $this->assertEquals($schema->properties[0]->enum, ['active', 'blocked']); } + + /** + * @group https://github.com/nelmio/NelmioApiDocBundle/issues/1780 + */ + public function testLengthConstraintDoesNotSetMaxLengthIfMaxIsNotSet() + { + $entity = new class() { + /** + * @Assert\Length(min = 1) + */ + private $property1; + }; + + $schema = new OA\Schema([]); + $schema->merge([new OA\Property(['property' => 'property1'])]); + + $symfonyConstraintAnnotationReader = new SymfonyConstraintAnnotationReader(new AnnotationReader()); + $symfonyConstraintAnnotationReader->setSchema($schema); + + $symfonyConstraintAnnotationReader->updateProperty(new \ReflectionProperty($entity, 'property1'), $schema->properties[0]); + + $this->assertSame(OA\UNDEFINED, $schema->properties[0]->maxLength); + $this->assertSame(1, $schema->properties[0]->minLength); + } + + /** + * @group https://github.com/nelmio/NelmioApiDocBundle/issues/1780 + */ + public function testLengthConstraintDoesNotSetMinLengthIfMinIsNotSet() + { + $entity = new class() { + /** + * @Assert\Length(max = 100) + */ + private $property1; + }; + + $schema = new OA\Schema([]); + $schema->merge([new OA\Property(['property' => 'property1'])]); + + $symfonyConstraintAnnotationReader = new SymfonyConstraintAnnotationReader(new AnnotationReader()); + $symfonyConstraintAnnotationReader->setSchema($schema); + + $symfonyConstraintAnnotationReader->updateProperty(new \ReflectionProperty($entity, 'property1'), $schema->properties[0]); + + $this->assertSame(OA\UNDEFINED, $schema->properties[0]->minLength); + $this->assertSame(100, $schema->properties[0]->maxLength); + } }