Skip to content

Commit 1280103

Browse files
fix(jsonschema): add test case for resource with iterable union type property schema generation
1 parent bf5c89f commit 1280103

File tree

3 files changed

+80
-0
lines changed

3 files changed

+80
-0
lines changed

src/JsonSchema/SchemaFactory.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@
3535
use Symfony\Component\TypeInfo\TypeIdentifier;
3636

3737
/**
38+
* {@inheritdoc}
39+
*
3840
* @author Kévin Dunglas <[email protected]>
3941
*/
4042
final class SchemaFactory implements SchemaFactoryInterface, SchemaFactoryAwareInterface
@@ -56,6 +58,9 @@ public function __construct(ResourceMetadataCollectionFactoryInterface $resource
5658
$this->resourceClassResolver = $resourceClassResolver;
5759
}
5860

61+
/**
62+
* {@inheritdoc}
63+
*/
5964
public function buildSchema(string $className, string $format = 'json', string $type = Schema::TYPE_OUTPUT, ?Operation $operation = null, ?Schema $schema = null, ?array $serializerContext = null, bool $forceCollection = false): Schema
6065
{
6166
$schema = $schema ? clone $schema : new Schema();
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the API Platform project.
5+
*
6+
* (c) Kévin Dunglas <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
declare(strict_types=1);
13+
14+
namespace ApiPlatform\Tests\Fixtures\TestBundle\ApiResource;
15+
16+
use ApiPlatform\Metadata\ApiProperty;
17+
use ApiPlatform\Metadata\ApiResource;
18+
use ApiPlatform\Tests\Fixtures\TestBundle\Dto\NonResourceClass;
19+
use Symfony\Component\TypeInfo\Type\BuiltinType;
20+
use Symfony\Component\TypeInfo\Type\CollectionType;
21+
use Symfony\Component\TypeInfo\Type\GenericType;
22+
use Symfony\Component\TypeInfo\Type\ObjectType;
23+
use Symfony\Component\TypeInfo\Type\UnionType;
24+
use Symfony\Component\TypeInfo\TypeIdentifier;
25+
26+
#[ApiResource]
27+
final class ResourceWithIterableUnionProperty
28+
{
29+
/**
30+
* @param array<int, Species|NonResourceClass|string|int> $unionItems
31+
*/
32+
public function __construct(
33+
public int $id,
34+
#[ApiProperty(
35+
nativeType: new CollectionType(
36+
new GenericType(
37+
new BuiltinType(TypeIdentifier::ARRAY),
38+
new BuiltinType(TypeIdentifier::INT),
39+
new UnionType(
40+
new ObjectType(Species::class),
41+
new ObjectType(NonResourceClass::class),
42+
new BuiltinType(TypeIdentifier::INT),
43+
new BuiltinType(TypeIdentifier::STRING),
44+
),
45+
),
46+
true,
47+
),
48+
)]
49+
public array $unionItems = [],
50+
) {
51+
}
52+
}

tests/Functional/JsonSchema/JsonSchemaTest.php

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
use ApiPlatform\Tests\Fixtures\TestBundle\ApiResource\Issue5501\Related;
2525
use ApiPlatform\Tests\Fixtures\TestBundle\ApiResource\Product;
2626
use ApiPlatform\Tests\Fixtures\TestBundle\ApiResource\ResourceWithEnumProperty;
27+
use ApiPlatform\Tests\Fixtures\TestBundle\ApiResource\ResourceWithIterableUnionProperty;
2728
use ApiPlatform\Tests\Fixtures\TestBundle\Entity\Issue5793\BagOfTests;
2829
use ApiPlatform\Tests\Fixtures\TestBundle\Entity\Issue5793\TestEntity;
2930
use ApiPlatform\Tests\Fixtures\TestBundle\Entity\Issue6212\Nest;
@@ -66,6 +67,7 @@ public static function getResources(): array
6667
JsonSchemaResourceRelated::class,
6768
Product::class,
6869
AggregateRating::class,
70+
ResourceWithIterableUnionProperty::class,
6971
];
7072
}
7173

@@ -223,4 +225,25 @@ public function testGenIdFalse()
223225
$schema = $this->schemaFactory->buildSchema(Product::class, 'jsonld', Schema::TYPE_OUTPUT, $this->operationMetadataFactory->create('_api_/json-stream-products_get_collection'));
224226
$this->assertThat(['member' => [['aggregateRating' => ['ratingValue' => '1.0', 'reviewCount' => 1]]]], new MatchesJsonSchema($schema));
225227
}
228+
229+
public function testIterableUnionItemsSchema(): void
230+
{
231+
$schema = $this->schemaFactory->buildSchema(ResourceWithIterableUnionProperty::class, 'json', Schema::TYPE_OUTPUT);
232+
$definition = $schema['definitions']['ResourceWithIterableUnionProperty'];
233+
234+
$this->assertArrayHasKey('properties', $definition);
235+
$this->assertArrayHasKey('unionItems', $definition['properties']);
236+
237+
$propertySchema = $definition['properties']['unionItems'];
238+
$this->assertSame('array', $propertySchema['type'] ?? null, 'Iterable union properties should map to array items.');
239+
240+
$itemsSchema = $propertySchema['items'] ?? null;
241+
$this->assertIsArray($itemsSchema);
242+
$this->assertArrayHasKey('anyOf', $itemsSchema);
243+
$unionSchemas = $itemsSchema['anyOf'];
244+
$this->assertContains(['$ref' => '#/definitions/Species'], $unionSchemas);
245+
$this->assertContains(['$ref' => '#/definitions/NonResourceClass'], $unionSchemas);
246+
$this->assertContains(['type' => 'string'], $unionSchemas);
247+
$this->assertContains(['type' => 'integer'], $unionSchemas);
248+
}
226249
}

0 commit comments

Comments
 (0)