api-platform / api-platform

Create REST and GraphQL APIs, scaffold Jamstack webapps, stream changes in real-time.
https://api-platform.com
MIT License
8.39k stars 945 forks source link

PHPUnit doesn't work with denormalization context #1942

Closed sta2m closed 3 years ago

sta2m commented 3 years ago

API Platform 2.6 / Symfony 5.3 / PHPUnit 9.5.5

Description

PUT request don't work in PHPUnit with a denormalization_context attribute in my entity. Entity is not modified.

Config Entity :

<?php
namespace App\Entity;

use ApiPlatform\Core\Annotation\ApiResource;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Serializer\Annotation\Groups;

/**
 * @ORM\Entity
 * @ApiResource(
 *     attributes={"security"="is_granted('ROLE_USER')"},
 *     collectionOperations={
 *          "get",
 *     },
 *     itemOperations={
 *         "get",
 *         "put"={
 *              "security"="is_granted('ROLE_ADMIN')",
 *              "denormalization_context"={
 *                  "groups"={"configs-put"}
 *              },
 *          }
 *     }
 *  )
 */

class Config
{
    /**
     *
     * @ORM\Id
     * @ORM\GeneratedValue
     * @ORM\Column(type="integer")
     */
    protected ?int $id = null;

    /**
     *
     * @ORM\Column(type="string", length=63)
     */
    protected string $cle = '';

    /**
     *
     * @ORM\Column(type="string", length=63)
     * @Groups({"configs-put"})
     */
    protected string $valeur = '';

    /**
     * @return int|null
     */
    public function getId(): ?int
    {
        return $this->id;
    }

    /**
     * @param int|null $id
     */
    public function setId(?int $id): void
    {
        $this->id = $id;
    }

    /**
     * @return string
     */
    public function getCle(): string
    {
        return $this->cle;
    }

    /**
     * @param string $cle
     */
    public function setCle(string $cle): void
    {
        $this->cle = $cle;
    }

    /**
     * @return string
     */
    public function getValeur(): string
    {
        return $this->valeur;
    }

    /**
     * @param string $valeur
     */
    public function setValeur(string $valeur): void
    {
        $this->valeur = $valeur;
    }
}

Working great with cURL :

curl --location --request PUT 'http://www.beaubourg.dev/configs/1' \
--header 'Authorization: Bearer .........' \
--header 'Content-Type: application/json' \
--data-raw '{
    "valeur" : "test"    
}'

Return :

{"@context":"\/contexts\/Config","@id":"\/configs\/1","@type":"Config","id":1,"cle":"notif_nombre_jour_changement_password","valeur":"test"}

With PHPUnit :

<?php

namespace App\Tests;

use ApiPlatform\Core\Bridge\Symfony\Bundle\Test\ApiTestCase;
use Hautelook\AliceBundle\PhpUnit\RefreshDatabaseTrait;

class ConfigsTest extends ApiTestCase
{
    // This trait provided by HautelookAliceBundle will take care of refreshing the database content to a known state before each test
    use RefreshDatabaseTrait;

    public function testPutConfigsByAdmin(): void
    {
        $response = static::createClient()->request('POST', '/login_check', ['json' => [
            'login' => 'admin',
            'password' => 'password',
        ]]);

        $content = json_decode($response->getContent(), true);
        $this->assertResponseIsSuccessful();

        $response = static::createClient()->request('PUT', '/configs/1',
            [
                'json' => [
                    "valeur" => "test"
                ],
                'headers' => [
                    'Content-Type' => 'application/json',
                    "Authorization" => 'Bearer ' . $content['token']
                ],
            ]
        );
        print_r($response->getContent());exit;

        $this->assertJsonContains([
                'valeur' => 'test'
            ]
        );
    }
}

Doesn't work. Return :

{"@context":"\/contexts\/Config","@id":"\/configs\/1","@type":"Config","id":1,"cle":"notif_nombre_jour_changement_password","valeur":"60"}

If I remove denormalization_context in my config entity, it work !

Any idea ?

sta2m commented 3 years ago

Ok, sorry. After deleting ./var/cache/test, all is ok.