From c39e0679dd9bcd40f1390c5a92bd436a1732b88c Mon Sep 17 00:00:00 2001 From: soyuka Date: Thu, 21 May 2026 10:38:08 +0200 Subject: [PATCH] test: cover Assert\Choice exposure in OpenAPI schema Functional ApiTestCase verifies PropertySchemaChoiceRestriction surfaces `enum` (single), `items.enum`, `minItems`, `maxItems` (multi) in /docs output. Existing OpenApiTest only covered PHP backed enums, not Symfony Validator Choice constraint. Closes #1522 --- .../CompanyWithChoiceValidation.php | 44 ++++++++++++++ .../ChoiceValidationOpenApiTest.php | 58 +++++++++++++++++++ 2 files changed, 102 insertions(+) create mode 100644 tests/Fixtures/TestBundle/ApiResource/CompanyWithChoiceValidation.php create mode 100644 tests/Functional/ChoiceValidationOpenApiTest.php diff --git a/tests/Fixtures/TestBundle/ApiResource/CompanyWithChoiceValidation.php b/tests/Fixtures/TestBundle/ApiResource/CompanyWithChoiceValidation.php new file mode 100644 index 0000000000..0b7ec23cc2 --- /dev/null +++ b/tests/Fixtures/TestBundle/ApiResource/CompanyWithChoiceValidation.php @@ -0,0 +1,44 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace ApiPlatform\Tests\Fixtures\TestBundle\ApiResource; + +use ApiPlatform\Metadata\ApiResource; +use ApiPlatform\Metadata\GetCollection; +use Symfony\Component\Validator\Constraints as Assert; + +#[ApiResource(operations: [new GetCollection(provider: [CompanyWithChoiceValidation::class, 'provide'])])] +class CompanyWithChoiceValidation +{ + public ?int $id = null; + + #[Assert\Choice(choices: ['SARL', 'SAS', 'SA'])] + public ?string $companyType = null; + + #[Assert\Choice(callback: [self::class, 'getCompanyTypeChoices'])] + public ?string $companyTypeFromCallback = null; + + /** @var string[] */ + #[Assert\Choice(choices: ['SARL', 'SAS', 'SA'], multiple: true, min: 1, max: 3)] + public array $allowedCompanyTypes = []; + + public static function getCompanyTypeChoices(): array + { + return ['SARL', 'SAS', 'SA', 'EURL']; + } + + public static function provide(): array + { + return []; + } +} diff --git a/tests/Functional/ChoiceValidationOpenApiTest.php b/tests/Functional/ChoiceValidationOpenApiTest.php new file mode 100644 index 0000000000..0dfc9a3e16 --- /dev/null +++ b/tests/Functional/ChoiceValidationOpenApiTest.php @@ -0,0 +1,58 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace ApiPlatform\Tests\Functional; + +use ApiPlatform\Symfony\Bundle\Test\ApiTestCase; +use ApiPlatform\Tests\Fixtures\TestBundle\ApiResource\CompanyWithChoiceValidation; +use ApiPlatform\Tests\SetupClassResourcesTrait; + +/** + * @see https://github.com/api-platform/core/issues/1522 + */ +final class ChoiceValidationOpenApiTest extends ApiTestCase +{ + use SetupClassResourcesTrait; + + protected static ?bool $alwaysBootKernel = false; + + /** + * @return class-string[] + */ + public static function getResources(): array + { + return [CompanyWithChoiceValidation::class]; + } + + public function testChoiceConstraintIsDocumentedInOpenApi(): void + { + $response = self::createClient()->request('GET', '/docs', [ + 'headers' => ['Accept' => 'application/vnd.openapi+json'], + ]); + $this->assertResponseIsSuccessful(); + + $json = $response->toArray(); + $this->assertArrayHasKey('CompanyWithChoiceValidation', $json['components']['schemas']); + + $properties = $json['components']['schemas']['CompanyWithChoiceValidation']['properties']; + + $this->assertSame(['SARL', 'SAS', 'SA'], $properties['companyType']['enum']); + $this->assertSame(['SARL', 'SAS', 'SA', 'EURL'], $properties['companyTypeFromCallback']['enum']); + + $this->assertSame('array', $properties['allowedCompanyTypes']['type']); + $this->assertSame(['SARL', 'SAS', 'SA'], $properties['allowedCompanyTypes']['items']['enum']); + $this->assertSame('string', $properties['allowedCompanyTypes']['items']['type']); + $this->assertSame(1, $properties['allowedCompanyTypes']['minItems']); + $this->assertSame(3, $properties['allowedCompanyTypes']['maxItems']); + } +}