From 85c501f727eca99150c6ec0eb4a31c9abf301965 Mon Sep 17 00:00:00 2001 From: Gwendolen Lynch Date: Wed, 10 Apr 2024 12:55:24 +0200 Subject: [PATCH] fix(jsonschema): don't try to define $ref if set in attributes --- src/JsonSchema/SchemaFactory.php | 5 +++ .../ApiResource/Issue6299/Issue6299.php | 23 +++++++++++ .../Issue6299/Issue6299CollectionDto.php | 19 +++++++++ .../Issue6299/Issue6299ItemDto.php | 19 +++++++++ .../Issue6299/Issue6299OutputDto.php | 39 +++++++++++++++++++ .../Command/JsonSchemaGenerateCommandTest.php | 13 +++++++ 6 files changed, 118 insertions(+) create mode 100644 tests/Fixtures/TestBundle/ApiResource/Issue6299/Issue6299.php create mode 100644 tests/Fixtures/TestBundle/ApiResource/Issue6299/Issue6299CollectionDto.php create mode 100644 tests/Fixtures/TestBundle/ApiResource/Issue6299/Issue6299ItemDto.php create mode 100644 tests/Fixtures/TestBundle/ApiResource/Issue6299/Issue6299OutputDto.php diff --git a/src/JsonSchema/SchemaFactory.php b/src/JsonSchema/SchemaFactory.php index 0b40d42036c..901660a79dc 100644 --- a/src/JsonSchema/SchemaFactory.php +++ b/src/JsonSchema/SchemaFactory.php @@ -150,6 +150,11 @@ private function buildPropertySchema(Schema $schema, string $definitionName, str $additionalPropertySchema ?? [] ); + // @see https://github.com/api-platform/core/issues/6299 + if (Schema::UNKNOWN_TYPE === ($propertySchema['type'] ?? null) && isset($propertySchema['$ref'])) { + unset($propertySchema['type']); + } + $extraProperties = $propertyMetadata->getExtraProperties() ?? []; // see AttributePropertyMetadataFactory if (true === ($extraProperties[SchemaPropertyMetadataFactory::JSON_SCHEMA_USER_DEFINED] ?? false)) { diff --git a/tests/Fixtures/TestBundle/ApiResource/Issue6299/Issue6299.php b/tests/Fixtures/TestBundle/ApiResource/Issue6299/Issue6299.php new file mode 100644 index 00000000000..35c4f08dbd5 --- /dev/null +++ b/tests/Fixtures/TestBundle/ApiResource/Issue6299/Issue6299.php @@ -0,0 +1,23 @@ + + * + * 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\Issue6299; + +use ApiPlatform\Metadata\ApiResource; +use ApiPlatform\Metadata\Get; + +#[ApiResource] +#[Get(output: Issue6299OutputDto::class)] +final class Issue6299 +{ +} diff --git a/tests/Fixtures/TestBundle/ApiResource/Issue6299/Issue6299CollectionDto.php b/tests/Fixtures/TestBundle/ApiResource/Issue6299/Issue6299CollectionDto.php new file mode 100644 index 00000000000..5e9791d11a3 --- /dev/null +++ b/tests/Fixtures/TestBundle/ApiResource/Issue6299/Issue6299CollectionDto.php @@ -0,0 +1,19 @@ + + * + * 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\Issue6299; + +final class Issue6299CollectionDto +{ + public string $name; +} diff --git a/tests/Fixtures/TestBundle/ApiResource/Issue6299/Issue6299ItemDto.php b/tests/Fixtures/TestBundle/ApiResource/Issue6299/Issue6299ItemDto.php new file mode 100644 index 00000000000..4f06aaca373 --- /dev/null +++ b/tests/Fixtures/TestBundle/ApiResource/Issue6299/Issue6299ItemDto.php @@ -0,0 +1,19 @@ + + * + * 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\Issue6299; + +final class Issue6299ItemDto +{ + public string $name; +} diff --git a/tests/Fixtures/TestBundle/ApiResource/Issue6299/Issue6299OutputDto.php b/tests/Fixtures/TestBundle/ApiResource/Issue6299/Issue6299OutputDto.php new file mode 100644 index 00000000000..51687855872 --- /dev/null +++ b/tests/Fixtures/TestBundle/ApiResource/Issue6299/Issue6299OutputDto.php @@ -0,0 +1,39 @@ + + * + * 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\Issue6299; + +use ApiPlatform\Metadata\ApiProperty; +use Symfony\Component\Serializer\Attribute\Groups; + +final class Issue6299OutputDto +{ + #[ApiProperty( + openapiContext: ['$ref' => '#/components/schemas/DummyFriend'], + jsonSchemaContext: ['$ref' => '#/definitions/DummyFriend'], + )] + #[Groups(['v1.read', 'v2.read'])] + public Issue6299ItemDto $itemDto; + + #[ApiProperty( + openapiContext: [ + 'items' => ['$ref' => '#/components/schemas/DummyDate'], + ], + jsonSchemaContext: [ + 'items' => ['$ref' => '#/definitions/DummyDate'], + ], + )] + #[Groups(['v1.read', 'v2.read'])] + /** @var Issue6299CollectionDto[] */ + public array $collectionDto; +} diff --git a/tests/JsonSchema/Command/JsonSchemaGenerateCommandTest.php b/tests/JsonSchema/Command/JsonSchemaGenerateCommandTest.php index 3e4ed9d4843..938eb6fbd53 100644 --- a/tests/JsonSchema/Command/JsonSchemaGenerateCommandTest.php +++ b/tests/JsonSchema/Command/JsonSchemaGenerateCommandTest.php @@ -166,6 +166,19 @@ public function testWritableNonResourceRef(): void $this->assertEquals($json['definitions']['SaveProduct.jsonld']['properties']['codes']['items']['$ref'], '#/definitions/ProductCode.jsonld'); } + /** + * Test issue #6299. + */ + public function testOpenApiResourceRefIsNotOverwritten(): void + { + $this->tester->run(['command' => 'api:json-schema:generate', 'resource' => 'ApiPlatform\Tests\Fixtures\TestBundle\ApiResource\Issue6299\Issue6299', '--type' => 'output']); + $result = $this->tester->getDisplay(); + $json = json_decode($result, associative: true); + + $this->assertEquals('#/definitions/DummyFriend', $json['definitions']['Issue6299.Issue6299OutputDto.jsonld']['properties']['itemDto']['$ref']); + $this->assertEquals('#/definitions/DummyDate', $json['definitions']['Issue6299.Issue6299OutputDto.jsonld']['properties']['collectionDto']['items']['$ref']); + } + /** * Test related Schema keeps json-ld context. */