diff --git a/src/JsonApi/JsonSchema/SchemaFactory.php b/src/JsonApi/JsonSchema/SchemaFactory.php index adf7594219e..e40ff6a2868 100644 --- a/src/JsonApi/JsonSchema/SchemaFactory.php +++ b/src/JsonApi/JsonSchema/SchemaFactory.php @@ -207,6 +207,7 @@ private function buildDefinitionPropertiesSchema(string $key, string $className, 'type' => 'array', 'items' => self::RELATION_PROPS, ]; + continue; } if ('id' === $propertyName) { $attributes['_id'] = $property; diff --git a/tests/Fixtures/TestBundle/ApiResource/Animal.php b/tests/Fixtures/TestBundle/ApiResource/Animal.php new file mode 100644 index 00000000000..6d9d3056db2 --- /dev/null +++ b/tests/Fixtures/TestBundle/ApiResource/Animal.php @@ -0,0 +1,43 @@ + + * + * 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\ApiProperty; +use ApiPlatform\Metadata\ApiResource; + +#[ApiResource] +class Animal +{ + private ?int $id = null; + + #[ApiProperty(required: true)] + private ?Species $species = null; + + public function getId(): ?int + { + return $this->id; + } + + public function getSpecies(): ?Species + { + return $this->species; + } + + public function setSpecies(?Species $species): static + { + $this->species = $species; + + return $this; + } +} diff --git a/tests/Fixtures/TestBundle/ApiResource/AnimalObservation.php b/tests/Fixtures/TestBundle/ApiResource/AnimalObservation.php new file mode 100644 index 00000000000..8c2ce7a4a9d --- /dev/null +++ b/tests/Fixtures/TestBundle/ApiResource/AnimalObservation.php @@ -0,0 +1,60 @@ + + * + * 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\ApiProperty; +use ApiPlatform\Metadata\ApiResource; +use Doctrine\Common\Collections\ArrayCollection; +use Doctrine\Common\Collections\Collection; + +#[ApiResource] +class AnimalObservation +{ + private ?int $id = null; + + #[ApiProperty(required: true)] + private Collection $individuals; + + public function __construct() + { + $this->individuals = new ArrayCollection(); + } + + public function getId(): ?int + { + return $this->id; + } + + /** @return Collection */ + public function getIndividuals(): Collection + { + return $this->individuals; + } + + public function addIndividual(Animal $individual): static + { + if (!$this->individuals->contains($individual)) { + $this->individuals->add($individual); + } + + return $this; + } + + public function removeIndividual(Animal $individual): static + { + $this->individuals->removeElement($individual); + + return $this; + } +} diff --git a/tests/Fixtures/TestBundle/ApiResource/Species.php b/tests/Fixtures/TestBundle/ApiResource/Species.php new file mode 100644 index 00000000000..54a184646e6 --- /dev/null +++ b/tests/Fixtures/TestBundle/ApiResource/Species.php @@ -0,0 +1,38 @@ + + * + * 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\ApiProperty; +use ApiPlatform\Metadata\ApiResource; +use ApiPlatform\Metadata\Get; +use ApiPlatform\Metadata\GetCollection; + +#[ApiResource] +#[GetCollection( + uriTemplate: '/species', +)] +#[Get( + uriTemplate: '/species/{key}', +)] +final class Species +{ + #[ApiProperty(identifier: true)] + public ?int $key = null; + public ?string $kingdom = null; + public ?string $phylum = null; + public ?string $order = null; + public ?string $family = null; + public ?string $genus = null; + public ?string $species = null; +} diff --git a/tests/JsonSchema/Command/JsonSchemaGenerateCommandTest.php b/tests/JsonSchema/Command/JsonSchemaGenerateCommandTest.php index a55ad77d6f5..3ef06851574 100644 --- a/tests/JsonSchema/Command/JsonSchemaGenerateCommandTest.php +++ b/tests/JsonSchema/Command/JsonSchemaGenerateCommandTest.php @@ -228,10 +228,45 @@ public function testJsonApiIncludesSchema(): void $this->tester->run(['command' => 'api:json-schema:generate', 'resource' => 'ApiPlatform\Tests\Fixtures\TestBundle\Entity\Question', '--type' => 'output', '--format' => 'jsonapi']); $result = $this->tester->getDisplay(); $json = json_decode($result, associative: true); + $properties = $json['definitions']['Question.jsonapi']['properties']['data']['properties']; + $included = $json['definitions']['Question.jsonapi']['properties']['included']; - $this->assertArrayHasKey('answer', $json['definitions']['Question.jsonapi']['properties']['data']['properties']['relationships']['properties']); - $this->assertArrayHasKey('anyOf', $json['definitions']['Question.jsonapi']['properties']['included']['items']); - $this->assertArrayHasKey('$ref', $json['definitions']['Question.jsonapi']['properties']['included']['items']['anyOf'][0]); - $this->assertSame('#/definitions/Answer.jsonapi', $json['definitions']['Question.jsonapi']['properties']['included']['items']['anyOf'][0]['$ref']); + $this->assertArrayHasKey('answer', $properties['relationships']['properties']); + $this->assertArrayHasKey('anyOf', $included['items']); + $this->assertCount(1, $included['items']['anyOf']); + $this->assertArrayHasKey('$ref', $included['items']['anyOf'][0]); + $this->assertSame('#/definitions/Answer.jsonapi', $included['items']['anyOf'][0]['$ref']); + + $this->tester->run(['command' => 'api:json-schema:generate', 'resource' => 'ApiPlatform\Tests\Fixtures\TestBundle\ApiResource\AnimalObservation', '--type' => 'output', '--format' => 'jsonapi']); + $result = $this->tester->getDisplay(); + $json = json_decode($result, associative: true); + $properties = $json['definitions']['AnimalObservation.jsonapi']['properties']['data']['properties']; + $included = $json['definitions']['AnimalObservation.jsonapi']['properties']['included']; + + $this->assertArrayHasKey('individuals', $properties['relationships']['properties']); + $this->assertArrayNotHasKey('individuals', $properties['attributes']['properties']); + $this->assertArrayHasKey('anyOf', $included['items']); + $this->assertCount(1, $included['items']['anyOf']); + $this->assertSame('#/definitions/Animal.jsonapi', $included['items']['anyOf'][0]['$ref']); + + $this->tester->run(['command' => 'api:json-schema:generate', 'resource' => 'ApiPlatform\Tests\Fixtures\TestBundle\ApiResource\Animal', '--type' => 'output', '--format' => 'jsonapi']); + $result = $this->tester->getDisplay(); + $json = json_decode($result, associative: true); + $properties = $json['definitions']['Animal.jsonapi']['properties']['data']['properties']; + $included = $json['definitions']['Animal.jsonapi']['properties']['included']; + + $this->assertArrayHasKey('species', $properties['relationships']['properties']); + $this->assertArrayNotHasKey('species', $properties['attributes']['properties']); + $this->assertArrayHasKey('anyOf', $included['items']); + $this->assertCount(1, $included['items']['anyOf']); + $this->assertSame('#/definitions/Species.jsonapi', $included['items']['anyOf'][0]['$ref']); + + $this->tester->run(['command' => 'api:json-schema:generate', 'resource' => 'ApiPlatform\Tests\Fixtures\TestBundle\ApiResource\Species', '--type' => 'output', '--format' => 'jsonapi']); + $result = $this->tester->getDisplay(); + $json = json_decode($result, associative: true); + $properties = $json['definitions']['Species.jsonapi']['properties']['data']['properties']; + + $this->assertArrayHasKey('kingdom', $properties['attributes']['properties']); + $this->assertArrayHasKey('phylum', $properties['attributes']['properties']); } }