diff --git a/src/JsonApi/JsonSchema/SchemaFactory.php b/src/JsonApi/JsonSchema/SchemaFactory.php index 6042dee5c7..71805d09fe 100644 --- a/src/JsonApi/JsonSchema/SchemaFactory.php +++ b/src/JsonApi/JsonSchema/SchemaFactory.php @@ -145,6 +145,7 @@ public function buildSchema(string $className, string $format = 'jsonapi', strin $properties = $definitions[$definitionName]['properties'] ?? []; if (Error::class === $className && !isset($properties['errors'])) { + $definitions[$definitionName]['type'] = 'object'; $definitions[$definitionName]['properties'] = [ 'errors' => [ 'type' => 'array', @@ -163,6 +164,7 @@ public function buildSchema(string $className, string $format = 'jsonapi', strin } if (!$collectionKey) { + $definitions[$definitionName]['type'] = 'object'; $definitions[$definitionName]['properties'] = $this->buildDefinitionPropertiesSchema($key, $definitionName, $inputOrOutputClass, $format, $type, $operation, $schema, []); $schema['$ref'] = $prefix.$definitionName; diff --git a/src/JsonApi/Tests/JsonSchema/SchemaFactoryTest.php b/src/JsonApi/Tests/JsonSchema/SchemaFactoryTest.php index b93add1228..64f4601313 100644 --- a/src/JsonApi/Tests/JsonSchema/SchemaFactoryTest.php +++ b/src/JsonApi/Tests/JsonSchema/SchemaFactoryTest.php @@ -35,6 +35,7 @@ use ApiPlatform\Metadata\Resource\Factory\ResourceMetadataCollectionFactoryInterface; use ApiPlatform\Metadata\Resource\ResourceMetadataCollection; use ApiPlatform\Metadata\ResourceClassResolverInterface; +use ApiPlatform\State\ApiResource\Error; use PHPUnit\Framework\TestCase; use Prophecy\Argument; use Prophecy\PhpUnit\ProphecyTrait; @@ -56,9 +57,17 @@ protected function setUp(): void ])), ]) ); + $resourceMetadataFactory->create(Error::class)->willReturn( + new ResourceMetadataCollection(Error::class, [ + (new ApiResource())->withOperations(new Operations([ + 'get' => (new Get())->withClass(Error::class)->withName('get'), + ])), + ]) + ); $propertyNameCollectionFactory = $this->prophesize(PropertyNameCollectionFactoryInterface::class); $propertyNameCollectionFactory->create(Dummy::class, ['enable_getter_setter_extraction' => true, 'schema_type' => Schema::TYPE_OUTPUT])->willReturn(new PropertyNameCollection()); $propertyNameCollectionFactory->create(Dummy::class, ['enable_getter_setter_extraction' => true, 'schema_type' => Schema::TYPE_INPUT])->willReturn(new PropertyNameCollection()); + $propertyNameCollectionFactory->create(Error::class, ['enable_getter_setter_extraction' => true, 'schema_type' => Schema::TYPE_OUTPUT])->willReturn(new PropertyNameCollection()); $propertyMetadataFactory = $this->prophesize(PropertyMetadataFactoryInterface::class); $definitionNameFactory = new DefinitionNameFactory(); @@ -72,6 +81,7 @@ protected function setUp(): void $resourceClassResolver = $this->prophesize(ResourceClassResolverInterface::class); $resourceClassResolver->isResourceClass(Dummy::class)->willReturn(true); + $resourceClassResolver->isResourceClass(Error::class)->willReturn(true); $this->schemaFactory = new SchemaFactory( schemaFactory: $baseSchemaFactory, @@ -105,6 +115,7 @@ public function testHasRootDefinitionKeyBuildSchema(): void $rootDefinitionKey = $resultSchema->getRootDefinitionKey(); $this->assertTrue(isset($definitions[$rootDefinitionKey])); + $this->assertSame('object', $definitions[$rootDefinitionKey]['type']); $this->assertTrue(isset($definitions[$rootDefinitionKey]['properties'])); $properties = $resultSchema['definitions'][$rootDefinitionKey]['properties']; $this->assertSame(['$ref' => '#/definitions/'.$rootDefinitionKey.'.resource'], $properties['data']); @@ -190,12 +201,22 @@ public function testPostInputSchemaDoesNotRequireId(): void $definitions = $resultSchema->getDefinitions(); $rootDefinitionKey = $resultSchema->getRootDefinitionKey(); + $this->assertSame('object', $definitions[$rootDefinitionKey]['type']); $this->assertSame(['$ref' => '#/definitions/'.$rootDefinitionKey.'.resource'], $definitions[$rootDefinitionKey]['properties']['data']); $data = $definitions[$rootDefinitionKey.'.resource']; $this->assertArrayHasKey('required', $data); $this->assertSame(['type'], $data['required']); } + public function testErrorSchemaIsAnObject(): void + { + $operation = (new Get())->withClass(Error::class)->withName('get')->withShortName('Error'); + $resultSchema = $this->schemaFactory->buildSchema(Error::class, 'jsonapi', Schema::TYPE_OUTPUT, $operation); + $definitions = $resultSchema->getDefinitions(); + + $this->assertSame('object', $definitions[$resultSchema->getRootDefinitionKey()]['type']); + } + public function testPatchInputSchemaRequiresId(): void { $resultSchema = $this->schemaFactory->buildSchema(Dummy::class, 'jsonapi', Schema::TYPE_INPUT, new Patch());