From a1141bb0de48a49f9f2817e6fb37df3d8793c8ad Mon Sep 17 00:00:00 2001 From: Benjamin ROTHAN Date: Tue, 4 Jun 2024 00:03:50 +0200 Subject: [PATCH] fix(metadata): wrong schema generated if openapicontext set on array --- .../Factory/SchemaPropertyMetadataFactory.php | 3 +- .../DummyWithCustomOpenApiContext.php | 33 +++++++++++++++++++ .../SchemaPropertyMetadataFactoryTest.php | 15 +++++++++ 3 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 src/JsonSchema/Tests/Fixtures/DummyWithCustomOpenApiContext.php diff --git a/src/JsonSchema/Metadata/Property/Factory/SchemaPropertyMetadataFactory.php b/src/JsonSchema/Metadata/Property/Factory/SchemaPropertyMetadataFactory.php index 087de10f6f1..d3b55e357a7 100644 --- a/src/JsonSchema/Metadata/Property/Factory/SchemaPropertyMetadataFactory.php +++ b/src/JsonSchema/Metadata/Property/Factory/SchemaPropertyMetadataFactory.php @@ -100,9 +100,10 @@ public function create(string $resourceClass, string $property, array $options = $propertySchema['example'] = $propertySchema['default']; } - // never override the following keys if at least one is already set + // never override the following keys if at least one is already set or if there's a custom openapi context if ([] === $types || ($propertySchema['type'] ?? $propertySchema['$ref'] ?? $propertySchema['anyOf'] ?? $propertySchema['allOf'] ?? $propertySchema['oneOf'] ?? false) + || ($propertyMetadata->getOpenapiContext() ?? false) ) { return $propertyMetadata->withSchema($propertySchema); } diff --git a/src/JsonSchema/Tests/Fixtures/DummyWithCustomOpenApiContext.php b/src/JsonSchema/Tests/Fixtures/DummyWithCustomOpenApiContext.php new file mode 100644 index 00000000000..ff15a72bfa7 --- /dev/null +++ b/src/JsonSchema/Tests/Fixtures/DummyWithCustomOpenApiContext.php @@ -0,0 +1,33 @@ + + * + * 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\JsonSchema\Tests\Fixtures; + +use ApiPlatform\Metadata\ApiProperty; +use ApiPlatform\Metadata\ApiResource; + +/* + * This file is part of the API Platform project. + * + * (c) Kévin Dunglas + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#[ApiResource] +class DummyWithCustomOpenApiContext +{ + #[ApiProperty(openapicontext: ['type' => 'object', 'properties' => ['alpha' => ['type' => 'integer']]])] + public $acme; +} diff --git a/src/JsonSchema/Tests/Metadata/Property/Factory/SchemaPropertyMetadataFactoryTest.php b/src/JsonSchema/Tests/Metadata/Property/Factory/SchemaPropertyMetadataFactoryTest.php index 03353150ad8..ec0817014db 100644 --- a/src/JsonSchema/Tests/Metadata/Property/Factory/SchemaPropertyMetadataFactoryTest.php +++ b/src/JsonSchema/Tests/Metadata/Property/Factory/SchemaPropertyMetadataFactoryTest.php @@ -14,6 +14,7 @@ namespace ApiPlatform\JsonSchema\Tests\Metadata\Property\Factory; use ApiPlatform\JsonSchema\Metadata\Property\Factory\SchemaPropertyMetadataFactory; +use ApiPlatform\JsonSchema\Tests\Fixtures\DummyWithCustomOpenApiContext; use ApiPlatform\JsonSchema\Tests\Fixtures\DummyWithEnum; use ApiPlatform\JsonSchema\Tests\Fixtures\Enum\IntEnumAsIdentifier; use ApiPlatform\Metadata\ApiProperty; @@ -34,4 +35,18 @@ public function testEnum(): void $apiProperty = $schemaPropertyMetadataFactory->create(DummyWithEnum::class, 'intEnumAsIdentifier'); $this->assertEquals(['type' => ['integer', 'null'], 'enum' => [1, 2, null]], $apiProperty->getSchema()); } + + public function testWithCustomOpenApiContext(): void + { + $resourceClassResolver = $this->createMock(ResourceClassResolverInterface::class); + $apiProperty = new ApiProperty( + builtinTypes: [new Type(builtinType: 'object', nullable: true, class: IntEnumAsIdentifier::class)], + openapiContext: ['type' => 'object', 'properties' => ['alpha' => ['type' => 'integer']]], + ); + $decorated = $this->createMock(PropertyMetadataFactoryInterface::class); + $decorated->expects($this->once())->method('create')->with(DummyWithCustomOpenApiContext::class, 'acme')->willReturn($apiProperty); + $schemaPropertyMetadataFactory = new SchemaPropertyMetadataFactory($resourceClassResolver, $decorated); + $apiProperty = $schemaPropertyMetadataFactory->create(DummyWithCustomOpenApiContext::class, 'acme'); + $this->assertEquals([], $apiProperty->getSchema()); + } }