Skip to content

Commit

Permalink
fix(openapi): not forbidden response on openAPI doc
Browse files Browse the repository at this point in the history
  • Loading branch information
vinceAmstoutz committed Jan 7, 2025
1 parent f8dae8e commit c6a756c
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 1 deletion.
4 changes: 4 additions & 0 deletions src/OpenApi/Factory/OpenApiFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -408,6 +408,10 @@ private function collectPaths(ApiResource $resource, ResourceMetadataCollection
}
}

if (true === $overrideResponses && !isset($existingResponses[403]) && $operation->getSecurity()) {
$openapiOperation = $openapiOperation->withResponse(403, new Response('Forbidden'));
}

if (true === $overrideResponses && !$operation instanceof CollectionOperationInterface && 'POST' !== $operation->getMethod()) {
if (!isset($existingResponses[404])) {
$openapiOperation = $openapiOperation->withResponse(404, new Response('Resource not found'));
Expand Down
29 changes: 28 additions & 1 deletion src/OpenApi/Tests/Factory/OpenApiFactoryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
use ApiPlatform\OpenApi\Tests\Fixtures\Dummy;
use ApiPlatform\OpenApi\Tests\Fixtures\DummyErrorResource;
use ApiPlatform\OpenApi\Tests\Fixtures\DummyFilter;
use ApiPlatform\OpenApi\Tests\Fixtures\Issue6872\Diamond;
use ApiPlatform\OpenApi\Tests\Fixtures\OutputDto;
use ApiPlatform\State\Pagination\PaginationOptions;
use ApiPlatform\Tests\Fixtures\TestBundle\ApiResource\WithParameter;
Expand All @@ -85,6 +86,7 @@ public function testInvoke(): void
$baseOperation = (new HttpOperation())->withTypes(['http://schema.example.com/Dummy'])->withInputFormats(self::OPERATION_FORMATS['input_formats'])->withOutputFormats(self::OPERATION_FORMATS['output_formats'])->withClass(Dummy::class)->withOutput([
'class' => OutputDto::class,
])->withPaginationClientItemsPerPage(true)->withShortName('Dummy')->withDescription('This is a dummy');

$dummyResourceWebhook = (new ApiResource())->withOperations(new Operations([
'dummy webhook' => (new Get())->withUriTemplate('/dummy/{id}')->withShortName('short')->withOpenapi(new Webhook('first webhook')),
'an other dummy webhook' => (new Post())->withUriTemplate('/dummies')->withShortName('short something')->withOpenapi(new Webhook('happy webhook', new Model\PathItem(post: new Operation(
Expand Down Expand Up @@ -272,13 +274,23 @@ public function testInvoke(): void
]))->withOperation($baseOperation),
]));

$diamondResource = (new ApiResource())
->withOperations(new Operations([
'getDiamondCollection' => (new GetCollection(uriTemplate: '/diamonds'))
->withSecurity("is_granted('ROLE_USER')")
->withOperation($baseOperation),
'putDiamond' => (new Put(uriTemplate: '/diamond/{id}'))
->withOperation($baseOperation),
]));

$resourceNameCollectionFactoryProphecy = $this->prophesize(ResourceNameCollectionFactoryInterface::class);
$resourceNameCollectionFactoryProphecy->create()->shouldBeCalled()->willReturn(new ResourceNameCollection([Dummy::class, WithParameter::class]));
$resourceNameCollectionFactoryProphecy->create()->shouldBeCalled()->willReturn(new ResourceNameCollection([Dummy::class, WithParameter::class, Diamond::class]));

$resourceCollectionMetadataFactoryProphecy = $this->prophesize(ResourceMetadataCollectionFactoryInterface::class);
$resourceCollectionMetadataFactoryProphecy->create(Dummy::class)->shouldBeCalled()->willReturn(new ResourceMetadataCollection(Dummy::class, [$dummyResource, $dummyResourceWebhook]));
$resourceCollectionMetadataFactoryProphecy->create(DummyErrorResource::class)->shouldBeCalled()->willReturn(new ResourceMetadataCollection(DummyErrorResource::class, [new ApiResource(operations: [new ErrorOperation(name: 'err', description: 'nice one!')])]));
$resourceCollectionMetadataFactoryProphecy->create(WithParameter::class)->shouldBeCalled()->willReturn(new ResourceMetadataCollection(WithParameter::class, [$parameterResource]));
$resourceCollectionMetadataFactoryProphecy->create(Diamond::class)->shouldBeCalled()->willReturn(new ResourceMetadataCollection(Diamond::class, [$diamondResource]));

$propertyNameCollectionFactoryProphecy = $this->prophesize(PropertyNameCollectionFactoryInterface::class);
$propertyNameCollectionFactoryProphecy->create(Dummy::class, Argument::any())->shouldBeCalled()->willReturn(new PropertyNameCollection(['id', 'name', 'description', 'dummyDate', 'enum']));
Expand Down Expand Up @@ -1171,5 +1183,20 @@ public function testInvoke(): void
],
deprecated: false
), $paths->getPath('/erroredDummies')->getGet());

$diamondsGetPath = $paths->getPath('/diamonds');
$diamondGetOperation = $diamondsGetPath->getGet();
$diamondGetResponses = $diamondGetOperation->getResponses();

$this->assertNotNull($diamondGetOperation);
$this->assertArrayHasKey('403', $diamondGetResponses);
$this->assertSame('Forbidden', $diamondGetResponses['403']->getDescription());

$diamondsPutPath = $paths->getPath('/diamond/{id}');
$diamondPutOperation = $diamondsPutPath->getPut();
$diamondPutResponses = $diamondPutOperation->getResponses();

$this->assertNotNull($diamondPutOperation);
$this->assertArrayNotHasKey('403', $diamondPutResponses);
}
}
19 changes: 19 additions & 0 deletions src/OpenApi/Tests/Fixtures/Issue6872/Diamond.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php

/*
* This file is part of the API Platform project.
*
* (c) Kévin Dunglas <[email protected]>
*
* 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\OpenApi\Tests\Fixtures\Issue6872;

class Diamond
{
public float $weight;
}

0 comments on commit c6a756c

Please sign in to comment.