Skip to content

Commit

Permalink
fix-2224: fix vendor extension being ignored (#2230)
Browse files Browse the repository at this point in the history
* fix-2224: fix vendor extension being ignored

* fix-2224: test vendor extension from config

* fix-2224: expand vendor extension tests

* style fix

* better annotation detection

* remove unused fixtures test

* check if bundle exist before setting config

* fix annotation check

* Revert "better annotation detection"

This reverts commit 048356f.

* allow passing no controller for test
  • Loading branch information
DjordyKoert committed Mar 6, 2024
1 parent 32537bb commit beb544e
Show file tree
Hide file tree
Showing 7 changed files with 66 additions and 25 deletions.
12 changes: 12 additions & 0 deletions src/OpenApiPhp/Util.php
Expand Up @@ -421,9 +421,21 @@ private static function mergeFromArray(OA\AbstractAnnotation $annotation, array
}

foreach ($properties as $propertyName => $value) {
if (str_starts_with($propertyName, 'x-')) {
$propertyName = substr($propertyName, 2);

if (Generator::isDefault($annotation->x)) {
$annotation->x = [];
}

$annotation->x = [$propertyName => $value] + ($annotation->x ?: []);
continue;
}

if ('$ref' === $propertyName) {
$propertyName = 'ref';
}

if (array_key_exists($propertyName, $defaults) && !\in_array($propertyName, $done, true)) {
self::mergeProperty($annotation, $propertyName, $value, $defaults[$propertyName], $overwrite);
}
Expand Down
14 changes: 14 additions & 0 deletions tests/Functional/Configs/VendorExtension.yaml
@@ -0,0 +1,14 @@
nelmio_api_doc:
documentation:
info:
title: 'Test API'
description: 'Test API description'
x-vendor:
test: 'Test vendor extension'
x-build: '#SomeCommitHash'
components:
schemas:
Test:
type: string
x-vendor:
test: 'Test vendor extension inside schema'
4 changes: 2 additions & 2 deletions tests/Functional/Controller/TestController.php
Expand Up @@ -11,12 +11,12 @@

namespace Nelmio\ApiDocBundle\Tests\Functional\Controller;

use Nelmio\ApiDocBundle\Tests\Functional\TestKernel;
use OpenApi\Annotations as OA;
use OpenApi\Attributes as OAT;
use Symfony\Component\HttpKernel\Kernel;
use Symfony\Component\Routing\Annotation\Route;

if (Kernel::MAJOR_VERSION < 7) {
if (TestKernel::isAnnotationsAvailable()) {
/**
* @Route("/test", host="api-test.example.com")
*/
Expand Down
32 changes: 11 additions & 21 deletions tests/Functional/ControllerTest.php
Expand Up @@ -26,11 +26,6 @@ final class ControllerTest extends WebTestCase
*/
private $configurableContainerFactory;

/**
* @var string[]
*/
private static $usedFixtures = [];

protected function setUp(): void
{
$this->configurableContainerFactory = new ConfigurableContainerFactory();
Expand All @@ -51,11 +46,15 @@ protected function getOpenApiDefinition($area = 'default'): OA\OpenApi
/**
* @dataProvider provideControllers
*/
public function testControllers(string $controllerName, ?string $fixtureName = null, array $extraConfigs = []): void
public function testControllers(?string $controllerName, ?string $fixtureName = null, array $extraConfigs = []): void
{
$fixtureName = $fixtureName ?? $controllerName;
$fixtureName = $fixtureName ?? $controllerName ?? $this->fail('A fixture name must be provided.');

$routingConfiguration = function (RoutingConfigurator $routes) use ($controllerName) {
if (null === $controllerName) {
return;
}

$routes->withPath('/')->import(__DIR__."/Controller/$controllerName.php", 'attribute');
};

Expand All @@ -68,8 +67,6 @@ public function testControllers(string $controllerName, ?string $fixtureName = n
file_put_contents($fixtureDir, $apiDefinition->toJson());
}

static::$usedFixtures[] = $fixtureName.'.json';

self::assertSame(
self::getFixture($fixtureDir),
$this->getOpenApiDefinition()->toJson()
Expand All @@ -87,19 +84,12 @@ public static function provideControllers(): iterable
[__DIR__.'/Configs/CleanUnusedComponentsProcessor.yaml'],
];
}
}

/**
* @depends testControllers
*/
public function testUnusedFixtures(): void
{
$fixtures = glob(__DIR__.'/Fixtures/*.json');
$fixtures = array_map('basename', $fixtures);

$diff = array_diff($fixtures, static::$usedFixtures);

self::assertEmpty($diff, sprintf('The following fixtures are not used: %s', implode(', ', $diff)));
yield 'https://github.com/nelmio/NelmioApiDocBundle/issues/2224' => [
null,
'VendorExtension',
[__DIR__.'/Configs/VendorExtension.yaml'],
];
}

private static function getFixture(string $fixture): string
Expand Down
23 changes: 23 additions & 0 deletions tests/Functional/Fixtures/VendorExtension.json
@@ -0,0 +1,23 @@
{
"openapi": "3.0.0",
"info": {
"title": "Test API",
"description": "Test API description",
"version": "0.0.0",
"x-build": "#SomeCommitHash",
"x-vendor": {
"test": "Test vendor extension"
}
},
"paths": {},
"components": {
"schemas": {
"Test": {
"type": "string",
"x-vendor": {
"test": "Test vendor extension inside schema"
}
}
}
}
}
1 change: 1 addition & 0 deletions tests/Functional/FunctionalTest.php
Expand Up @@ -32,6 +32,7 @@ protected function setUp(): void
public function testConfiguredDocumentation()
{
$this->assertEquals('My Default App', $this->getOpenApiDefinition()->info->title);
$this->assertEquals(['buildHash' => 'ab1234567890'], $this->getOpenApiDefinition()->info->x);
$this->assertEquals('My Test App', $this->getOpenApiDefinition('test')->info->title);
}

Expand Down
5 changes: 3 additions & 2 deletions tests/Functional/TestKernel.php
Expand Up @@ -157,7 +157,7 @@ protected function configureContainer(ContainerBuilder $c, LoaderInterface $load
'exception_controller' => null,
]);

if (self::isAnnotationsAvailable()) {
if (class_exists(SensioFrameworkExtraBundle::class)) {
$c->loadFromExtension('sensio_framework_extra', [
'router' => [
'annotations' => false,
Expand All @@ -173,7 +173,7 @@ protected function configureContainer(ContainerBuilder $c, LoaderInterface $load
]],
]);

if (self::isAnnotationsAvailable()) {
if (class_exists(FOSRestBundle::class)) {
$c->loadFromExtension('fos_rest', [
'format_listener' => [
'rules' => [
Expand Down Expand Up @@ -268,6 +268,7 @@ protected function configureContainer(ContainerBuilder $c, LoaderInterface $load
'documentation' => [
'info' => [
'title' => 'My Default App',
'x-buildHash' => 'ab1234567890',
],
'paths' => [
// Ensures we can define routes in Yaml without defining OperationIds
Expand Down

0 comments on commit beb544e

Please sign in to comment.