diff --git a/src/JsonSchema/Metadata/Property/Factory/SchemaPropertyMetadataFactory.php b/src/JsonSchema/Metadata/Property/Factory/SchemaPropertyMetadataFactory.php index cf41fbed56e..90f8ddea3fc 100644 --- a/src/JsonSchema/Metadata/Property/Factory/SchemaPropertyMetadataFactory.php +++ b/src/JsonSchema/Metadata/Property/Factory/SchemaPropertyMetadataFactory.php @@ -280,6 +280,7 @@ private function getJsonSchemaFromType(Type $type, ?bool $readableLink = null): TypeIdentifier::OBJECT => ['type' => 'object'], TypeIdentifier::RESOURCE => ['type' => 'string'], TypeIdentifier::CALLABLE => ['type' => 'string'], + TypeIdentifier::MIXED => ['type' => 'string'], default => ['type' => 'null'], }; diff --git a/src/JsonSchema/Tests/Fixtures/DummyWithMixed.php b/src/JsonSchema/Tests/Fixtures/DummyWithMixed.php new file mode 100644 index 00000000000..3703a17d941 --- /dev/null +++ b/src/JsonSchema/Tests/Fixtures/DummyWithMixed.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\JsonSchema\Tests\Fixtures; + +use ApiPlatform\Metadata\ApiResource; + +#[ApiResource] +class DummyWithMixed +{ + public mixed $mixedProperty; + public array $mixedArrayProperty; +} diff --git a/src/JsonSchema/Tests/Metadata/Property/Factory/SchemaPropertyMetadataFactoryTest.php b/src/JsonSchema/Tests/Metadata/Property/Factory/SchemaPropertyMetadataFactoryTest.php index ce930485a04..70b5f81b6b9 100644 --- a/src/JsonSchema/Tests/Metadata/Property/Factory/SchemaPropertyMetadataFactoryTest.php +++ b/src/JsonSchema/Tests/Metadata/Property/Factory/SchemaPropertyMetadataFactoryTest.php @@ -16,6 +16,7 @@ use ApiPlatform\JsonSchema\Metadata\Property\Factory\SchemaPropertyMetadataFactory; use ApiPlatform\JsonSchema\Tests\Fixtures\DummyWithCustomOpenApiContext; use ApiPlatform\JsonSchema\Tests\Fixtures\DummyWithEnum; +use ApiPlatform\JsonSchema\Tests\Fixtures\DummyWithMixed; use ApiPlatform\JsonSchema\Tests\Fixtures\DummyWithUnionTypeProperty; use ApiPlatform\JsonSchema\Tests\Fixtures\Enum\IntEnumAsIdentifier; use ApiPlatform\Metadata\ApiProperty; @@ -167,4 +168,37 @@ public function testUnionTypeAnyOfIsArray(): void $this->assertEquals($expectedSchema, $apiProperty->getSchema()); } + + public function testMixed(): void + { + if (!method_exists(PropertyInfoExtractor::class, 'getType')) { // @phpstan-ignore-line symfony/property-info 6.4 is still allowed and this may be true + $this->markTestSkipped('This test only supports type-info component'); + } + + $resourceClassResolver = $this->createMock(ResourceClassResolverInterface::class); + $apiProperty = new ApiProperty(nativeType: Type::mixed()); + $decorated = $this->createMock(PropertyMetadataFactoryInterface::class); + $decorated->expects($this->once())->method('create')->with(DummyWithMixed::class, 'mixedProperty')->willReturn($apiProperty); + + $schemaPropertyMetadataFactory = new SchemaPropertyMetadataFactory($resourceClassResolver, $decorated); + $apiProperty = $schemaPropertyMetadataFactory->create(DummyWithMixed::class, 'mixedProperty'); + + $this->assertEquals([ + 'type' => ['string', 'null'], + ], $apiProperty->getSchema()); + + $apiProperty = new ApiProperty(nativeType: Type::array(Type::mixed())); + $decorated = $this->createMock(PropertyMetadataFactoryInterface::class); + $decorated->expects($this->once())->method('create')->with(DummyWithMixed::class, 'mixedArrayProperty')->willReturn($apiProperty); + + $schemaPropertyMetadataFactory = new SchemaPropertyMetadataFactory($resourceClassResolver, $decorated); + $apiProperty = $schemaPropertyMetadataFactory->create(DummyWithMixed::class, 'mixedArrayProperty'); + + $this->assertEquals([ + 'type' => 'array', + 'items' => [ + 'type' => ['string', 'null'], + ], + ], $apiProperty->getSchema()); + } }