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
23 changes: 15 additions & 8 deletions src/Symfony/Bundle/Resources/views/SwaggerUi/index.html.twig
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
<title>{% if title %}{{ title }} - {% endif %}API Platform</title>
{% endblock %}

{% set active_ui = app.request.query.get('ui', 'swagger_ui') %}
{% set active_ui = app.request.query.get('ui', reDocEnabled and not swaggerUiEnabled ? 're_doc' : 'swagger_ui') %}
{% set is_scalar = (scalarEnabled and not swaggerUiEnabled and not reDocEnabled) or (scalarEnabled and 'scalar' == active_ui) %}

{%- set csp_nonce_attr = cspNonce is defined and cspNonce is not null ? ' nonce="' ~ (cspNonce|e('html_attr')) ~ '"' : '' -%}
Expand Down Expand Up @@ -90,12 +90,19 @@
{% for format in formats|keys %}
<a href="{{ path(originalRoute, originalRouteParams|merge({'_format': format})) }}">{{ format }}</a>
{% endfor %}
<br>
Other API docs:
{% if swaggerUiEnabled and active_ui != 'swagger_ui' %}<a href="{{ path(originalRoute, originalRouteParams) }}">Swagger UI</a>{% endif %}
{% if reDocEnabled and active_ui != 're_doc' %}<a href="{{ path(originalRoute, originalRouteParams|merge({'ui': 're_doc'})) }}">ReDoc</a>{% endif %}
{% if scalarEnabled and active_ui != 'scalar' %}<a href="{{ path(originalRoute, originalRouteParams|merge({'ui': 'scalar'})) }}">Scalar</a>{% endif %}
{% if graphiQlEnabled %}<a href="{{ path('api_graphql_graphiql') }}" class="graphiql-link">GraphiQL</a>{% endif %}

{% set swaggerUiOption = swaggerUiEnabled and active_ui != 'swagger_ui' %}
{% set reDocOption = reDocEnabled and active_ui != 're_doc' %}
{% set scalarOption = scalarEnabled and active_ui != 'scalar' %}

{% if swaggerUiOption or reDocOption or scalarOption or graphiQlEnabled %}
<br>
Other API docs:
{% if swaggerUiOption %}<a href="{{ path(originalRoute, originalRouteParams) }}">Swagger UI</a>{% endif %}
{% if reDocOption %}<a href="{{ path(originalRoute, originalRouteParams|merge({'ui': 're_doc'})) }}">ReDoc</a>{% endif %}
{% if scalarOption %}<a href="{{ path(originalRoute, originalRouteParams|merge({'ui': 'scalar'})) }}">Scalar</a>{% endif %}
{% if graphiQlEnabled %}<a href="{{ path('api_graphql_graphiql') }}" class="graphiql-link">GraphiQL</a>{% endif %}
{% endif %}
</div>
</div>
</div>
Expand All @@ -105,7 +112,7 @@
{% if is_scalar %}
<script src="https://cdn.jsdelivr.net/npm/@scalar/api-reference"{{ csp_nonce_attr|raw }}></script>
<script src="{{ asset('bundles/apiplatform/init-scalar-ui.js', assetPackage) }}"{{ csp_nonce_attr|raw }}></script>
{% elseif (reDocEnabled and not swaggerUiEnabled) or (reDocEnabled and 're_doc' == active_ui) %}
{% elseif (reDocEnabled and 're_doc' == active_ui) %}
<script src="{{ asset('bundles/apiplatform/redoc/redoc.standalone.js', assetPackage) }}"{{ csp_nonce_attr|raw }}></script>
<script src="{{ asset('bundles/apiplatform/init-redoc-ui.js', assetPackage) }}"{{ csp_nonce_attr|raw }}></script>
{% else %}
Expand Down
69 changes: 69 additions & 0 deletions tests/Functional/RedocOtherApiDocLinkTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
<?php

/*
* This file is part of the API Platform project.
*
* (c) Kévin Dunglas <dunglas@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

declare(strict_types=1);

namespace ApiPlatform\Tests\Functional;

use ApiPlatform\Test\ApiTestCase;
use Symfony\Component\Config\Loader\LoaderInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;

class RedocOtherApiDocLinkAppKernel extends \AppKernel
{
public function getCacheDir(): string
{
return parent::getCacheDir().'/redoc_otherapidoc_link';
}

public function getLogDir(): string
{
return parent::getLogDir().'/redoc_otherapidoc_link';
}

protected function configureContainer(ContainerBuilder $c, LoaderInterface $loader): void
{
parent::configureContainer($c, $loader);

$loader->load(static function (ContainerBuilder $container): void {
$container->loadFromExtension('api_platform', [
'enable_swagger_ui' => false,
'enable_re_doc' => true,
'enable_scalar' => false,
'graphql' => ['enabled' => false],
]);

// the fixtures decorate a GraphQL service that is not registered once GraphQL is off
if ($container->hasDefinition('app.graphql.type_converter')) {
$container->removeDefinition('app.graphql.type_converter');
}
});
}
}

final class RedocOtherApiDocLinkTest extends ApiTestCase
{
protected static ?bool $alwaysBootKernel = true;

protected static function getKernelClass(): string
{
return RedocOtherApiDocLinkAppKernel::class;
}

public function testOtherApiDocsLinkAreHiddenWhenAllOptionsAreDisabled(): void
{
$client = self::createClient();
$client->request('GET', '/docs', ['headers' => ['Accept' => 'text/html']]);

$this->assertResponseIsSuccessful();
$this->assertStringNotContainsString('Other API docs:', $client->getResponse()->getContent());
}
}
69 changes: 69 additions & 0 deletions tests/Functional/SwaggerUiOtherApiDocLinkTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
<?php

/*
* This file is part of the API Platform project.
*
* (c) Kévin Dunglas <dunglas@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

declare(strict_types=1);

namespace ApiPlatform\Tests\Functional;

use ApiPlatform\Test\ApiTestCase;
use Symfony\Component\Config\Loader\LoaderInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;

class SwaggerUiOtherApiDocLinkAppKernel extends \AppKernel
{
public function getCacheDir(): string
{
return parent::getCacheDir().'/swagger_otherapidoc_link';
}

public function getLogDir(): string
{
return parent::getLogDir().'/swagger_otherapidoc_link';
}

protected function configureContainer(ContainerBuilder $c, LoaderInterface $loader): void
{
parent::configureContainer($c, $loader);

$loader->load(static function (ContainerBuilder $container): void {
$container->loadFromExtension('api_platform', [
'enable_swagger_ui' => true,
'enable_re_doc' => false,
'enable_scalar' => false,
'graphql' => ['enabled' => false],
]);

// the fixtures decorate a GraphQL service that is not registered once GraphQL is off
if ($container->hasDefinition('app.graphql.type_converter')) {
$container->removeDefinition('app.graphql.type_converter');
}
});
}
}

final class SwaggerUiOtherApiDocLinkTest extends ApiTestCase
{
protected static ?bool $alwaysBootKernel = true;

protected static function getKernelClass(): string
{
return SwaggerUiOtherApiDocLinkAppKernel::class;
}

public function testOtherApiDocsLinkAreHiddenWhenAllOptionsAreDisabled(): void
{
$client = self::createClient();
$client->request('GET', '/docs', ['headers' => ['Accept' => 'text/html']]);

$this->assertResponseIsSuccessful();
$this->assertStringNotContainsString('Other API docs:', $client->getResponse()->getContent());
}
}
Loading