Skip to content

Commit

Permalink
fix: ensure OpenAPI-specific implementation for nullable types does n…
Browse files Browse the repository at this point in the history
…ot influence the other ones
  • Loading branch information
Jérôme Deuchnord committed Apr 21, 2022
1 parent 39b4e43 commit 7301f27
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 17 deletions.
14 changes: 10 additions & 4 deletions src/JsonSchema/TypeFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -169,10 +169,16 @@ private function addNullabilityToTypeDefinition(array $jsonSchema, Type $type, ?
}

if (\array_key_exists('$ref', $jsonSchema)) {
return [
'nullable' => true,
'anyOf' => [$jsonSchema],
];
$typeDefinition = ['anyOf' => [$jsonSchema]];

if ($schema && Schema::VERSION_JSON_SCHEMA === $schema->getVersion()) {
$typeDefinition['anyOf'][] = ['type' => 'null'];
} else {
// OpenAPI < 3.1
$typeDefinition['nullable'] = true;
}

return $typeDefinition;
}

if ($schema && Schema::VERSION_JSON_SCHEMA === $schema->getVersion()) {
Expand Down
57 changes: 44 additions & 13 deletions tests/JsonSchema/TypeFactoryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -387,29 +387,60 @@ public function testGetClassType(): void
$this->assertSame(['$ref' => 'ref'], $typeFactory->getType(new Type(Type::BUILTIN_TYPE_OBJECT, false, Dummy::class), 'jsonld', true, ['foo' => 'bar'], new Schema()));
}

public function testGetClassTypeWithNullability(): void
/** @dataProvider classTypeWithNullabilityDataProvider */
public function testGetClassTypeWithNullability(array $expected, SchemaFactoryInterface $schemaFactory, Schema $schema): void
{
$typeFactory = new TypeFactory();
$typeFactory->setSchemaFactory($schemaFactory);

self::assertSame(
$expected,
$typeFactory->getType(new Type(Type::BUILTIN_TYPE_OBJECT, true, Dummy::class), 'jsonld', true, ['foo' => 'bar'], $schema)
);
}

public function classTypeWithNullabilityDataProvider(): iterable
{
$schemaFactory = $this->createSchemaFactoryMock($schema = new Schema());

yield 'JSON-Schema version' => [
[
'anyOf' => [
['$ref' => 'the-ref-name'],
['type' => 'null'],
],
],
$schemaFactory,
$schema,
];

$schemaFactory = $this->createSchemaFactoryMock($schema = new Schema(Schema::VERSION_OPENAPI));

yield 'OpenAPI < 3.1 version' => [
[
'anyOf' => [
['$ref' => 'the-ref-name'],
],
'nullable' => true,
],
$schemaFactory,
$schema,
];
}

private function createSchemaFactoryMock(Schema $schema): SchemaFactoryInterface
{
$schemaFactory = $this->createMock(SchemaFactoryInterface::class);

$schemaFactory
->method('buildSchema')
->willReturnCallback(static function (): Schema {
$schema = new Schema();

->willReturnCallback(static function () use ($schema): Schema {
$schema['$ref'] = 'the-ref-name';
$schema['description'] = 'more stuff here';

return $schema;
});

$typeFactory = new TypeFactory();
$typeFactory->setSchemaFactory($schemaFactory);

self::assertSame([
'nullable' => true,
'anyOf' => [
['$ref' => 'the-ref-name'],
],
], $typeFactory->getType(new Type(Type::BUILTIN_TYPE_OBJECT, true, Dummy::class), 'jsonld', true, ['foo' => 'bar'], new Schema()));
return $schemaFactory;
}
}

0 comments on commit 7301f27

Please sign in to comment.