-
-
Notifications
You must be signed in to change notification settings - Fork 836
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
) * refactor: TestKernel configureRoutes method * improve testing to a per controller test * uncomment commented code * style fix * more refactoring for new ControllerTest * fix-2209: do not generate content if already exists * style fix * check if MapRequestPayload exists * Add MapQueryStringController * add test showcasing CleanUnusedComponents Processor * style fix * cleaner fix
- Loading branch information
1 parent
5a5049d
commit daadb0b
Showing
11 changed files
with
6,853 additions
and
19 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
services: | ||
OpenApi\Processors\CleanUnusedComponents: | ||
tags: | ||
- { name: 'nelmio_api_doc.swagger.processor', priority: -100 } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Nelmio\ApiDocBundle\Tests\Functional; | ||
|
||
use Symfony\Component\DependencyInjection\ContainerInterface; | ||
use Symfony\Component\Filesystem\Filesystem; | ||
use Symfony\Component\HttpKernel\Bundle\Bundle; | ||
|
||
final class ConfigurableContainerFactory | ||
{ | ||
/** | ||
* @var ContainerInterface | ||
*/ | ||
private $container; | ||
|
||
/** | ||
* @param Bundle[] $extraBundles | ||
* @param string[] $extraConfigs | ||
*/ | ||
public function create(array $extraBundles, ?callable $routeConfiguration, array $extraConfigs): void | ||
{ | ||
// clear cache directory for a fresh container | ||
$filesystem = new Filesystem(); | ||
$filesystem->remove('var/cache/test'); | ||
|
||
$appKernel = new NelmioKernel($extraBundles, $routeConfiguration, $extraConfigs); | ||
$appKernel->boot(); | ||
|
||
$this->container = $appKernel->getContainer(); | ||
} | ||
|
||
public function getContainer(): ContainerInterface | ||
{ | ||
return $this->container; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Nelmio\ApiDocBundle\Tests\Functional\Controller; | ||
|
||
use Nelmio\ApiDocBundle\Annotation\Model; | ||
use Nelmio\ApiDocBundle\Tests\Functional\Entity\Article81; | ||
use OpenApi\Attributes as OA; | ||
use Symfony\Component\HttpFoundation\JsonResponse; | ||
use Symfony\Component\HttpKernel\Attribute\MapRequestPayload; | ||
use Symfony\Component\Routing\Annotation\Route; | ||
|
||
class Controller2209 | ||
{ | ||
#[Route(path: '/api/v3/users', name: 'api_v3_users_create', methods: 'POST')] | ||
#[OA\RequestBody( | ||
content: new OA\MediaType(mediaType: 'application/json', schema: new OA\Schema( | ||
ref: new Model(type: Article81::class), | ||
)), | ||
)] | ||
public function __invoke(#[MapRequestPayload] Article81 $requestDTO): JsonResponse | ||
{ | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Nelmio\ApiDocBundle\Tests\Functional\Controller; | ||
|
||
use Nelmio\ApiDocBundle\Tests\Functional\Entity\QueryModel\ArrayQueryModel; | ||
use Nelmio\ApiDocBundle\Tests\Functional\Entity\QueryModel\FilterQueryModel; | ||
use Nelmio\ApiDocBundle\Tests\Functional\Entity\QueryModel\PaginationQueryModel; | ||
use Nelmio\ApiDocBundle\Tests\Functional\Entity\QueryModel\SortQueryModel; | ||
use Nelmio\ApiDocBundle\Tests\Functional\Entity\SymfonyConstraintsWithValidationGroups; | ||
use Nelmio\ApiDocBundle\Tests\Functional\Entity\SymfonyMapQueryString; | ||
use Symfony\Component\HttpKernel\Attribute\MapQueryString; | ||
use Symfony\Component\Routing\Annotation\Route; | ||
|
||
class MapQueryStringController | ||
{ | ||
#[Route('/article_map_query_string')] | ||
#[OA\Response(response: '200', description: '')] | ||
public function fetchArticleFromMapQueryString( | ||
#[MapQueryString] SymfonyMapQueryString $article81Query | ||
) { | ||
} | ||
|
||
#[Route('/article_map_query_string_nullable')] | ||
#[OA\Response(response: '200', description: '')] | ||
public function fetchArticleFromMapQueryStringNullable( | ||
#[MapQueryString] ?SymfonyMapQueryString $article81Query | ||
) { | ||
} | ||
|
||
#[Route('/article_map_query_string_passes_validation_groups')] | ||
#[OA\Response(response: '200', description: '')] | ||
public function fetchArticleFromMapQueryStringHandlesValidationGroups( | ||
#[MapQueryString(validationGroups: ['test'])] SymfonyConstraintsWithValidationGroups $symfonyConstraintsWithValidationGroups, | ||
) { | ||
} | ||
|
||
#[Route('/article_map_query_string_overwrite_parameters')] | ||
#[OA\Parameter( | ||
name: 'id', | ||
in: 'query', | ||
schema: new OA\Schema(type: 'string', nullable: true), | ||
description: 'Query parameter id description' | ||
)] | ||
#[OA\Parameter( | ||
name: 'name', | ||
in: 'query', | ||
description: 'Query parameter name description' | ||
)] | ||
#[OA\Parameter( | ||
name: 'nullableName', | ||
in: 'query', | ||
description: 'Query parameter nullableName description' | ||
)] | ||
#[OA\Parameter( | ||
name: 'articleType81', | ||
in: 'query', | ||
description: 'Query parameter articleType81 description' | ||
)] | ||
#[OA\Parameter( | ||
name: 'nullableArticleType81', | ||
in: 'query', | ||
description: 'Query parameter nullableArticleType81 description' | ||
)] | ||
#[OA\Response(response: '200', description: '')] | ||
public function fetchArticleFromMapQueryStringOverwriteParameters( | ||
#[MapQueryString] SymfonyMapQueryString $article81Query | ||
) { | ||
} | ||
|
||
#[Route('/article_map_query_string_many_parameters')] | ||
#[OA\Response(response: '200', description: '')] | ||
public function fetchArticleWithManyParameters( | ||
#[MapQueryString] FilterQueryModel $filterQuery, | ||
#[MapQueryString] PaginationQueryModel $paginationQuery, | ||
#[MapQueryString] SortQueryModel $sortQuery, | ||
#[MapQueryString] ArrayQueryModel $arrayQuery, | ||
) { | ||
} | ||
|
||
#[Route('/article_map_query_string_many_parameters_optional')] | ||
#[OA\Response(response: '200', description: '')] | ||
public function fetchArticleWithManyOptionalParameters( | ||
#[MapQueryString] ?FilterQueryModel $filterQuery, | ||
#[MapQueryString] ?PaginationQueryModel $paginationQuery, | ||
#[MapQueryString] ?SortQueryModel $sortQuery, | ||
#[MapQueryString] ?ArrayQueryModel $arrayQuery, | ||
) { | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,119 @@ | ||
<?php | ||
|
||
/* | ||
* This file is part of the NelmioApiDocBundle package. | ||
* | ||
* (c) Nelmio | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
namespace Nelmio\ApiDocBundle\Tests\Functional; | ||
|
||
use OpenApi\Annotations as OA; | ||
use Symfony\Component\HttpKernel\Kernel; | ||
use Symfony\Component\HttpKernel\KernelInterface; | ||
use Symfony\Component\Routing\Loader\Configurator\RoutingConfigurator; | ||
|
||
/** | ||
* Fairly intensive functional tests because the Kernel is recreated for each test. | ||
*/ | ||
final class ControllerTest extends WebTestCase | ||
{ | ||
/** | ||
* @var ConfigurableContainerFactory | ||
*/ | ||
private $configurableContainerFactory; | ||
|
||
/** | ||
* @var string[] | ||
*/ | ||
private static $usedFixtures = []; | ||
|
||
protected function setUp(): void | ||
{ | ||
$this->configurableContainerFactory = new ConfigurableContainerFactory(); | ||
|
||
static::createClient([], ['HTTP_HOST' => 'api.example.com']); | ||
} | ||
|
||
protected static function createKernel(array $options = []): KernelInterface | ||
{ | ||
return new NelmioKernel([], null, []); | ||
} | ||
|
||
protected function getOpenApiDefinition($area = 'default'): OA\OpenApi | ||
{ | ||
return $this->configurableContainerFactory->getContainer()->get(sprintf('nelmio_api_doc.generator.%s', $area))->generate(); | ||
} | ||
|
||
/** | ||
* @dataProvider provideControllers | ||
*/ | ||
public function testControllers(string $controllerName, ?string $fixtureName = null, array $extraConfigs = []): void | ||
{ | ||
$fixtureName = $fixtureName ?? $controllerName; | ||
|
||
$routingConfiguration = function (RoutingConfigurator $routes) use ($controllerName) { | ||
$routes->withPath('/')->import(__DIR__."/Controller/$controllerName.php", 'attribute'); | ||
}; | ||
|
||
$this->configurableContainerFactory->create([], $routingConfiguration, $extraConfigs); | ||
|
||
$apiDefinition = $this->getOpenApiDefinition(); | ||
|
||
// Create the fixture if it does not exist | ||
if (!file_exists($fixtureDir = __DIR__.'/Fixtures/'.$fixtureName.'.json')) { | ||
file_put_contents($fixtureDir, $apiDefinition->toJson()); | ||
} | ||
|
||
static::$usedFixtures[] = $fixtureName.'.json'; | ||
|
||
self::assertSame( | ||
self::getFixture($fixtureDir), | ||
$this->getOpenApiDefinition()->toJson() | ||
); | ||
} | ||
|
||
public static function provideControllers(): iterable | ||
{ | ||
if (version_compare(Kernel::VERSION, '6.3.0', '>=')) { | ||
yield 'https://github.com/nelmio/NelmioApiDocBundle/issues/2209' => ['Controller2209']; | ||
yield 'MapQueryString' => ['MapQueryStringController']; | ||
yield 'https://github.com/nelmio/NelmioApiDocBundle/issues/2191' => [ | ||
'MapQueryStringController', | ||
'MapQueryStringCleanupComponents', | ||
[__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))); | ||
} | ||
|
||
private static function getFixture(string $fixture): string | ||
{ | ||
if (!file_exists($fixture)) { | ||
self::fail(sprintf('The fixture file "%s" does not exist.', $fixture)); | ||
} | ||
|
||
$content = file_get_contents($fixture); | ||
|
||
if (false === $content) { | ||
self::fail(sprintf('Failed to read the fixture file "%s".', $fixture)); | ||
} | ||
|
||
return $content; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
{ | ||
"openapi": "3.0.0", | ||
"info": { | ||
"title": "", | ||
"version": "0.0.0" | ||
}, | ||
"paths": { | ||
"/api/v3/users": { | ||
"post": { | ||
"operationId": "post_api_v3_users_create", | ||
"requestBody": { | ||
"required": true, | ||
"content": { | ||
"application/json": { | ||
"schema": { | ||
"$ref": "#/components/schemas/Article81" | ||
} | ||
} | ||
} | ||
}, | ||
"responses": { | ||
"default": { | ||
"description": "" | ||
} | ||
} | ||
} | ||
} | ||
}, | ||
"components": { | ||
"schemas": { | ||
"Article81": { | ||
"required": [ | ||
"id", | ||
"type", | ||
"intBackedType", | ||
"notBackedType" | ||
], | ||
"properties": { | ||
"id": { | ||
"type": "integer" | ||
}, | ||
"type": { | ||
"$ref": "#/components/schemas/ArticleType81" | ||
}, | ||
"intBackedType": { | ||
"$ref": "#/components/schemas/ArticleType81IntBacked" | ||
}, | ||
"notBackedType": { | ||
"$ref": "#/components/schemas/ArticleType81NotBacked" | ||
}, | ||
"nullableType": { | ||
"nullable": true, | ||
"allOf": [ | ||
{ | ||
"$ref": "#/components/schemas/ArticleType81" | ||
} | ||
] | ||
} | ||
}, | ||
"type": "object" | ||
}, | ||
"ArticleType81": { | ||
"type": "string", | ||
"enum": [ | ||
"draft", | ||
"final" | ||
] | ||
}, | ||
"ArticleType81IntBacked": { | ||
"type": "integer", | ||
"enum": [ | ||
0, | ||
1 | ||
] | ||
}, | ||
"ArticleType81NotBacked": { | ||
"required": [ | ||
"name" | ||
], | ||
"properties": { | ||
"name": { | ||
"type": "string" | ||
} | ||
}, | ||
"type": "object" | ||
} | ||
} | ||
} | ||
} |
Oops, something went wrong.