Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions src/Serializer.php
Original file line number Diff line number Diff line change
Expand Up @@ -74,21 +74,21 @@ protected static function isValidAnnotationClass(string $className): bool
*
* @param class-string<OA\AbstractAnnotation> $className
*/
public function deserialize(string $jsonString, string $className): OA\AbstractAnnotation
public function deserialize(string $jsonString, string $className, ?Context $context = null): OA\AbstractAnnotation
{
if (!static::isValidAnnotationClass($className)) {
throw new OpenApiException($className . ' is not defined in OpenApi PHP Annotations');
}

return $this->doDeserialize(json_decode($jsonString), $className, new Context(['generated' => true]));
return $this->doDeserialize(json_decode($jsonString), $className, $context ?? new Context(['generated' => true]));
}

/**
* Deserialize a file.
*
* @param class-string<OA\AbstractAnnotation> $className
*/
public function deserializeFile(string $filename, string $format = 'json', string $className = OA\OpenApi::class): OA\AbstractAnnotation
public function deserializeFile(string $filename, string $format = 'json', string $className = OA\OpenApi::class, ?Context $context = null): OA\AbstractAnnotation
{
if (!static::isValidAnnotationClass($className)) {
throw new OpenApiException($className . ' is not a valid OpenApi PHP Annotations');
Expand All @@ -101,7 +101,7 @@ public function deserializeFile(string $filename, string $format = 'json', strin
$contents = json_encode(Yaml::parse($contents));
}

return $this->doDeserialize(json_decode($contents), $className, new Context(['generated' => true]));
return $this->doDeserialize(json_decode($contents), $className, $context ?? new Context(['generated' => true]));
}

/**
Expand Down
189 changes: 108 additions & 81 deletions tests/SerializerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

use OpenApi\Annotations as OA;
use OpenApi\Annotations\OpenApi;
use OpenApi\Context;
use OpenApi\Generator;
use OpenApi\Serializer;
use OpenApi\Tests\Concerns\UsesExamples;
Expand All @@ -17,7 +18,7 @@ final class SerializerTest extends OpenApiTestCase
{
use UsesExamples;

private function getExpected(): OpenApi
private function getPetstoreExpected(): OpenApi
{
$path = new OA\PathItem(['_context' => $this->getContext()]);
$path->path = '/products';
Expand Down Expand Up @@ -54,7 +55,7 @@ private function getExpected(): OpenApi
$path->post->responses = [$resp, $respRange];

$expected = new OpenApi(['_context' => $this->getContext()]);
$expected->openapi = OpenApi::VERSION_3_0_0;
$expected->openapi = OpenApi::VERSION_3_1_0;
$expected->paths = [
$path,
];
Expand All @@ -74,76 +75,76 @@ private function getExpected(): OpenApi
return $expected;
}

public function testDeserializeAnnotation(): void
public function testDeserializePetstore(): void
{
$serializer = new Serializer();

$json = <<<JSON
{
"openapi": "3.0.0",
"info": {
"title": "Pet store",
"version": "1.0"
},
"paths": {
"/products": {
"post": {
"tags": [
"products"
],
"summary": "s1",
"description": "d1",
"requestBody": {
"description": "data in body",
"content": {
"application/json": {
"schema": {
"type": "object",
"additionalProperties": true
}
}
},
"x-repository": "def"
},
"responses": {
"200": {
"description": "Success",
"content": {
"application/json": {
"schema": {
"\$ref": "#/components/schemas/Pet"
}
}
},
"x-repository": "def"
},
"4XX": {
"description": "Client error response"
}
}
}
}
},
"components": {
"schemas": {
"Pet": {
"required": [
"name",
"photoUrls"
]
}
}
}
"openapi": "3.1.0",
"info": {
"title": "Pet store",
"version": "1.0"
},
"paths": {
"/products": {
"post": {
"tags": [
"products"
],
"summary": "s1",
"description": "d1",
"requestBody": {
"description": "data in body",
"content": {
"application/json": {
"schema": {
"type": "object",
"additionalProperties": true
}
}
},
"x-repository": "def"
},
"responses": {
"200": {
"description": "Success",
"content": {
"application/json": {
"schema": {
"\$ref": "#/components/schemas/Pet"
}
}
},
"x-repository": "def"
},
"4XX": {
"description": "Client error response"
}
}
}
}
},
"components": {
"schemas": {
"Pet": {
"required": [
"name",
"photoUrls"
]
}
}
}
}
JSON;

$serializer = new Serializer();

/** @var OpenApi $annotation */
$annotation = $serializer->deserialize($json, OpenApi::class);

$this->assertInstanceOf(OpenApi::class, $annotation);
$this->assertJsonStringEqualsJsonString(
$annotation->toJson(),
$this->getExpected()->toJson()
$this->getPetstoreExpected()->toJson()
);

$schema = $annotation->paths['/products']->post->requestBody->content['application/json']->schema;
Expand All @@ -153,7 +154,7 @@ public function testDeserializeAnnotation(): void
public function testPetstoreExample(): void
{
$serializer = new Serializer();
$spec = self::examplePath('petstore/petstore-3.0.0.yaml');
$spec = self::examplePath('petstore/petstore-3.1.0.yaml');
$openapi = $serializer->deserializeFile($spec, 'yaml');
$this->assertInstanceOf(OpenApi::class, $openapi);
$this->assertSpecEquals(file_get_contents($spec), $openapi->toYaml());
Expand All @@ -166,30 +167,32 @@ public function testPetstoreExample(): void
*/
public function testDeserializeAllOfProperty(): void
{
$serializer = new Serializer();
$json = <<<JSON
{
"openapi": "3.0.0",
"info": {
"title": "Pet store",
"version": "1.0"
},
"components": {
"schemas": {
"Dog": {
"allOf": [{
"\$ref": "#/components/schemas/SomeSchema"
}]
},
"Cat": {
"allOf": [{
"\$ref": "#/components/schemas/SomeSchema"
}]
}
}
}
"openapi": "3.0.0",
"info": {
"title": "Pet store",
"version": "1.0"
},
"components": {
"schemas": {
"Dog": {
"allOf": [{
"\$ref": "#/components/schemas/SomeSchema"
}]
},
"Cat": {
"allOf": [{
"\$ref": "#/components/schemas/SomeSchema"
}]
}
}
}
}
JSON;

$serializer = new Serializer();

/** @var OpenApi $annotation */
$annotation = $serializer->deserialize($json, OpenApi::class);

Expand All @@ -212,4 +215,28 @@ public function testValidAnnotationsListComplete(string $annotation): void
$staticProperties = (new \ReflectionClass((Serializer::class)))->getStaticProperties();
$this->assertArrayHasKey($annotation, array_flip($staticProperties['VALID_ANNOTATIONS']));
}

public function testSerializeWithContext(): void
{
$json = <<<JSON
{
"tags": [
{
"name": "Foo",
"summary": "Foo stuff"
}
]
}
JSON;

$serializer = new Serializer();

/** @var OpenApi $annotation */
$annotation = $serializer->deserialize($json, OpenApi::class, new Context(['version' => '3.2.0', 'generated' => true]));

$this->assertJsonStringEqualsJsonString(
str_replace('"tags"', '"openapi":"3.2.0", "tags"', $json),
$annotation->toJson(),
);
}
}