Skip to content

Commit

Permalink
fix(symfony): status at 200 when allowCreate is false (#5465)
Browse files Browse the repository at this point in the history
  • Loading branch information
Zowac authored Mar 17, 2023
1 parent 16a1a61 commit 1f23344
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 1 deletion.
29 changes: 29 additions & 0 deletions features/main/custom_put.feature
Original file line number Diff line number Diff line change
@@ -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"
}
"""
3 changes: 2 additions & 1 deletion src/Symfony/EventListener/RespondListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}

Expand Down
44 changes: 44 additions & 0 deletions tests/Fixtures/TestBundle/Entity/CustomPut.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<?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\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 <kevin@dunglas.fr>
*/
#[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 = '';
}

0 comments on commit 1f23344

Please sign in to comment.