diff --git a/features/main/crud.feature b/features/main/crud.feature
index 61b6a78a1b7..3cd5760ff4d 100644
--- a/features/main/crud.feature
+++ b/features/main/crud.feature
@@ -91,6 +91,12 @@ Feature: Create-Retrieve-Update-Delete
}
"""
+ Scenario: Create a resource with empty body
+ When I add "Content-Type" header equal to "application/ld+json"
+ And I send a "POST" request to "/dummies"
+ Then the response status code should be 400
+ And the JSON node "hydra:description" should be equal to "Syntax error"
+
Scenario: Get a not found exception
When I send a "GET" request to "/dummies/42"
Then the response status code should be 404
@@ -526,42 +532,8 @@ Feature: Create-Retrieve-Update-Delete
Scenario: Update a resource with empty body
When I add "Content-Type" header equal to "application/ld+json"
And I send a "PUT" request to "/dummies/1"
- Then the response status code should be 200
- And the response should be in JSON
- And the header "Content-Type" should be equal to "application/ld+json; charset=utf-8"
- And the header "Content-Location" should be equal to "/dummies/1"
- And the JSON should be equal to:
- """
- {
- "@context": "/contexts/Dummy",
- "@id": "/dummies/1",
- "@type": "Dummy",
- "description": null,
- "dummy": null,
- "dummyBoolean": null,
- "dummyDate": "2018-12-01T13:12:00+00:00",
- "dummyFloat": null,
- "dummyPrice": null,
- "relatedDummy": null,
- "relatedDummies": [],
- "jsonData": [
- {
- "key": "value1"
- },
- {
- "key": "value2"
- }
- ],
- "arrayData": [],
- "name_converted": null,
- "relatedOwnedDummy": null,
- "relatedOwningDummy": null,
- "id": 1,
- "name": "A nice dummy",
- "alias": null,
- "foo": null
- }
- """
+ Then the response status code should be 400
+ And the JSON node "hydra:description" should be equal to "Syntax error"
Scenario: Delete a resource
When I send a "DELETE" request to "/dummies/1"
diff --git a/src/Bridge/Symfony/Bundle/DependencyInjection/Configuration.php b/src/Bridge/Symfony/Bundle/DependencyInjection/Configuration.php
index 2aebccb946b..e1fecd99901 100644
--- a/src/Bridge/Symfony/Bundle/DependencyInjection/Configuration.php
+++ b/src/Bridge/Symfony/Bundle/DependencyInjection/Configuration.php
@@ -32,7 +32,7 @@
use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Messenger\MessageBusInterface;
-use Symfony\Component\Serializer\Exception\ExceptionInterface;
+use Symfony\Component\Serializer\Exception\ExceptionInterface as SerializerExceptionInterface;
/**
* The configuration of the bundle.
@@ -369,7 +369,7 @@ private function addExceptionToStatusSection(ArrayNodeDefinition $rootNode): voi
->children()
->arrayNode('exception_to_status')
->defaultValue([
- ExceptionInterface::class => Response::HTTP_BAD_REQUEST,
+ SerializerExceptionInterface::class => Response::HTTP_BAD_REQUEST,
InvalidArgumentException::class => Response::HTTP_BAD_REQUEST,
FilterValidationException::class => Response::HTTP_BAD_REQUEST,
OptimisticLockException::class => Response::HTTP_CONFLICT,
diff --git a/src/Bridge/Symfony/Bundle/Resources/config/api.xml b/src/Bridge/Symfony/Bundle/Resources/config/api.xml
index 458a990747c..47e1aa9f81d 100644
--- a/src/Bridge/Symfony/Bundle/Resources/config/api.xml
+++ b/src/Bridge/Symfony/Bundle/Resources/config/api.xml
@@ -154,6 +154,7 @@
+
@@ -161,7 +162,7 @@
-
+
@@ -170,6 +171,7 @@
+
@@ -177,6 +179,7 @@
+
diff --git a/src/EventListener/DeserializeListener.php b/src/EventListener/DeserializeListener.php
index 8bb02323655..2eecf7682db 100644
--- a/src/EventListener/DeserializeListener.php
+++ b/src/EventListener/DeserializeListener.php
@@ -16,6 +16,8 @@
use ApiPlatform\Core\Api\FormatMatcher;
use ApiPlatform\Core\Api\FormatsProviderInterface;
use ApiPlatform\Core\Exception\InvalidArgumentException;
+use ApiPlatform\Core\Metadata\Resource\Factory\ResourceMetadataFactoryInterface;
+use ApiPlatform\Core\Metadata\Resource\ToggleableOperationAttributeTrait;
use ApiPlatform\Core\Serializer\SerializerContextBuilderInterface;
use ApiPlatform\Core\Util\RequestAttributesExtractor;
use Symfony\Component\HttpFoundation\Request;
@@ -31,6 +33,10 @@
*/
final class DeserializeListener
{
+ use ToggleableOperationAttributeTrait;
+
+ public const OPERATION_ATTRIBUTE_KEY = 'deserialize';
+
private $serializer;
private $serializerContextBuilder;
private $formats = [];
@@ -40,7 +46,7 @@ final class DeserializeListener
/**
* @throws InvalidArgumentException
*/
- public function __construct(SerializerInterface $serializer, SerializerContextBuilderInterface $serializerContextBuilder, /* FormatsProviderInterface */$formatsProvider)
+ public function __construct(SerializerInterface $serializer, SerializerContextBuilderInterface $serializerContextBuilder, /* FormatsProviderInterface */$formatsProvider, ResourceMetadataFactoryInterface $resourceMetadataFactory = null)
{
$this->serializer = $serializer;
$this->serializerContextBuilder = $serializerContextBuilder;
@@ -54,6 +60,7 @@ public function __construct(SerializerInterface $serializer, SerializerContextBu
$this->formatsProvider = $formatsProvider;
}
+ $this->resourceMetadataFactory = $resourceMetadataFactory;
}
/**
@@ -69,18 +76,12 @@ public function onKernelRequest(GetResponseEvent $event): void
|| $request->isMethodSafe(false)
|| !($attributes = RequestAttributesExtractor::extractAttributes($request))
|| !$attributes['receive']
- || (
- '' === ($requestContent = $request->getContent())
- && ('POST' === $method || 'PUT' === $method)
- )
+ || $this->isOperationAttributeDisabled($attributes, self::OPERATION_ATTRIBUTE_KEY)
) {
return;
}
$context = $this->serializerContextBuilder->createFromRequest($request, false, $attributes);
- if (isset($context['input']) && \array_key_exists('class', $context['input']) && null === $context['input']['class']) {
- return;
- }
// BC check to be removed in 3.0
if (null !== $this->formatsProvider) {
@@ -96,9 +97,7 @@ public function onKernelRequest(GetResponseEvent $event): void
$request->attributes->set(
'data',
- $this->serializer->deserialize(
- $requestContent, $context['resource_class'], $format, $context
- )
+ $this->serializer->deserialize($request->getContent(), $context['resource_class'], $format, $context)
);
}
diff --git a/src/EventListener/ReadListener.php b/src/EventListener/ReadListener.php
index 0116f6e0322..d4e9215dcf2 100644
--- a/src/EventListener/ReadListener.php
+++ b/src/EventListener/ReadListener.php
@@ -20,6 +20,8 @@
use ApiPlatform\Core\Exception\InvalidIdentifierException;
use ApiPlatform\Core\Exception\RuntimeException;
use ApiPlatform\Core\Identifier\IdentifierConverterInterface;
+use ApiPlatform\Core\Metadata\Resource\Factory\ResourceMetadataFactoryInterface;
+use ApiPlatform\Core\Metadata\Resource\ToggleableOperationAttributeTrait;
use ApiPlatform\Core\Serializer\SerializerContextBuilderInterface;
use ApiPlatform\Core\Util\RequestAttributesExtractor;
use ApiPlatform\Core\Util\RequestParser;
@@ -34,16 +36,20 @@
final class ReadListener
{
use OperationDataProviderTrait;
+ use ToggleableOperationAttributeTrait;
+
+ public const OPERATION_ATTRIBUTE_KEY = 'read';
private $serializerContextBuilder;
- public function __construct(CollectionDataProviderInterface $collectionDataProvider, ItemDataProviderInterface $itemDataProvider, SubresourceDataProviderInterface $subresourceDataProvider = null, SerializerContextBuilderInterface $serializerContextBuilder = null, IdentifierConverterInterface $identifierConverter = null)
+ public function __construct(CollectionDataProviderInterface $collectionDataProvider, ItemDataProviderInterface $itemDataProvider, SubresourceDataProviderInterface $subresourceDataProvider = null, SerializerContextBuilderInterface $serializerContextBuilder = null, IdentifierConverterInterface $identifierConverter = null, ResourceMetadataFactoryInterface $resourceMetadataFactory = null)
{
$this->collectionDataProvider = $collectionDataProvider;
$this->itemDataProvider = $itemDataProvider;
$this->subresourceDataProvider = $subresourceDataProvider;
$this->serializerContextBuilder = $serializerContextBuilder;
$this->identifierConverter = $identifierConverter;
+ $this->resourceMetadataFactory = $resourceMetadataFactory;
}
/**
@@ -57,6 +63,8 @@ public function onKernelRequest(GetResponseEvent $event): void
if (
!($attributes = RequestAttributesExtractor::extractAttributes($request))
|| !$attributes['receive']
+ || $request->isMethod('POST') && isset($attributes['collection_operation_name'])
+ || $this->isOperationAttributeDisabled($attributes, self::OPERATION_ATTRIBUTE_KEY)
) {
return;
}
@@ -74,7 +82,7 @@ public function onKernelRequest(GetResponseEvent $event): void
}
if (isset($attributes['collection_operation_name'])) {
- $request->attributes->set('data', $request->isMethod('POST') ? null : $this->getCollectionData($attributes, $context));
+ $request->attributes->set('data', $this->getCollectionData($attributes, $context));
return;
}
diff --git a/src/EventListener/SerializeListener.php b/src/EventListener/SerializeListener.php
index 7598bcbf534..bfb9abd318b 100644
--- a/src/EventListener/SerializeListener.php
+++ b/src/EventListener/SerializeListener.php
@@ -14,6 +14,8 @@
namespace ApiPlatform\Core\EventListener;
use ApiPlatform\Core\Exception\RuntimeException;
+use ApiPlatform\Core\Metadata\Resource\Factory\ResourceMetadataFactoryInterface;
+use ApiPlatform\Core\Metadata\Resource\ToggleableOperationAttributeTrait;
use ApiPlatform\Core\Serializer\ResourceList;
use ApiPlatform\Core\Serializer\SerializerContextBuilderInterface;
use ApiPlatform\Core\Util\RequestAttributesExtractor;
@@ -32,13 +34,18 @@
*/
final class SerializeListener
{
+ use ToggleableOperationAttributeTrait;
+
+ public const OPERATION_ATTRIBUTE_KEY = 'serialize';
+
private $serializer;
private $serializerContextBuilder;
- public function __construct(SerializerInterface $serializer, SerializerContextBuilderInterface $serializerContextBuilder)
+ public function __construct(SerializerInterface $serializer, SerializerContextBuilderInterface $serializerContextBuilder, ResourceMetadataFactoryInterface $resourceMetadataFactory = null)
{
$this->serializer = $serializer;
$this->serializerContextBuilder = $serializerContextBuilder;
+ $this->resourceMetadataFactory = $resourceMetadataFactory;
}
/**
@@ -49,7 +56,11 @@ public function onKernelView(GetResponseForControllerResultEvent $event): void
$controllerResult = $event->getControllerResult();
$request = $event->getRequest();
- if ($controllerResult instanceof Response || !(($attributes = RequestAttributesExtractor::extractAttributes($request))['respond'] ?? $request->attributes->getBoolean('_api_respond', false))) {
+ if (
+ $controllerResult instanceof Response
+ || !(($attributes = RequestAttributesExtractor::extractAttributes($request))['respond'] ?? $request->attributes->getBoolean('_api_respond', false))
+ || $attributes && $this->isOperationAttributeDisabled($attributes, self::OPERATION_ATTRIBUTE_KEY)
+ ) {
return;
}
diff --git a/src/EventListener/WriteListener.php b/src/EventListener/WriteListener.php
index 844205860a9..26ae4829baa 100644
--- a/src/EventListener/WriteListener.php
+++ b/src/EventListener/WriteListener.php
@@ -16,7 +16,9 @@
use ApiPlatform\Core\Api\IriConverterInterface;
use ApiPlatform\Core\DataPersister\DataPersisterInterface;
use ApiPlatform\Core\Metadata\Resource\Factory\ResourceMetadataFactoryInterface;
+use ApiPlatform\Core\Metadata\Resource\ToggleableOperationAttributeTrait;
use ApiPlatform\Core\Util\RequestAttributesExtractor;
+use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Event\GetResponseForControllerResultEvent;
/**
@@ -27,6 +29,10 @@
*/
final class WriteListener
{
+ use ToggleableOperationAttributeTrait;
+
+ public const OPERATION_ATTRIBUTE_KEY = 'write';
+
private $dataPersister;
private $iriConverter;
private $resourceMetadataFactory;
@@ -43,12 +49,19 @@ public function __construct(DataPersisterInterface $dataPersister, IriConverterI
*/
public function onKernelView(GetResponseForControllerResultEvent $event): void
{
+ $controllerResult = $event->getControllerResult();
$request = $event->getRequest();
- if ($request->isMethodSafe(false) || !($attributes = RequestAttributesExtractor::extractAttributes($request)) || !$attributes['persist']) {
+
+ if (
+ $controllerResult instanceof Response
+ || $request->isMethodSafe(false)
+ || !($attributes = RequestAttributesExtractor::extractAttributes($request))
+ || !$attributes['persist']
+ || $this->isOperationAttributeDisabled($attributes, self::OPERATION_ATTRIBUTE_KEY)
+ ) {
return;
}
- $controllerResult = $event->getControllerResult();
if (!$this->dataPersister->supports($controllerResult, $attributes)) {
return;
}
diff --git a/src/Metadata/Resource/Factory/InputOutputResourceMetadataFactory.php b/src/Metadata/Resource/Factory/InputOutputResourceMetadataFactory.php
index 7702f558617..c5809ffb0c6 100644
--- a/src/Metadata/Resource/Factory/InputOutputResourceMetadataFactory.php
+++ b/src/Metadata/Resource/Factory/InputOutputResourceMetadataFactory.php
@@ -66,12 +66,20 @@ private function getTransformedOperations(array $operations, array $resourceAttr
$operation['output'] = isset($operation['output']) ? $this->transformInputOutput($operation['output']) : $resourceAttributes['output'];
if (
- !isset($operation['status'])
- && isset($operation['output'])
+ isset($operation['input'])
+ && \array_key_exists('class', $operation['input'])
+ && null === $operation['input']['class']
+ ) {
+ $operation['deserialize'] ?? $operation['deserialize'] = false;
+ $operation['validate'] ?? $operation['validate'] = false;
+ }
+
+ if (
+ isset($operation['output'])
&& \array_key_exists('class', $operation['output'])
&& null === $operation['output']['class']
) {
- $operation['status'] = 204;
+ $operation['status'] ?? $operation['status'] = 204;
}
}
diff --git a/src/Metadata/Resource/ToggleableOperationAttributeTrait.php b/src/Metadata/Resource/ToggleableOperationAttributeTrait.php
new file mode 100644
index 00000000000..3551faf6f24
--- /dev/null
+++ b/src/Metadata/Resource/ToggleableOperationAttributeTrait.php
@@ -0,0 +1,38 @@
+
+ *
+ * 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\Metadata\Resource;
+
+use ApiPlatform\Core\Metadata\Resource\Factory\ResourceMetadataFactoryInterface;
+
+/**
+ * @internal
+ */
+trait ToggleableOperationAttributeTrait
+{
+ /**
+ * @var ResourceMetadataFactoryInterface|null
+ */
+ private $resourceMetadataFactory;
+
+ private function isOperationAttributeDisabled(array $attributes, string $attribute, bool $default = false, bool $resourceFallback = true): bool
+ {
+ if (null === $this->resourceMetadataFactory) {
+ return $default;
+ }
+
+ $resourceMetadata = $this->resourceMetadataFactory->create($attributes['resource_class']);
+
+ return !((bool) $resourceMetadata->getOperationAttribute($attributes, $attribute, !$default, $resourceFallback));
+ }
+}
diff --git a/src/Validator/EventListener/ValidateListener.php b/src/Validator/EventListener/ValidateListener.php
index 9ab4503676d..ff1f00fd3eb 100644
--- a/src/Validator/EventListener/ValidateListener.php
+++ b/src/Validator/EventListener/ValidateListener.php
@@ -15,8 +15,10 @@
use ApiPlatform\Core\Bridge\Symfony\Validator\Exception\ValidationException;
use ApiPlatform\Core\Metadata\Resource\Factory\ResourceMetadataFactoryInterface;
+use ApiPlatform\Core\Metadata\Resource\ToggleableOperationAttributeTrait;
use ApiPlatform\Core\Util\RequestAttributesExtractor;
use ApiPlatform\Core\Validator\ValidatorInterface;
+use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Event\GetResponseForControllerResultEvent;
/**
@@ -26,6 +28,10 @@
*/
final class ValidateListener
{
+ use ToggleableOperationAttributeTrait;
+
+ public const OPERATION_ATTRIBUTE_KEY = 'validate';
+
private $validator;
private $resourceMetadataFactory;
@@ -42,23 +48,23 @@ public function __construct(ValidatorInterface $validator, ResourceMetadataFacto
*/
public function onKernelView(GetResponseForControllerResultEvent $event): void
{
+ $controllerResult = $event->getControllerResult();
$request = $event->getRequest();
+
if (
- $request->isMethodSafe(false)
+ $controllerResult instanceof Response
+ || $request->isMethodSafe(false)
|| $request->isMethod('DELETE')
|| !($attributes = RequestAttributesExtractor::extractAttributes($request))
|| !$attributes['receive']
+ || $this->isOperationAttributeDisabled($attributes, self::OPERATION_ATTRIBUTE_KEY)
) {
return;
}
$resourceMetadata = $this->resourceMetadataFactory->create($attributes['resource_class']);
- $inputMetadata = $resourceMetadata->getOperationAttribute($attributes, 'input', [], true);
- if (\array_key_exists('class', $inputMetadata) && null === $inputMetadata['class']) {
- return;
- }
$validationGroups = $resourceMetadata->getOperationAttribute($attributes, 'validation_groups', null, true);
- $this->validator->validate($event->getControllerResult(), ['groups' => $validationGroups]);
+ $this->validator->validate($controllerResult, ['groups' => $validationGroups]);
}
}
diff --git a/tests/Bridge/Symfony/Validator/EventListener/ValidateListenerTest.php b/tests/Bridge/Symfony/Validator/EventListener/ValidateListenerTest.php
index 24acf3b971e..781116e84f7 100644
--- a/tests/Bridge/Symfony/Validator/EventListener/ValidateListenerTest.php
+++ b/tests/Bridge/Symfony/Validator/EventListener/ValidateListenerTest.php
@@ -37,18 +37,17 @@ class ValidateListenerTest extends TestCase
public function testNotAnApiPlatformRequest()
{
$validatorProphecy = $this->prophesize(ValidatorInterface::class);
- $validatorProphecy->validate()->shouldNotBeCalled();
+ $validatorProphecy->validate(Argument::cetera())->shouldNotBeCalled();
$validator = $validatorProphecy->reveal();
$resourceMetadataFactoryProphecy = $this->prophesize(ResourceMetadataFactoryInterface::class);
- $resourceMetadataFactoryProphecy->create()->shouldNotBeCalled();
$resourceMetadataFactory = $resourceMetadataFactoryProphecy->reveal();
$request = new Request();
$request->setMethod('POST');
$event = $this->prophesize(GetResponseForControllerResultEvent::class);
- $event->getRequest()->willReturn($request)->shouldBeCalled();
+ $event->getRequest()->willReturn($request);
$listener = new ValidateListener($validator, $resourceMetadataFactory);
$listener->onKernelView($event->reveal());
diff --git a/tests/EventListener/DeserializeListenerTest.php b/tests/EventListener/DeserializeListenerTest.php
index a28d72527f2..16426e65798 100644
--- a/tests/EventListener/DeserializeListenerTest.php
+++ b/tests/EventListener/DeserializeListenerTest.php
@@ -15,7 +15,10 @@
use ApiPlatform\Core\Api\FormatsProviderInterface;
use ApiPlatform\Core\EventListener\DeserializeListener;
+use ApiPlatform\Core\Metadata\Resource\Factory\ResourceMetadataFactoryInterface;
+use ApiPlatform\Core\Metadata\Resource\ResourceMetadata;
use ApiPlatform\Core\Serializer\SerializerContextBuilderInterface;
+use ApiPlatform\Core\Tests\Fixtures\TestBundle\Entity\Dummy;
use PHPUnit\Framework\TestCase;
use Prophecy\Argument;
use Symfony\Component\HttpFoundation\Request;
@@ -40,7 +43,7 @@ public function testDoNotCallWhenRequestMethodIsSafe()
$eventProphecy->getRequest()->willReturn($request)->shouldBeCalled();
$serializerProphecy = $this->prophesize(SerializerInterface::class);
- $serializerProphecy->deserialize()->shouldNotBeCalled();
+ $serializerProphecy->deserialize(Argument::cetera())->shouldNotBeCalled();
$serializerContextBuilderProphecy = $this->prophesize(SerializerContextBuilderInterface::class);
$serializerContextBuilderProphecy->createFromRequest(Argument::type(Request::class), false, Argument::type('array'))->shouldNotBeCalled();
@@ -52,20 +55,16 @@ public function testDoNotCallWhenRequestMethodIsSafe()
$listener->onKernelRequest($eventProphecy->reveal());
}
- /**
- * @dataProvider allowedEmptyRequestMethodsProvider
- */
- public function testDoNotCallWhenSendingAndEmptyRequestContent($method)
+ public function testDoNotCallWhenRequestNotManaged()
{
$eventProphecy = $this->prophesize(GetResponseEvent::class);
- $request = new Request([], [], ['data' => new \stdClass(), '_api_resource_class' => 'Foo', '_api_item_operation_name' => 'put'], [], [], [], '');
- $request->setMethod($method);
- $request->headers->set('Content-Type', 'application/json');
+ $request = new Request([], [], ['data' => new \stdClass()], [], [], [], '{}');
+ $request->setMethod('POST');
$eventProphecy->getRequest()->willReturn($request)->shouldBeCalled();
$serializerProphecy = $this->prophesize(SerializerInterface::class);
- $serializerProphecy->deserialize()->shouldNotBeCalled();
+ $serializerProphecy->deserialize(Argument::cetera())->shouldNotBeCalled();
$serializerContextBuilderProphecy = $this->prophesize(SerializerContextBuilderInterface::class);
$serializerContextBuilderProphecy->createFromRequest(Argument::type(Request::class), false, Argument::type('array'))->shouldNotBeCalled();
@@ -77,71 +76,51 @@ public function testDoNotCallWhenSendingAndEmptyRequestContent($method)
$listener->onKernelRequest($eventProphecy->reveal());
}
- public function allowedEmptyRequestMethodsProvider()
- {
- return [['PUT'], ['POST']];
- }
-
- public function testDoNotCallWhenRequestNotManaged()
+ public function testDoNotDeserializeWhenReceiveFlagIsFalse()
{
- $eventProphecy = $this->prophesize(GetResponseEvent::class);
-
- $request = new Request([], [], ['data' => new \stdClass()], [], [], [], '{}');
- $request->setMethod('POST');
- $eventProphecy->getRequest()->willReturn($request)->shouldBeCalled();
-
$serializerProphecy = $this->prophesize(SerializerInterface::class);
- $serializerProphecy->deserialize()->shouldNotBeCalled();
+ $serializerProphecy->deserialize(Argument::cetera())->shouldNotBeCalled();
$serializerContextBuilderProphecy = $this->prophesize(SerializerContextBuilderInterface::class);
- $serializerContextBuilderProphecy->createFromRequest(Argument::type(Request::class), false, Argument::type('array'))->shouldNotBeCalled();
$formatsProviderProphecy = $this->prophesize(FormatsProviderInterface::class);
- $formatsProviderProphecy->getFormatsFromAttributes(Argument::type('array'))->shouldNotBeCalled();
+
+ $request = new Request([], [], ['data' => new Dummy(), '_api_resource_class' => Dummy::class, '_api_collection_operation_name' => 'post', '_api_receive' => false]);
+ $request->setMethod('POST');
+
+ $eventProphecy = $this->prophesize(GetResponseEvent::class);
+ $eventProphecy->getRequest()->willReturn($request);
$listener = new DeserializeListener($serializerProphecy->reveal(), $serializerContextBuilderProphecy->reveal(), $formatsProviderProphecy->reveal());
$listener->onKernelRequest($eventProphecy->reveal());
}
- public function testDoNotCallWhenReceiveFlagIsFalse()
+ public function testDoNotDeserializeWhenDisabledInOperationAttribute()
{
- $eventProphecy = $this->prophesize(GetResponseEvent::class);
-
- $request = new Request([], [], ['data' => new \stdClass(), '_api_resource_class' => 'Foo', '_api_collection_operation_name' => 'post', '_api_receive' => false]);
- $request->setMethod('POST');
- $eventProphecy->getRequest()->willReturn($request)->shouldBeCalled();
-
$serializerProphecy = $this->prophesize(SerializerInterface::class);
- $serializerProphecy->deserialize()->shouldNotBeCalled();
+ $serializerProphecy->deserialize(Argument::cetera())->shouldNotBeCalled();
$serializerContextBuilderProphecy = $this->prophesize(SerializerContextBuilderInterface::class);
- $serializerContextBuilderProphecy->createFromRequest(Argument::type(Request::class), false, Argument::type('array'))->shouldNotBeCalled();
$formatsProviderProphecy = $this->prophesize(FormatsProviderInterface::class);
- $formatsProviderProphecy->getFormatsFromAttributes(Argument::type('array'))->shouldNotBeCalled();
+ $formatsProviderProphecy->getFormatsFromAttributes(Argument::type('array'));
- $listener = new DeserializeListener($serializerProphecy->reveal(), $serializerContextBuilderProphecy->reveal(), $formatsProviderProphecy->reveal());
- $listener->onKernelRequest($eventProphecy->reveal());
- }
+ $resourceMetadata = new ResourceMetadata('Dummy', null, null, [], [
+ 'post' => [
+ 'deserialize' => false,
+ ],
+ ]);
- public function testDoNotCallWhenInputClassDisabled()
- {
- $eventProphecy = $this->prophesize(GetResponseEvent::class);
+ $resourceMetadataFactoryProphecy = $this->prophesize(ResourceMetadataFactoryInterface::class);
+ $resourceMetadataFactoryProphecy->create(Dummy::class)->willReturn($resourceMetadata);
- $request = new Request([], [], ['data' => new \stdClass(), '_api_resource_class' => 'Foo', '_api_collection_operation_name' => 'post'], [], [], [], 'content');
+ $request = new Request([], [], ['data' => new Dummy(), '_api_resource_class' => Dummy::class, '_api_collection_operation_name' => 'post']);
$request->setMethod('POST');
- $eventProphecy->getRequest()->willReturn($request)->shouldBeCalled();
- $serializerProphecy = $this->prophesize(SerializerInterface::class);
- $serializerProphecy->deserialize()->shouldNotBeCalled();
-
- $serializerContextBuilderProphecy = $this->prophesize(SerializerContextBuilderInterface::class);
- $serializerContextBuilderProphecy->createFromRequest(Argument::type(Request::class), false, Argument::type('array'))->willReturn(['input' => ['class' => null], 'output' => ['class' => null]]);
-
- $formatsProviderProphecy = $this->prophesize(FormatsProviderInterface::class);
- $formatsProviderProphecy->getFormatsFromAttributes(Argument::type('array'))->shouldNotBeCalled();
+ $eventProphecy = $this->prophesize(GetResponseEvent::class);
+ $eventProphecy->getRequest()->willReturn($request);
- $listener = new DeserializeListener($serializerProphecy->reveal(), $serializerContextBuilderProphecy->reveal(), $formatsProviderProphecy->reveal());
+ $listener = new DeserializeListener($serializerProphecy->reveal(), $serializerContextBuilderProphecy->reveal(), $formatsProviderProphecy->reveal(), $resourceMetadataFactoryProphecy->reveal());
$listener->onKernelRequest($eventProphecy->reveal());
}
@@ -260,7 +239,7 @@ public function testNotSupportedContentType()
$eventProphecy->getRequest()->willReturn($request)->shouldBeCalled();
$serializerProphecy = $this->prophesize(SerializerInterface::class);
- $serializerProphecy->deserialize()->shouldNotBeCalled();
+ $serializerProphecy->deserialize(Argument::cetera())->shouldNotBeCalled();
$serializerContextBuilderProphecy = $this->prophesize(SerializerContextBuilderInterface::class);
$serializerContextBuilderProphecy->createFromRequest(Argument::type(Request::class), false, Argument::type('array'))->willReturn(['input' => ['class' => 'Foo'], 'output' => ['class' => 'Foo']]);
@@ -289,7 +268,7 @@ public function testNoContentType()
$eventProphecy->getRequest()->willReturn($request)->shouldBeCalled();
$serializerProphecy = $this->prophesize(SerializerInterface::class);
- $serializerProphecy->deserialize()->shouldNotBeCalled();
+ $serializerProphecy->deserialize(Argument::cetera())->shouldNotBeCalled();
$serializerContextBuilderProphecy = $this->prophesize(SerializerContextBuilderInterface::class);
$serializerContextBuilderProphecy->createFromRequest(Argument::type(Request::class), false, Argument::type('array'))->willReturn(['input' => ['class' => 'Foo'], 'output' => ['class' => 'Foo']]);
@@ -311,10 +290,8 @@ public function testBadFormatsProviderParameterThrowsException()
$this->expectExceptionMessage('The "$formatsProvider" argument is expected to be an implementation of the "ApiPlatform\\Core\\Api\\FormatsProviderInterface" interface.');
$serializerProphecy = $this->prophesize(SerializerInterface::class);
- $serializerProphecy->deserialize()->shouldNotBeCalled();
$serializerContextBuilderProphecy = $this->prophesize(SerializerContextBuilderInterface::class);
- $serializerContextBuilderProphecy->createFromRequest()->shouldNotBeCalled();
new DeserializeListener(
$serializerProphecy->reveal(),
@@ -330,10 +307,8 @@ public function testBadFormatsProviderParameterThrowsException()
public function testLegacyFormatsParameter()
{
$serializerProphecy = $this->prophesize(SerializerInterface::class);
- $serializerProphecy->deserialize()->shouldNotBeCalled();
$serializerContextBuilderProphecy = $this->prophesize(SerializerContextBuilderInterface::class);
- $serializerContextBuilderProphecy->createFromRequest()->shouldNotBeCalled();
new DeserializeListener(
$serializerProphecy->reveal(),
diff --git a/tests/EventListener/ReadListenerTest.php b/tests/EventListener/ReadListenerTest.php
index 2185e58e63c..f023cb440e3 100644
--- a/tests/EventListener/ReadListenerTest.php
+++ b/tests/EventListener/ReadListenerTest.php
@@ -20,6 +20,9 @@
use ApiPlatform\Core\Exception\InvalidIdentifierException;
use ApiPlatform\Core\Exception\RuntimeException;
use ApiPlatform\Core\Identifier\IdentifierConverterInterface;
+use ApiPlatform\Core\Metadata\Resource\Factory\ResourceMetadataFactoryInterface;
+use ApiPlatform\Core\Metadata\Resource\ResourceMetadata;
+use ApiPlatform\Core\Tests\Fixtures\TestBundle\Entity\Dummy;
use PHPUnit\Framework\TestCase;
use Prophecy\Argument;
use Symfony\Component\HttpFoundation\Request;
@@ -72,26 +75,58 @@ public function testLegacyConstructor()
$listener->onKernelRequest($event->reveal());
}
- public function testDoNotCallWhenReceiveFlagIsFalse()
+ public function testDoNotReadWhenReceiveFlagIsFalse()
{
+ $collectionDataProvider = $this->prophesize(CollectionDataProviderInterface::class);
+ $collectionDataProvider->getCollection(Argument::cetera())->shouldNotBeCalled();
+
+ $itemDataProvider = $this->prophesize(ItemDataProviderInterface::class);
+ $itemDataProvider->getItem(Argument::cetera())->shouldNotBeCalled();
+
+ $subresourceDataProvider = $this->prophesize(SubresourceDataProviderInterface::class);
+ $subresourceDataProvider->getSubresource(Argument::cetera())->shouldNotBeCalled();
+
$identifierConverter = $this->prophesize(IdentifierConverterInterface::class);
+ $request = new Request([], [], ['id' => 1, 'data' => new Dummy(), '_api_resource_class' => Dummy::class, '_api_item_operation_name' => 'put', '_api_receive' => false]);
+ $request->setMethod('PUT');
+
+ $event = $this->prophesize(GetResponseEvent::class);
+ $event->getRequest()->willReturn($request);
+
+ $listener = new ReadListener($collectionDataProvider->reveal(), $itemDataProvider->reveal(), $subresourceDataProvider->reveal(), null, $identifierConverter->reveal());
+ $listener->onKernelRequest($event->reveal());
+ }
+
+ public function testDoNotReadWhenDisabledInOperationAttribute()
+ {
$collectionDataProvider = $this->prophesize(CollectionDataProviderInterface::class);
- $collectionDataProvider->getCollection()->shouldNotBeCalled();
+ $collectionDataProvider->getCollection(Argument::cetera())->shouldNotBeCalled();
$itemDataProvider = $this->prophesize(ItemDataProviderInterface::class);
- $itemDataProvider->getItem()->shouldNotBeCalled();
+ $itemDataProvider->getItem(Argument::cetera())->shouldNotBeCalled();
$subresourceDataProvider = $this->prophesize(SubresourceDataProviderInterface::class);
- $subresourceDataProvider->getSubresource()->shouldNotBeCalled();
+ $subresourceDataProvider->getSubresource(Argument::cetera())->shouldNotBeCalled();
+
+ $identifierConverter = $this->prophesize(IdentifierConverterInterface::class);
+
+ $resourceMetadata = new ResourceMetadata('Dummy', null, null, [
+ 'put' => [
+ 'read' => false,
+ ],
+ ]);
+
+ $resourceMetadataFactoryProphecy = $this->prophesize(ResourceMetadataFactoryInterface::class);
+ $resourceMetadataFactoryProphecy->create(Dummy::class)->willReturn($resourceMetadata);
- $request = new Request([], [], ['data' => new \stdClass(), '_api_resource_class' => 'Foo', '_api_collection_operation_name' => 'post', '_api_receive' => false]);
+ $request = new Request([], [], ['id' => 1, 'data' => new Dummy(), '_api_resource_class' => Dummy::class, '_api_item_operation_name' => 'put']);
$request->setMethod('PUT');
$event = $this->prophesize(GetResponseEvent::class);
- $event->getRequest()->willReturn($request)->shouldBeCalled();
+ $event->getRequest()->willReturn($request);
- $listener = new ReadListener($collectionDataProvider->reveal(), $itemDataProvider->reveal(), $subresourceDataProvider->reveal(), null, $identifierConverter->reveal());
+ $listener = new ReadListener($collectionDataProvider->reveal(), $itemDataProvider->reveal(), $subresourceDataProvider->reveal(), null, $identifierConverter->reveal(), $resourceMetadataFactoryProphecy->reveal());
$listener->onKernelRequest($event->reveal());
}
@@ -112,13 +147,12 @@ public function testRetrieveCollectionPost()
$request->setMethod('POST');
$event = $this->prophesize(GetResponseEvent::class);
- $event->getRequest()->willReturn($request)->shouldBeCalled();
+ $event->getRequest()->willReturn($request);
$listener = new ReadListener($collectionDataProvider->reveal(), $itemDataProvider->reveal(), $subresourceDataProvider->reveal(), null, $identifierConverter->reveal());
$listener->onKernelRequest($event->reveal());
- $this->assertTrue($request->attributes->has('data'));
- $this->assertNull($request->attributes->get('data'));
+ $this->assertFalse($request->attributes->has('data'));
}
public function testRetrieveCollectionGet()
diff --git a/tests/EventListener/SerializeListenerTest.php b/tests/EventListener/SerializeListenerTest.php
index 0507945d7a4..8c1c163f263 100644
--- a/tests/EventListener/SerializeListenerTest.php
+++ b/tests/EventListener/SerializeListenerTest.php
@@ -14,8 +14,11 @@
namespace ApiPlatform\Core\Tests\EventListener;
use ApiPlatform\Core\EventListener\SerializeListener;
+use ApiPlatform\Core\Metadata\Resource\Factory\ResourceMetadataFactoryInterface;
+use ApiPlatform\Core\Metadata\Resource\ResourceMetadata;
use ApiPlatform\Core\Serializer\ResourceList;
use ApiPlatform\Core\Serializer\SerializerContextBuilderInterface;
+use ApiPlatform\Core\Tests\Fixtures\TestBundle\Entity\Dummy;
use PHPUnit\Framework\TestCase;
use Prophecy\Argument;
use Symfony\Component\HttpFoundation\Request;
@@ -29,20 +32,19 @@
*/
class SerializeListenerTest extends TestCase
{
- public function testDoNotSerializeResponse()
+ public function testDoNotSerializeWhenControllerResultIsResponse()
{
$serializerProphecy = $this->prophesize(SerializerInterface::class);
$serializerProphecy->serialize(Argument::cetera())->shouldNotBeCalled();
$request = new Request();
- $request->setRequestFormat('xml');
$eventProphecy = $this->prophesize(GetResponseForControllerResultEvent::class);
- $eventProphecy->getControllerResult()->willReturn(new Response())->shouldBeCalled();
- $eventProphecy->getRequest()->willReturn($request)->shouldBeCalled();
+ $eventProphecy->getControllerResult()->willReturn(new Response());
+ $eventProphecy->getRequest()->willReturn($request);
$serializerContextBuilderProphecy = $this->prophesize(SerializerContextBuilderInterface::class);
- $serializerContextBuilderProphecy->createFromRequest(Argument::cetera())->shouldNotBeCalled();
+ $serializerContextBuilderProphecy->createFromRequest(Argument::cetera());
$listener = new SerializeListener($serializerProphecy->reveal(), $serializerContextBuilderProphecy->reveal());
$listener->onKernelView($eventProphecy->reveal());
@@ -55,10 +57,13 @@ public function testDoNotSerializeWhenRespondFlagIsFalse()
$serializerContextBuilderProphecy = $this->prophesize(SerializerContextBuilderInterface::class);
- $request = new Request([], [], ['_api_respond' => false]);
+ $dummy = new Dummy();
+
+ $request = new Request([], [], ['data' => $dummy, '_api_resource_class' => Dummy::class, '_api_collection_operation_name' => 'post', '_api_respond' => false]);
+ $request->setMethod('POST');
$eventProphecy = $this->prophesize(GetResponseForControllerResultEvent::class);
- $eventProphecy->getControllerResult()->willReturn(new \stdClass());
+ $eventProphecy->getControllerResult()->willReturn($dummy);
$eventProphecy->getRequest()->willReturn($request);
$eventProphecy->setControllerResult(Argument::any())->shouldNotBeCalled();
@@ -66,6 +71,36 @@ public function testDoNotSerializeWhenRespondFlagIsFalse()
$listener->onKernelView($eventProphecy->reveal());
}
+ public function testDoNotSerializeWhenDisabledInOperationAttribute()
+ {
+ $serializerProphecy = $this->prophesize(SerializerInterface::class);
+ $serializerProphecy->serialize(Argument::cetera())->shouldNotBeCalled();
+
+ $serializerContextBuilderProphecy = $this->prophesize(SerializerContextBuilderInterface::class);
+
+ $resourceMetadata = new ResourceMetadata('Dummy', null, null, [], [
+ 'post' => [
+ 'serialize' => false,
+ ],
+ ]);
+
+ $resourceMetadataFactoryProphecy = $this->prophesize(ResourceMetadataFactoryInterface::class);
+ $resourceMetadataFactoryProphecy->create(Dummy::class)->willReturn($resourceMetadata);
+
+ $dummy = new Dummy();
+
+ $request = new Request([], [], ['data' => $dummy, '_api_resource_class' => Dummy::class, '_api_collection_operation_name' => 'post']);
+ $request->setMethod('POST');
+
+ $eventProphecy = $this->prophesize(GetResponseForControllerResultEvent::class);
+ $eventProphecy->getControllerResult()->willReturn($dummy);
+ $eventProphecy->getRequest()->willReturn($request);
+ $eventProphecy->setControllerResult(Argument::any())->shouldNotBeCalled();
+
+ $listener = new SerializeListener($serializerProphecy->reveal(), $serializerContextBuilderProphecy->reveal(), $resourceMetadataFactoryProphecy->reveal());
+ $listener->onKernelView($eventProphecy->reveal());
+ }
+
public function testSerializeCollectionOperation()
{
$expectedContext = ['request_uri' => '', 'resource_class' => 'Foo', 'collection_operation_name' => 'get'];
diff --git a/tests/EventListener/WriteListenerTest.php b/tests/EventListener/WriteListenerTest.php
index 04b4834d778..d6b3412cda7 100644
--- a/tests/EventListener/WriteListenerTest.php
+++ b/tests/EventListener/WriteListenerTest.php
@@ -23,6 +23,7 @@
use PHPUnit\Framework\TestCase;
use Prophecy\Argument;
use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Event\GetResponseForControllerResultEvent;
use Symfony\Component\HttpKernel\HttpKernelInterface;
@@ -215,21 +216,44 @@ public function testOnKernelViewWithSafeMethod()
(new WriteListener($dataPersisterProphecy->reveal()))->onKernelView($event);
}
- public function testOnKernelViewWithPersistFlagOff()
+ public function testDoNotWriteWhenControllerResultIsResponse()
+ {
+ $dataPersisterProphecy = $this->prophesize(DataPersisterInterface::class);
+ $dataPersisterProphecy->supports(Argument::cetera())->shouldNotBeCalled();
+ $dataPersisterProphecy->persist(Argument::cetera())->shouldNotBeCalled();
+ $dataPersisterProphecy->remove(Argument::cetera())->shouldNotBeCalled();
+
+ $iriConverterProphecy = $this->prophesize(IriConverterInterface::class);
+
+ $request = new Request();
+
+ $response = new Response();
+
+ $event = new GetResponseForControllerResultEvent(
+ $this->prophesize(HttpKernelInterface::class)->reveal(),
+ $request,
+ HttpKernelInterface::MASTER_REQUEST,
+ $response
+ );
+
+ $listener = new WriteListener($dataPersisterProphecy->reveal(), $iriConverterProphecy->reveal());
+ $listener->onKernelView($event);
+ }
+
+ public function testDoNotWriteWhenPersistFlagIsFalse()
{
$dummy = new Dummy();
$dummy->setName('Dummyrino');
$dataPersisterProphecy = $this->prophesize(DataPersisterInterface::class);
- $dataPersisterProphecy->supports($dummy, Argument::type('array'))->shouldNotBeCalled();
- $dataPersisterProphecy->persist($dummy, Argument::type('array'))->shouldNotBeCalled();
- $dataPersisterProphecy->remove($dummy, Argument::type('array'))->shouldNotBeCalled();
+ $dataPersisterProphecy->supports(Argument::cetera())->shouldNotBeCalled();
+ $dataPersisterProphecy->persist(Argument::cetera())->shouldNotBeCalled();
+ $dataPersisterProphecy->remove(Argument::cetera())->shouldNotBeCalled();
$iriConverterProphecy = $this->prophesize(IriConverterInterface::class);
- $iriConverterProphecy->getIriFromItem($dummy)->shouldNotBeCalled();
- $request = new Request([], [], ['_api_resource_class' => Dummy::class, '_api_item_operation_name' => 'head', '_api_persist' => false]);
- $request->setMethod('HEAD');
+ $request = new Request([], [], ['data' => new Dummy(), '_api_resource_class' => Dummy::class, '_api_collection_operation_name' => 'post', '_api_persist' => false]);
+ $request->setMethod('POST');
$event = new GetResponseForControllerResultEvent(
$this->prophesize(HttpKernelInterface::class)->reveal(),
@@ -238,7 +262,43 @@ public function testOnKernelViewWithPersistFlagOff()
$dummy
);
- (new WriteListener($dataPersisterProphecy->reveal(), $iriConverterProphecy->reveal()))->onKernelView($event);
+ $listener = new WriteListener($dataPersisterProphecy->reveal(), $iriConverterProphecy->reveal());
+ $listener->onKernelView($event);
+ }
+
+ public function testDoNotWriteWhenDisabledInOperationAttribute()
+ {
+ $dummy = new Dummy();
+ $dummy->setName('Dummyrino');
+
+ $dataPersisterProphecy = $this->prophesize(DataPersisterInterface::class);
+ $dataPersisterProphecy->supports(Argument::cetera())->shouldNotBeCalled();
+ $dataPersisterProphecy->persist(Argument::cetera())->shouldNotBeCalled();
+ $dataPersisterProphecy->remove(Argument::cetera())->shouldNotBeCalled();
+
+ $iriConverterProphecy = $this->prophesize(IriConverterInterface::class);
+
+ $resourceMetadata = new ResourceMetadata('Dummy', null, null, [], [
+ 'post' => [
+ 'write' => false,
+ ],
+ ]);
+
+ $resourceMetadataFactoryProphecy = $this->prophesize(ResourceMetadataFactoryInterface::class);
+ $resourceMetadataFactoryProphecy->create(Dummy::class)->willReturn($resourceMetadata);
+
+ $request = new Request([], [], ['data' => new Dummy(), '_api_resource_class' => Dummy::class, '_api_collection_operation_name' => 'post']);
+ $request->setMethod('POST');
+
+ $event = new GetResponseForControllerResultEvent(
+ $this->prophesize(HttpKernelInterface::class)->reveal(),
+ $request,
+ HttpKernelInterface::MASTER_REQUEST,
+ $dummy
+ );
+
+ $listener = new WriteListener($dataPersisterProphecy->reveal(), $iriConverterProphecy->reveal(), $resourceMetadataFactoryProphecy->reveal());
+ $listener->onKernelView($event);
}
public function testOnKernelViewWithNoResourceClass()
diff --git a/tests/Validator/EventListener/ValidateListenerTest.php b/tests/Validator/EventListener/ValidateListenerTest.php
index 892c5bd2b5e..56422cec36b 100644
--- a/tests/Validator/EventListener/ValidateListenerTest.php
+++ b/tests/Validator/EventListener/ValidateListenerTest.php
@@ -20,7 +20,9 @@
use ApiPlatform\Core\Validator\Exception\ValidationException;
use ApiPlatform\Core\Validator\ValidatorInterface;
use PHPUnit\Framework\TestCase;
+use Prophecy\Argument;
use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Event\GetResponseForControllerResultEvent;
use Symfony\Component\HttpKernel\HttpKernelInterface;
@@ -35,21 +37,19 @@ class ValidateListenerTest extends TestCase
public function testNotAnApiPlatformRequest()
{
$validatorProphecy = $this->prophesize(ValidatorInterface::class);
- $validatorProphecy->validate()->shouldNotBeCalled();
- $validator = $validatorProphecy->reveal();
+ $validatorProphecy->validate(Argument::cetera())->shouldNotBeCalled();
$resourceMetadataFactoryProphecy = $this->prophesize(ResourceMetadataFactoryInterface::class);
- $resourceMetadataFactoryProphecy->create()->shouldNotBeCalled();
- $resourceMetadataFactory = $resourceMetadataFactoryProphecy->reveal();
$request = new Request();
$request->setMethod('POST');
- $event = $this->prophesize(GetResponseForControllerResultEvent::class);
- $event->getRequest()->willReturn($request)->shouldBeCalled();
+ $eventProphecy = $this->prophesize(GetResponseForControllerResultEvent::class);
+ $eventProphecy->getControllerResult()->willReturn([]);
+ $eventProphecy->getRequest()->willReturn($request);
- $listener = new ValidateListener($validator, $resourceMetadataFactory);
- $listener->onKernelView($event->reveal());
+ $listener = new ValidateListener($validatorProphecy->reveal(), $resourceMetadataFactoryProphecy->reveal());
+ $listener->onKernelView($eventProphecy->reveal());
}
public function testValidatorIsCalled()
@@ -67,19 +67,73 @@ public function testValidatorIsCalled()
$validationViewListener->onKernelView($event);
}
- public function testDoNotCallWhenReceiveFlagIsFalse()
+ public function testDoNotValidateWhenControllerResultIsResponse()
{
- $data = new DummyEntity();
- $expectedValidationGroups = ['a', 'b', 'c'];
+ $validatorProphecy = $this->prophesize(ValidatorInterface::class);
+ $validatorProphecy->validate(Argument::cetera())->shouldNotBeCalled();
+
+ $resourceMetadataFactoryProphecy = $this->prophesize(ResourceMetadataFactoryInterface::class);
+
+ $dummy = new DummyEntity();
+
+ $request = new Request([], [], ['data' => $dummy, '_api_resource_class' => DummyEntity::class, '_api_collection_operation_name' => 'post', '_api_receive' => false]);
+ $request->setMethod('POST');
+
+ $response = new Response();
+
+ $eventProphecy = $this->prophesize(GetResponseForControllerResultEvent::class);
+ $eventProphecy->getControllerResult()->willReturn($response);
+ $eventProphecy->getRequest()->willReturn($request);
+
+ $validationViewListener = new ValidateListener($validatorProphecy->reveal(), $resourceMetadataFactoryProphecy->reveal());
+ $validationViewListener->onKernelView($eventProphecy->reveal());
+ }
+ public function testDoNotValidateWhenReceiveFlagIsFalse()
+ {
$validatorProphecy = $this->prophesize(ValidatorInterface::class);
- $validatorProphecy->validate($data, ['groups' => $expectedValidationGroups])->shouldNotBeCalled();
- $validator = $validatorProphecy->reveal();
+ $validatorProphecy->validate(Argument::cetera())->shouldNotBeCalled();
- [$resourceMetadataFactory, $event] = $this->createEventObject($expectedValidationGroups, $data, false);
+ $resourceMetadataFactoryProphecy = $this->prophesize(ResourceMetadataFactoryInterface::class);
- $validationViewListener = new ValidateListener($validator, $resourceMetadataFactory);
- $validationViewListener->onKernelView($event);
+ $dummy = new DummyEntity();
+
+ $request = new Request([], [], ['data' => $dummy, '_api_resource_class' => DummyEntity::class, '_api_collection_operation_name' => 'post', '_api_receive' => false]);
+ $request->setMethod('POST');
+
+ $eventProphecy = $this->prophesize(GetResponseForControllerResultEvent::class);
+ $eventProphecy->getControllerResult()->willReturn($dummy);
+ $eventProphecy->getRequest()->willReturn($request);
+
+ $validationViewListener = new ValidateListener($validatorProphecy->reveal(), $resourceMetadataFactoryProphecy->reveal());
+ $validationViewListener->onKernelView($eventProphecy->reveal());
+ }
+
+ public function testDoNotValidateWhenDisabledInOperationAttribute()
+ {
+ $validatorProphecy = $this->prophesize(ValidatorInterface::class);
+ $validatorProphecy->validate(Argument::cetera())->shouldNotBeCalled();
+
+ $resourceMetadata = new ResourceMetadata('DummyEntity', null, null, [], [
+ 'post' => [
+ 'validate' => false,
+ ],
+ ]);
+
+ $resourceMetadataFactoryProphecy = $this->prophesize(ResourceMetadataFactoryInterface::class);
+ $resourceMetadataFactoryProphecy->create(DummyEntity::class)->willReturn($resourceMetadata);
+
+ $dummy = new DummyEntity();
+
+ $request = new Request([], [], ['data' => $dummy, '_api_resource_class' => DummyEntity::class, '_api_collection_operation_name' => 'post']);
+ $request->setMethod('POST');
+
+ $eventProphecy = $this->prophesize(GetResponseForControllerResultEvent::class);
+ $eventProphecy->getControllerResult()->willReturn($dummy);
+ $eventProphecy->getRequest()->willReturn($request);
+
+ $validationViewListener = new ValidateListener($validatorProphecy->reveal(), $resourceMetadataFactoryProphecy->reveal());
+ $validationViewListener->onKernelView($eventProphecy->reveal());
}
public function testThrowsValidationExceptionWithViolationsFound()