Skip to content

Commit

Permalink
Merge 22e1ea5 into d008a59
Browse files Browse the repository at this point in the history
  • Loading branch information
soyuka committed Feb 2, 2021
2 parents d008a59 + 22e1ea5 commit 56e2983
Show file tree
Hide file tree
Showing 8 changed files with 75 additions and 3 deletions.
Expand Up @@ -373,6 +373,7 @@ private function registerOAuthConfiguration(ContainerBuilder $container, array $
*/
private function registerSwaggerConfiguration(ContainerBuilder $container, array $config, XmlFileLoader $loader): void
{
$container->setParameter('api_platform.openapi.backward_compatibility', $config['openapi']['backward_compatibility']);
$container->setParameter('api_platform.swagger.versions', $config['swagger']['versions']);

if (empty($config['swagger']['versions'])) {
Expand Down
Expand Up @@ -483,6 +483,7 @@ private function addOpenApiSection(ArrayNodeDefinition $rootNode): void
->scalarNode('email')->defaultNull()->info('The email address of the contact person/organization. MUST be in the format of an email address.')->end()
->end()
->end()
->booleanNode('backward_compatibility')->defaultTrue()->info('Enable this to decorate the "api_platform.swagger.normalizer.documentation" instead of decorating the OpenAPI factory.')->end()
->scalarNode('termsOfService')->defaultNull()->info('A URL to the Terms of Service for the API. MUST be in the format of a URL.')->end()
->arrayNode('license')
->addDefaultsIfNotSet()
Expand Down
3 changes: 2 additions & 1 deletion src/Bridge/Symfony/Bundle/Resources/config/openapi.xml
Expand Up @@ -7,7 +7,8 @@
<services>
<service id="api_platform.openapi.normalizer" class="ApiPlatform\Core\OpenApi\Serializer\OpenApiNormalizer" public="false">
<argument type="service" id="serializer.normalizer.object" />
<tag name="serializer.normalizer" priority="-785" />
<!-- Just after the DocumentationNormalizer see swagger.xml -->
<tag name="serializer.normalizer" priority="-795" />
</service>
<service id="ApiPlatform\Core\OpenApi\Serializer\OpenApiNormalizer" alias="api_platform.openapi.normalizer" />

Expand Down
2 changes: 2 additions & 0 deletions src/Bridge/Symfony/Bundle/Resources/config/swagger.xml
Expand Up @@ -34,6 +34,8 @@
<argument type="collection" />
<argument>%api_platform.swagger.versions%</argument>
<argument type="service" id="api_platform.identifiers_extractor.cached" />
<argument>%api_platform.openapi.backward_compatibility%</argument>
<argument type="service" id="api_platform.openapi.normalizer" />
<tag name="serializer.normalizer" priority="-790" />
</service>

Expand Down
17 changes: 15 additions & 2 deletions src/Swagger/Serializer/DocumentationNormalizer.php
Expand Up @@ -33,6 +33,7 @@
use ApiPlatform\Core\Metadata\Property\Factory\PropertyNameCollectionFactoryInterface;
use ApiPlatform\Core\Metadata\Resource\Factory\ResourceMetadataFactoryInterface;
use ApiPlatform\Core\Metadata\Resource\ResourceMetadata;
use ApiPlatform\Core\OpenApi\OpenApi;
use ApiPlatform\Core\Operation\Factory\SubresourceOperationFactoryInterface;
use ApiPlatform\Core\PathResolver\OperationPathResolverInterface;
use Psr\Container\ContainerInterface;
Expand Down Expand Up @@ -102,14 +103,17 @@ final class DocumentationNormalizer implements NormalizerInterface, CacheableSup

private $identifiersExtractor;

private $openApiBackwardCompatibility;
private $openApiNormalizer;

/**
* @param SchemaFactoryInterface|ResourceClassResolverInterface|null $jsonSchemaFactory
* @param ContainerInterface|FilterCollection|null $filterLocator
* @param array|OperationAwareFormatsProviderInterface $formats
* @param mixed|null $jsonSchemaTypeFactory
* @param int[] $swaggerVersions
*/
public function __construct(ResourceMetadataFactoryInterface $resourceMetadataFactory, PropertyNameCollectionFactoryInterface $propertyNameCollectionFactory, PropertyMetadataFactoryInterface $propertyMetadataFactory, $jsonSchemaFactory = null, $jsonSchemaTypeFactory = null, OperationPathResolverInterface $operationPathResolver = null, UrlGeneratorInterface $urlGenerator = null, $filterLocator = null, NameConverterInterface $nameConverter = null, bool $oauthEnabled = false, string $oauthType = '', string $oauthFlow = '', string $oauthTokenUrl = '', string $oauthAuthorizationUrl = '', array $oauthScopes = [], array $apiKeys = [], SubresourceOperationFactoryInterface $subresourceOperationFactory = null, bool $paginationEnabled = true, string $paginationPageParameterName = 'page', bool $clientItemsPerPage = false, string $itemsPerPageParameterName = 'itemsPerPage', $formats = [], bool $paginationClientEnabled = false, string $paginationClientEnabledParameterName = 'pagination', array $defaultContext = [], array $swaggerVersions = [2, 3], IdentifiersExtractorInterface $identifiersExtractor = null)
public function __construct(ResourceMetadataFactoryInterface $resourceMetadataFactory, PropertyNameCollectionFactoryInterface $propertyNameCollectionFactory, PropertyMetadataFactoryInterface $propertyMetadataFactory, $jsonSchemaFactory = null, $jsonSchemaTypeFactory = null, OperationPathResolverInterface $operationPathResolver = null, UrlGeneratorInterface $urlGenerator = null, $filterLocator = null, NameConverterInterface $nameConverter = null, bool $oauthEnabled = false, string $oauthType = '', string $oauthFlow = '', string $oauthTokenUrl = '', string $oauthAuthorizationUrl = '', array $oauthScopes = [], array $apiKeys = [], SubresourceOperationFactoryInterface $subresourceOperationFactory = null, bool $paginationEnabled = true, string $paginationPageParameterName = 'page', bool $clientItemsPerPage = false, string $itemsPerPageParameterName = 'itemsPerPage', $formats = [], bool $paginationClientEnabled = false, string $paginationClientEnabledParameterName = 'pagination', array $defaultContext = [], array $swaggerVersions = [2, 3], IdentifiersExtractorInterface $identifiersExtractor = null, bool $openApiBackwardCompatibility = true, NormalizerInterface $openApiNormalizer = null)
{
if ($jsonSchemaTypeFactory instanceof OperationMethodResolverInterface) {
@trigger_error(sprintf('Passing an instance of %s to %s() is deprecated since version 2.5 and will be removed in 3.0.', OperationMethodResolverInterface::class, __METHOD__), \E_USER_DEPRECATED);
Expand Down Expand Up @@ -171,13 +175,22 @@ public function __construct(ResourceMetadataFactoryInterface $resourceMetadataFa

$this->defaultContext = array_merge($this->defaultContext, $defaultContext);
$this->identifiersExtractor = $identifiersExtractor;

$this->openApiBackwardCompatibility = $openApiBackwardCompatibility;
$this->openApiNormalizer = $openApiNormalizer;
}

/**
* {@inheritdoc}
*/
public function normalize($object, $format = null, array $context = [])
{
if ($object instanceof OpenApi) {
// uncomment this for 2.7
// @trigger_error('Using the swagger DocumentationNormalizer is deprecated in favor of decorating the OpenApiFactory', \E_USER_DEPRECATED);
return $this->openApiNormalizer->normalize($object, $format, $context);
}

$v3 = 3 === ($context['spec_version'] ?? $this->defaultContext['spec_version']) && !($context['api_gateway'] ?? $this->defaultContext['api_gateway']);

$definitions = new \ArrayObject();
Expand Down Expand Up @@ -779,7 +792,7 @@ private function getFiltersParameters(bool $v3, string $resourceClass, string $o
*/
public function supportsNormalization($data, $format = null): bool
{
return self::FORMAT === $format && $data instanceof Documentation;
return self::FORMAT === $format && ($data instanceof Documentation || $this->openApiBackwardCompatibility && $data instanceof OpenApi);
}

/**
Expand Down
Expand Up @@ -1147,6 +1147,7 @@ private function getBaseContainerBuilderProphecy(array $doctrineIntegrationsToLo
'api_platform.openapi.contact.email' => null,
'api_platform.openapi.license.name' => null,
'api_platform.openapi.license.url' => null,
'api_platform.openapi.backward_compatibility' => true,
];

if ($hasSwagger) {
Expand Down
Expand Up @@ -218,6 +218,7 @@ private function runDefaultConfigTests(array $doctrineIntegrationsToLoad = ['orm
'name' => null,
'url' => null,
],
'backward_compatibility' => true,
],
], $config);
}
Expand Down
52 changes: 52 additions & 0 deletions tests/Swagger/Serializer/DocumentationNormalizerV3Test.php
Expand Up @@ -18,6 +18,7 @@
use ApiPlatform\Core\Api\OperationAwareFormatsProviderInterface;
use ApiPlatform\Core\Api\OperationMethodResolverInterface;
use ApiPlatform\Core\Api\OperationType;
use ApiPlatform\Core\Api\ResourceClassResolverInterface;
use ApiPlatform\Core\Bridge\Symfony\Routing\RouterOperationPathResolver;
use ApiPlatform\Core\Documentation\Documentation;
use ApiPlatform\Core\Exception\InvalidArgumentException;
Expand All @@ -33,6 +34,8 @@
use ApiPlatform\Core\Metadata\Resource\Factory\ResourceMetadataFactoryInterface;
use ApiPlatform\Core\Metadata\Resource\ResourceMetadata;
use ApiPlatform\Core\Metadata\Resource\ResourceNameCollection;
use ApiPlatform\Core\OpenApi\Model;
use ApiPlatform\Core\OpenApi\OpenApi;
use ApiPlatform\Core\Operation\Factory\SubresourceOperationFactory;
use ApiPlatform\Core\Operation\UnderscorePathSegmentNameGenerator;
use ApiPlatform\Core\PathResolver\CustomOperationPathResolver;
Expand All @@ -54,6 +57,7 @@
use Symfony\Component\Routing\RouterInterface;
use Symfony\Component\Serializer\NameConverter\NameConverterInterface;
use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;

/**
* @author Amrouche Hamza <hamza.simperfit@gmail.com>
Expand Down Expand Up @@ -3208,4 +3212,52 @@ private function doTestNormalizeWithCustomFormatsDefinedAtOperationLevel(Operati

$this->assertEquals($expected, $normalizer->normalize($documentation, DocumentationNormalizer::FORMAT, ['base_url' => '/']));
}

public function testNormalizeOpenApi()
{
$openapi = new OpenApi(new Model\Info('api', 'v1'), [], new Model\Paths());
$propertyNameCollectionFactoryProphecy = $this->prophesize(PropertyNameCollectionFactoryInterface::class);
$resourceMetadataFactoryProphecy = $this->prophesize(ResourceMetadataFactoryInterface::class);
$propertyMetadataFactoryProphecy = $this->prophesize(PropertyMetadataFactoryInterface::class);
$resourceClassResolverProphecy = $this->prophesize(ResourceClassResolverInterface::class);
$operationPathResolver = new OperationPathResolver(new UnderscorePathSegmentNameGenerator());
$identifiersExtractorProphecy = $this->prophesize(IdentifiersExtractorInterface::class);

$openApiNormalizerProphecy = $this->prophesize(NormalizerInterface::class);
$openApiNormalizerProphecy->normalize($openapi, null, [])->willReturn([])->shouldBeCalled();

$normalizer = new DocumentationNormalizer(
$resourceMetadataFactoryProphecy->reveal(),
$propertyNameCollectionFactoryProphecy->reveal(),
$propertyMetadataFactoryProphecy->reveal(),
null,
null,
$operationPathResolver,
null,
null,
null, false,
'',
'',
'',
'',
[],
[],
null,
false,
'page',
false,
'itemsPerPage',
$formatsProvider ?? [],
false,
'pagination',
['spec_version' => 3],
[2, 3],
$identifiersExtractorProphecy->reveal(),
true,
$openApiNormalizerProphecy->reveal()
);

$this->assertTrue($normalizer->supportsNormalization($openapi, 'json'));
$this->assertEquals([], $normalizer->normalize($openapi));
}
}

0 comments on commit 56e2983

Please sign in to comment.