Skip to content

Commit

Permalink
Add behat test data transformer initializer
Browse files Browse the repository at this point in the history
  • Loading branch information
soyuka committed Sep 1, 2020
1 parent bae152d commit d04fa9c
Show file tree
Hide file tree
Showing 10 changed files with 228 additions and 2 deletions.
24 changes: 24 additions & 0 deletions features/bootstrap/DoctrineContext.php
Expand Up @@ -53,6 +53,7 @@
use ApiPlatform\Core\Tests\Fixtures\TestBundle\Document\FooDummy as FooDummyDocument;
use ApiPlatform\Core\Tests\Fixtures\TestBundle\Document\FourthLevel as FourthLevelDocument;
use ApiPlatform\Core\Tests\Fixtures\TestBundle\Document\Greeting as GreetingDocument;
use ApiPlatform\Core\Tests\Fixtures\TestBundle\Document\InitializeInput as InitializeInputDocument;
use ApiPlatform\Core\Tests\Fixtures\TestBundle\Document\MaxDepthDummy as MaxDepthDummyDocument;
use ApiPlatform\Core\Tests\Fixtures\TestBundle\Document\NetworkPathDummy as NetworkPathDummyDocument;
use ApiPlatform\Core\Tests\Fixtures\TestBundle\Document\NetworkPathRelationDummy as NetworkPathRelationDummyDocument;
Expand Down Expand Up @@ -117,6 +118,7 @@
use ApiPlatform\Core\Tests\Fixtures\TestBundle\Entity\FooDummy;
use ApiPlatform\Core\Tests\Fixtures\TestBundle\Entity\FourthLevel;
use ApiPlatform\Core\Tests\Fixtures\TestBundle\Entity\Greeting;
use ApiPlatform\Core\Tests\Fixtures\TestBundle\Entity\InitializeInput;
use ApiPlatform\Core\Tests\Fixtures\TestBundle\Entity\InternalUser;
use ApiPlatform\Core\Tests\Fixtures\TestBundle\Entity\MaxDepthDummy;
use ApiPlatform\Core\Tests\Fixtures\TestBundle\Entity\NetworkPathDummy;
Expand Down Expand Up @@ -1589,6 +1591,20 @@ public function thereAreNetworkPathDummies(int $nb)
$this->manager->flush();
}

/**
* @Given there is an InitializeInput object with id :id
*/
public function thereIsAnInitializeInput(int $id)
{
$initializeInput = $this->buildInitializeInput();
$initializeInput->id = $id;
$initializeInput->manager = 'Orwell';
$initializeInput->name = '1984';

$this->manager->persist($initializeInput);
$this->manager->flush();
}

private function isOrm(): bool
{
return null !== $this->schemaTool;
Expand Down Expand Up @@ -2006,4 +2022,12 @@ private function buildNetworkPathRelationDummy()
{
return $this->isOrm() ? new NetworkPathRelationDummy() : new NetworkPathRelationDummyDocument();
}

/**
* @return InitializeInput|InitializeInputDocument
*/
private function buildInitializeInput()
{
return $this->isOrm() ? new InitializeInput() : new InitializeInputDocument();
}
}
23 changes: 23 additions & 0 deletions features/jsonld/input_output.feature
Expand Up @@ -317,3 +317,26 @@ Feature: JSON-LD DTO input and output
"data": 123
}
"""

@createSchema
Scenario: Initialize input data with a DataTransformerInitializer
Given there is an InitializeInput object with id 1
When I send a "PUT" request to "/initialize_inputs/1" with body:
"""
{
"name": "La peste"
}
"""
Then the response status code should be 200
And the response should be in JSON
And the JSON should be equal to:
"""
{
"@context": "/contexts/InitializeInput",
"@id": "/initialize_inputs/1",
"@type": "InitializeInput",
"id": 1,
"manager": "Orwell",
"name": "La peste"
}
"""
Expand Up @@ -30,6 +30,7 @@
use ApiPlatform\Core\DataProvider\CollectionDataProviderInterface;
use ApiPlatform\Core\DataProvider\ItemDataProviderInterface;
use ApiPlatform\Core\DataProvider\SubresourceDataProviderInterface;
use ApiPlatform\Core\DataTransformer\DataTransformerInitializerInterface;
use ApiPlatform\Core\DataTransformer\DataTransformerInterface;
use ApiPlatform\Core\GraphQl\Error\ErrorHandlerInterface;
use ApiPlatform\Core\GraphQl\Resolver\MutationResolverInterface;
Expand Down
4 changes: 3 additions & 1 deletion src/DataTransformer/DataTransformerInitializerInterface.php
Expand Up @@ -19,6 +19,8 @@ interface DataTransformerInitializerInterface extends DataTransformerInterface
* Creates a new DTO object that the data will then be serialized into (using object_to_populate).
*
* This is useful to "initialize" the DTO object based on the current resource's data.
*
* @return object|null
*/
public function initialize(string $inputClass, array $context = []): ?object;
public function initialize(string $inputClass, array $context = []);
}
@@ -0,0 +1,62 @@
<?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\Core\Tests\Fixtures\TestBundle\DataTransformer;

use ApiPlatform\Core\DataTransformer\DataTransformerInitializerInterface;
use ApiPlatform\Core\Serializer\AbstractItemNormalizer;
use ApiPlatform\Core\Tests\Fixtures\TestBundle\Document\InitializeInput as InitializeInputDocument;
use ApiPlatform\Core\Tests\Fixtures\TestBundle\Dto\InitializeInputDto;
use ApiPlatform\Core\Tests\Fixtures\TestBundle\Entity\InitializeInput;

final class InitializeInputDataTransformer implements DataTransformerInitializerInterface
{
/**
* {@inheritdoc}
*/
public function transform($object, string $to, array $context = [])
{
/** @var InitializeInputDto */
$data = $object;

/** @var InitializeInput|InitializeInputDocument */
$resourceObject = $context[AbstractItemNormalizer::OBJECT_TO_POPULATE] ?? new $context['resource_class']();
$resourceObject->name = $data->name;

return $resourceObject;
}

/**
* {@inheritdoc}
*/
public function initialize(string $inputClass, array $context = [])
{
$currentResource = $context[AbstractItemNormalizer::OBJECT_TO_POPULATE] ?? null;
if (!$currentResource) {
return new InitializeInputDto();
}

$dto = new InitializeInputDto();
$dto->manager = $currentResource->manager;

return $dto;
}

/**
* {@inheritdoc}
*/
public function supportsTransformation($data, string $to, array $context = []): bool
{
return (InitializeInput::class === $to || InitializeInputDocument::class === $to) && InitializeInputDto::class === ($context['input']['class'] ?? null);
}
}
40 changes: 40 additions & 0 deletions tests/Fixtures/TestBundle/Document/InitializeInput.php
@@ -0,0 +1,40 @@
<?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\Core\Tests\Fixtures\TestBundle\Document;

use ApiPlatform\Core\Annotation\ApiResource;
use ApiPlatform\Core\Tests\Fixtures\TestBundle\Dto\InitializeInputDto;
use Doctrine\ODM\MongoDB\Mapping\Annotations as ODM;

/**
* @ApiResource(input=InitializeInputDto::class)
* @ODM\Document
*/
class InitializeInput
{
/**
* @ODM\Id(strategy="NONE", type="integer")
*/
public $id;

/**
* @ODM\Field
*/
public $manager;

/**
* @ODM\Field
*/
public $name;
}
27 changes: 27 additions & 0 deletions tests/Fixtures/TestBundle/Dto/InitializeInputDto.php
@@ -0,0 +1,27 @@
<?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\Core\Tests\Fixtures\TestBundle\Dto;

class InitializeInputDto
{
/**
* @var string
*/
public $name;

/**
* @var string
*/
public $manager;
}
41 changes: 41 additions & 0 deletions tests/Fixtures/TestBundle/Entity/InitializeInput.php
@@ -0,0 +1,41 @@
<?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\Core\Tests\Fixtures\TestBundle\Entity;

use ApiPlatform\Core\Annotation\ApiResource;
use ApiPlatform\Core\Tests\Fixtures\TestBundle\Dto\InitializeInputDto;
use Doctrine\ORM\Mapping as ORM;

/**
* @ApiResource(input=InitializeInputDto::class)
* @ORM\Entity
*/
class InitializeInput
{
/**
* @ORM\Id
* @ORM\Column(type="integer")
*/
public $id;

/**
* @ORM\Column
*/
public $manager;

/**
* @ORM\Column
*/
public $name;
}
6 changes: 6 additions & 0 deletions tests/Fixtures/app/config/config_common.yml
Expand Up @@ -291,6 +291,12 @@ services:
tags:
- { name: 'api_platform.data_transformer' }

app.data_transformer.initialize_input:
class: 'ApiPlatform\Core\Tests\Fixtures\TestBundle\DataTransformer\InitializeInputDataTransformer'
public: false
tags:
- { name: 'api_platform.data_transformer' }

app.messenger_handler.messenger_with_response:
class: 'ApiPlatform\Core\Tests\Fixtures\TestBundle\MessengerHandler\MessengerWithResponseHandler'
public: false
Expand Down
2 changes: 1 addition & 1 deletion tests/Serializer/AbstractItemNormalizerTest.php
Expand Up @@ -429,7 +429,7 @@ public function testCanDenormalizeInputClassWithDifferentFieldsThanResourceClass
$resourceClassResolverProphecy = $this->prophesize(ResourceClassResolverInterface::class);
$resourceClassResolverProphecy->getResourceClass(null, DummyForAdditionalFields::class)->willReturn(DummyForAdditionalFields::class);

$inputDataTransformerProphecy = $this->prophesize(DataTransformerInterface::class);
$inputDataTransformerProphecy = $this->prophesize(DataTransformerInitializerInterface::class);
$inputDataTransformerProphecy->willImplement(DataTransformerInitializerInterface::class);
$inputDataTransformerProphecy->initialize(DummyForAdditionalFieldsInput::class, $cleanedContext)->willReturn($preHydratedDummy);
$inputDataTransformerProphecy->supportsTransformation($data, DummyForAdditionalFields::class, $augmentedContext)->willReturn(true);
Expand Down

0 comments on commit d04fa9c

Please sign in to comment.