From 901680bbe2977523ed0a77b687e47bf22986c40a Mon Sep 17 00:00:00 2001 From: Zowac Date: Thu, 16 Mar 2023 14:44:40 +0100 Subject: [PATCH] fix(symfony): checking of the allowCreate option to set the status --- features/main/custom_put.feature | 29 ++++++++++++ src/Symfony/EventListener/RespondListener.php | 3 +- .../Fixtures/TestBundle/Entity/CustomPut.php | 44 +++++++++++++++++++ 3 files changed, 75 insertions(+), 1 deletion(-) create mode 100644 features/main/custom_put.feature create mode 100644 tests/Fixtures/TestBundle/Entity/CustomPut.php diff --git a/features/main/custom_put.feature b/features/main/custom_put.feature new file mode 100644 index 00000000000..9b286b57cb4 --- /dev/null +++ b/features/main/custom_put.feature @@ -0,0 +1,29 @@ +Feature: Spec-compliant PUT support + As a client software developer + I need to be able to create or replace resources using the PUT HTTP method + + @createSchema + @!mongodb + Scenario: Get a correct status code when updating a resource that is not allowed to read nor to create + When I add "Content-Type" header equal to "application/ld+json" + And I send a "PUT" request to "/custom_puts/1" with body: + """ + { + "foo": "a", + "bar": "b" + } + """ + Then the response status code should be 200 + And the response status code should not be 201 + And the response should be in JSON + And the JSON should be equal to: + """ + { + "@context": "/contexts/CustomPut", + "@id": "/custom_puts/1", + "@type": "CustomPut", + "id": 1, + "foo": "a", + "bar": "b" + } + """ diff --git a/src/Symfony/EventListener/RespondListener.php b/src/Symfony/EventListener/RespondListener.php index a9a075ccd23..8948f38e690 100644 --- a/src/Symfony/EventListener/RespondListener.php +++ b/src/Symfony/EventListener/RespondListener.php @@ -16,6 +16,7 @@ use ApiPlatform\Api\IriConverterInterface; use ApiPlatform\Api\UrlGeneratorInterface; use ApiPlatform\Metadata\HttpOperation; +use ApiPlatform\Metadata\Put; use ApiPlatform\Metadata\Resource\Factory\ResourceMetadataCollectionFactoryInterface; use ApiPlatform\Util\OperationRequestInitiatorTrait; use ApiPlatform\Util\RequestAttributesExtractor; @@ -90,7 +91,7 @@ public function onKernelView(ViewEvent $event): void ) { $status = 301; $headers['Location'] = $this->iriConverter->getIriFromResource($request->attributes->get('data'), UrlGeneratorInterface::ABS_PATH, $operation); - } elseif (HttpOperation::METHOD_PUT === $method && !($attributes['previous_data'] ?? null) && null === $status) { + } elseif (HttpOperation::METHOD_PUT === $method && !($attributes['previous_data'] ?? null) && null === $status && ($operation instanceof Put && ($operation->getAllowCreate() ?? false))) { $status = Response::HTTP_CREATED; } diff --git a/tests/Fixtures/TestBundle/Entity/CustomPut.php b/tests/Fixtures/TestBundle/Entity/CustomPut.php new file mode 100644 index 00000000000..fbeb68c199f --- /dev/null +++ b/tests/Fixtures/TestBundle/Entity/CustomPut.php @@ -0,0 +1,44 @@ + + * + * 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\Fixtures\TestBundle\Entity; + +use ApiPlatform\Metadata\ApiResource; +use ApiPlatform\Metadata\Get; +use ApiPlatform\Metadata\Put; +use Doctrine\ORM\Mapping\Column; +use Doctrine\ORM\Mapping\Entity; +use Doctrine\ORM\Mapping\Id; + +/** + * @author Kévin Dunglas + */ +#[ApiResource( + operations: [new Get(), new Put(read: false, allowCreate: false)], + extraProperties: [ + 'custom_put' => true, + ] +)] +#[Entity] +class CustomPut +{ + #[Id] + #[Column] + public ?int $id = null; + + #[Column] + public string $foo = ''; + + #[Column] + public string $bar = ''; +}