Skip to content

Commit

Permalink
Consider the root annotation type when augmenting schemas (#1387)
Browse files Browse the repository at this point in the history
  • Loading branch information
DerManoMann authored Jan 12, 2023
1 parent b419fb1 commit 8a6e6b6
Show file tree
Hide file tree
Showing 7 changed files with 90 additions and 18 deletions.
22 changes: 21 additions & 1 deletion src/Annotations/AbstractAnnotation.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

use OpenApi\Context;
use OpenApi\Generator;
use OpenApi\Annotations as OA;
use OpenApi\Util;
use Symfony\Component\Yaml\Yaml;

Expand Down Expand Up @@ -566,7 +567,7 @@ public function identity(): string
/**
* Find matching nested details.
*
* @param string $class the class to match
* @param class-string $class the class to match
*
* @return null|object key/value object or `null`
*/
Expand All @@ -587,6 +588,25 @@ public static function matchNested(string $class)
return null;
}

/**
* Match the annotation root.
*
* @param class-string $rootClass the root class to match
*/
public function isRoot(string $rootClass): bool
{
$parent = get_class($this);

// only consider the immediate OpenApi parent
do {
if ($parent == $rootClass) {
return true;
}
} while (0 !== strpos($parent, 'OpenApi\\Annotations\\') && $parent = get_parent_class($parent));

return false;
}

/**
* Helper for generating the identity().
*/
Expand Down
13 changes: 7 additions & 6 deletions src/Processors/AugmentSchemas.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@

use OpenApi\Analysis;
use OpenApi\Annotations as OA;
use OpenApi\Attributes as OAT;
use OpenApi\Context;
use OpenApi\Generator;

Expand All @@ -21,8 +20,13 @@ class AugmentSchemas
{
public function __invoke(Analysis $analysis)
{
/** @var OA\Schema $schema */
foreach ($analysis->getAnnotationsOfType([OA\Schema::class, OAT\Schema::class], true) as $schema) {
/** @var OA\Schema[] $schemas */
$schemas = $analysis->getAnnotationsOfType(OA\Schema::class);

foreach ($schemas as $schema) {
if (!$schema->isRoot(OA\Schema::class)) {
continue;
}
if (Generator::isDefault($schema->schema)) {
if ($schema->_context->is('class')) {
$schema->schema = $schema->_context->class;
Expand All @@ -36,9 +40,6 @@ public function __invoke(Analysis $analysis)
}
}

/** @var OA\Schema[] $schemas */
$schemas = $analysis->getAnnotationsOfType(OA\Schema::class);

// Merge unmerged @OA\Property annotations into the @OA\Schema of the class
$unmergedProperties = $analysis->unmerged()->getAnnotationsOfType(OA\Property::class);
foreach ($unmergedProperties as $property) {
Expand Down
23 changes: 14 additions & 9 deletions tests/Annotations/AbstractAnnotationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,7 @@

namespace OpenApi\Tests\Annotations;

use OpenApi\Annotations\Get;
use OpenApi\Annotations\Parameter;
use OpenApi\Annotations\Schema;
use OpenApi\Annotations as OA;
use OpenApi\Generator;
use OpenApi\Tests\OpenApiTestCase;

Expand Down Expand Up @@ -112,12 +110,12 @@ public function testTypeValidation(): void

public function nestedMatches(): iterable
{
$parameterMatch = (object) ['key' => Parameter::class, 'value' => ['parameters']];
$parameterMatch = (object) ['key' => OA\Parameter::class, 'value' => ['parameters']];

return [
'unknown' => [self::class, null],
'simple-match' => [Parameter::class, $parameterMatch],
'invalid-annotation' => [Schema::class, null],
'simple-match' => [OA\Parameter::class, $parameterMatch],
'invalid-annotation' => [OA\Schema::class, null],
'sub-annotation' => [SubParameter::class, $parameterMatch],
'sub-sub-annotation' => [SubSubParameter::class, $parameterMatch],
'sub-invalid' => [SubSchema::class, null],
Expand All @@ -129,7 +127,7 @@ public function nestedMatches(): iterable
*/
public function testMatchNested(string $class, $expected): void
{
$this->assertEquals($expected, Get::matchNested($class));
$this->assertEquals($expected, OA\Get::matchNested($class));
}

public function testDuplicateOperationIdValidation(): void
Expand All @@ -140,13 +138,20 @@ public function testDuplicateOperationIdValidation(): void
$this->assertOpenApiLogEntryContains('operationId must be unique. Duplicate value found: "getItem"');
$this->assertFalse($analysis->validate());
}

public function testIsRoot(): void
{
$this->assertTrue((new OA\AdditionalProperties([]))->isRoot(OA\AdditionalProperties::class));
$this->assertFalse((new OA\AdditionalProperties([]))->isRoot(OA\Schema::class));
$this->assertTrue((new SubSchema([]))->isRoot(OA\Schema::class));
}
}

class SubSchema extends Schema
class SubSchema extends OA\Schema
{
}

class SubParameter extends Parameter
class SubParameter extends OA\Parameter
{
}

Expand Down
32 changes: 32 additions & 0 deletions tests/Fixtures/Scratch/CustomAttributeSchema.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php declare(strict_types=1);

/**
* @license Apache 2.0
*/

namespace OpenApi\Tests\Fixtures\Scratch;

use OpenApi\Attributes as OAT;

#[\Attribute(\Attribute::TARGET_CLASS | \Attribute::TARGET_METHOD | \Attribute::TARGET_PROPERTY)]
class CustomAttributeSchema extends OAT\Schema
{
}

#[CustomAttributeSchema()]
class MyClass
{
}

#[OAT\Info(
title: 'Custom Attribute Schema Scratch',
version: '1.0'
)]
#[OAT\Get(
path: '/api/endpoint',
description: 'An endpoint',
responses: [new OAT\Response(response: 200, description: 'OK')]
)]
class CustomAttributeSchemaEndpoint
{
}
14 changes: 14 additions & 0 deletions tests/Fixtures/Scratch/CustomAttributeSchema.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
openapi: 3.0.0
info:
title: 'Custom Attribute Schema Scratch'
version: '1.0'
paths:
/api/endpoint:
get:
description: 'An endpoint'
responses:
'200':
description: OK
components:
schemas:
MyClass: { }
2 changes: 1 addition & 1 deletion tests/Fixtures/Scratch/MergeTraits.php
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,6 @@ class Address extends Model
* )
* )
*/
class Endpoint
class MergeTraitsEndpoint
{
}
2 changes: 1 addition & 1 deletion tests/Fixtures/Scratch/ParameterContent.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,6 @@
],
responses: [new OAT\Response(response: 200, description: 'OK')]
)]
class Endpoint
class ParameterContentEndpoint
{
}

0 comments on commit 8a6e6b6

Please sign in to comment.