Skip to content

Commit

Permalink
Merge fca4fe9 into 4359926
Browse files Browse the repository at this point in the history
  • Loading branch information
mtarld committed Dec 10, 2020
2 parents 4359926 + fca4fe9 commit 03a575e
Show file tree
Hide file tree
Showing 11 changed files with 80 additions and 20 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
@@ -1,5 +1,9 @@
# Changelog

## 2.7.0

* Validator: Add custom constraint set validation

## 2.6.0

* Cache: adds a `max_header_length` configuration (#2865)
Expand Down
2 changes: 1 addition & 1 deletion src/Bridge/Symfony/Bundle/Resources/config/validator.xml
Expand Up @@ -9,7 +9,7 @@
<argument type="service" id="validator" />
<argument type="service" id="service_container" />
</service>
<service id="ApiPlatform\Core\Validator\ValidatorInterface" alias="api_platform.validator" />
<service id="ApiPlatform\Core\Validator\ConstraintValidatorInterface" alias="api_platform.validator" />

<service id="api_platform.metadata.property.metadata_factory.validator" class="ApiPlatform\Core\Bridge\Symfony\Validator\Metadata\Property\ValidatorPropertyMetadataFactory" decorates="api_platform.metadata.property.metadata_factory" decoration-priority="20" public="false">
<argument type="service" id="validator" />
Expand Down
8 changes: 4 additions & 4 deletions src/Bridge/Symfony/Validator/Validator.php
Expand Up @@ -14,7 +14,7 @@
namespace ApiPlatform\Core\Bridge\Symfony\Validator;

use ApiPlatform\Core\Bridge\Symfony\Validator\Exception\ValidationException;
use ApiPlatform\Core\Validator\ValidatorInterface;
use ApiPlatform\Core\Validator\ConstraintValidatorInterface;
use Psr\Container\ContainerInterface;
use Symfony\Component\Validator\Constraints\GroupSequence;
use Symfony\Component\Validator\Validator\ValidatorInterface as SymfonyValidatorInterface;
Expand All @@ -26,7 +26,7 @@
*
* @final
*/
class Validator implements ValidatorInterface
class Validator implements ConstraintValidatorInterface
{
private $validator;
private $container;
Expand All @@ -40,7 +40,7 @@ public function __construct(SymfonyValidatorInterface $validator, ContainerInter
/**
* {@inheritdoc}
*/
public function validate($data, array $context = [])
public function validate($data, array $context = [], ?array $constraints = null)
{
if (null !== $validationGroups = $context['groups'] ?? null) {
if (
Expand All @@ -64,7 +64,7 @@ public function validate($data, array $context = [])
}
}

$violations = $this->validator->validate($data, null, $validationGroups);
$violations = $this->validator->validate($data, $constraints, $validationGroups);
if (0 !== \count($violations)) {
throw new ValidationException($violations);
}
Expand Down
4 changes: 2 additions & 2 deletions src/GraphQl/Resolver/Stage/ValidateStage.php
Expand Up @@ -14,7 +14,7 @@
namespace ApiPlatform\Core\GraphQl\Resolver\Stage;

use ApiPlatform\Core\Metadata\Resource\Factory\ResourceMetadataFactoryInterface;
use ApiPlatform\Core\Validator\ValidatorInterface;
use ApiPlatform\Core\Validator\ConstraintValidatorInterface;

/**
* Validate stage of GraphQL resolvers.
Expand All @@ -28,7 +28,7 @@ final class ValidateStage implements ValidateStageInterface
private $resourceMetadataFactory;
private $validator;

public function __construct(ResourceMetadataFactoryInterface $resourceMetadataFactory, ValidatorInterface $validator)
public function __construct(ResourceMetadataFactoryInterface $resourceMetadataFactory, ConstraintValidatorInterface $validator)
{
$this->resourceMetadataFactory = $resourceMetadataFactory;
$this->validator = $validator;
Expand Down
34 changes: 34 additions & 0 deletions src/Validator/ConstraintValidatorInterface.php
@@ -0,0 +1,34 @@
<?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\Validator;

use ApiPlatform\Core\Validator\Exception\ValidationException;
use Symfony\Component\Validator\Constraint;

/**
* Validates an item.
*
* @author Mathias Arlaud <mathias.arlaud@gmail.com>
*/
interface ConstraintValidatorInterface extends ValidatorInterface
{
/**
* Validates an item with an optional set of constraints.
*
* @param Constraint[]|null $constraints
*
* @throws ValidationException
*/
public function validate($data, array $context = [], ?array $constraints = null);
}
4 changes: 2 additions & 2 deletions src/Validator/EventListener/ValidateListener.php
Expand Up @@ -16,8 +16,8 @@
use ApiPlatform\Core\Metadata\Resource\Factory\ResourceMetadataFactoryInterface;
use ApiPlatform\Core\Metadata\Resource\ToggleableOperationAttributeTrait;
use ApiPlatform\Core\Util\RequestAttributesExtractor;
use ApiPlatform\Core\Validator\ConstraintValidatorInterface;
use ApiPlatform\Core\Validator\Exception\ValidationException;
use ApiPlatform\Core\Validator\ValidatorInterface;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Event\ViewEvent;

Expand All @@ -35,7 +35,7 @@ final class ValidateListener
private $validator;
private $resourceMetadataFactory;

public function __construct(ValidatorInterface $validator, ResourceMetadataFactoryInterface $resourceMetadataFactory)
public function __construct(ConstraintValidatorInterface $validator, ResourceMetadataFactoryInterface $resourceMetadataFactory)
{
$this->validator = $validator;
$this->resourceMetadataFactory = $resourceMetadataFactory;
Expand Down
2 changes: 2 additions & 0 deletions src/Validator/ValidatorInterface.php
Expand Up @@ -19,6 +19,8 @@
* Validates an item.
*
* @author Kévin Dunglas <dunglas@gmail.com>
*
* @deprecated since version 2.7, to be removed in 3.0. Use {@see \ApiPlatform\Core\Validator\ConstraintValidatorInterface} instead.
*/
interface ValidatorInterface
{
Expand Down
Expand Up @@ -88,7 +88,7 @@
use ApiPlatform\Core\Serializer\SerializerContextBuilderInterface;
use ApiPlatform\Core\Tests\Fixtures\TestBundle\TestBundle;
use ApiPlatform\Core\Tests\ProphecyTrait;
use ApiPlatform\Core\Validator\ValidatorInterface;
use ApiPlatform\Core\Validator\ConstraintValidatorInterface;
use Doctrine\Bundle\DoctrineBundle\DoctrineBundle;
use Doctrine\ORM\OptimisticLockException;
use Nelmio\ApiDocBundle\NelmioApiDocBundle;
Expand Down Expand Up @@ -1356,7 +1356,7 @@ private function getBaseContainerBuilderProphecy(array $doctrineIntegrationsToLo
FilterEagerLoadingExtension::class => 'api_platform.doctrine.orm.query_extension.filter_eager_loading',
PaginationExtension::class => 'api_platform.doctrine.orm.query_extension.pagination',
OrderExtension::class => 'api_platform.doctrine.orm.query_extension.order',
ValidatorInterface::class => 'api_platform.validator',
ConstraintValidatorInterface::class => 'api_platform.validator',
SearchFilter::class => 'api_platform.doctrine.orm.search_filter',
OrderFilter::class => 'api_platform.doctrine.orm.order_filter',
RangeFilter::class => 'api_platform.doctrine.orm.range_filter',
Expand Down
20 changes: 20 additions & 0 deletions tests/Bridge/Symfony/Validator/ValidatorTest.php
Expand Up @@ -20,6 +20,7 @@
use ApiPlatform\Core\Tests\ProphecyTrait;
use PHPUnit\Framework\TestCase;
use Psr\Container\ContainerInterface;
use Symfony\Component\Validator\Constraints\NotBlank;
use Symfony\Component\Validator\ConstraintViolationListInterface;
use Symfony\Component\Validator\Validator\ValidatorInterface as SymfonyValidatorInterface;

Expand Down Expand Up @@ -142,4 +143,23 @@ public function testValidatorWithScalarGroup()
$validator = new Validator($symfonyValidator, $containerProphecy->reveal());
$validator->validate(new DummyEntity(), ['groups' => 'foo']);
}

public function testValidateCustomConstraints()
{
$this->expectException(ValidationException::class);

$data = new DummyEntity();

$constraintViolationListProphecy = $this->prophesize(ConstraintViolationListInterface::class);
$constraintViolationListProphecy->rewind()->shouldBeCalled();
$constraintViolationListProphecy->valid()->shouldBeCalled();
$constraintViolationListProphecy->count()->willReturn(1)->shouldBeCalled();

$symfonyValidatorProphecy = $this->prophesize(SymfonyValidatorInterface::class);
$symfonyValidatorProphecy->validate($data, [new NotBlank()], null)->willReturn($constraintViolationListProphecy->reveal())->shouldBeCalled();
$symfonyValidator = $symfonyValidatorProphecy->reveal();

$validator = new Validator($symfonyValidator);
$validator->validate($data, [], [new NotBlank()]);
}
}
4 changes: 2 additions & 2 deletions tests/GraphQl/Resolver/Stage/ValidateStageTest.php
Expand Up @@ -17,8 +17,8 @@
use ApiPlatform\Core\Metadata\Resource\Factory\ResourceMetadataFactoryInterface;
use ApiPlatform\Core\Metadata\Resource\ResourceMetadata;
use ApiPlatform\Core\Tests\ProphecyTrait;
use ApiPlatform\Core\Validator\ConstraintValidatorInterface;
use ApiPlatform\Core\Validator\Exception\ValidationException;
use ApiPlatform\Core\Validator\ValidatorInterface;
use GraphQL\Type\Definition\ResolveInfo;
use PHPUnit\Framework\TestCase;
use Prophecy\Argument;
Expand All @@ -41,7 +41,7 @@ class ValidateStageTest extends TestCase
protected function setUp(): void
{
$this->resourceMetadataFactoryProphecy = $this->prophesize(ResourceMetadataFactoryInterface::class);
$this->validatorProphecy = $this->prophesize(ValidatorInterface::class);
$this->validatorProphecy = $this->prophesize(ConstraintValidatorInterface::class);

$this->validateStage = new ValidateStage(
$this->resourceMetadataFactoryProphecy->reveal(),
Expand Down
14 changes: 7 additions & 7 deletions tests/Validator/EventListener/ValidateListenerTest.php
Expand Up @@ -17,9 +17,9 @@
use ApiPlatform\Core\Metadata\Resource\ResourceMetadata;
use ApiPlatform\Core\Tests\Fixtures\DummyEntity;
use ApiPlatform\Core\Tests\ProphecyTrait;
use ApiPlatform\Core\Validator\ConstraintValidatorInterface;
use ApiPlatform\Core\Validator\EventListener\ValidateListener;
use ApiPlatform\Core\Validator\Exception\ValidationException;
use ApiPlatform\Core\Validator\ValidatorInterface;
use PHPUnit\Framework\TestCase;
use Prophecy\Argument;
use Symfony\Component\HttpFoundation\Request;
Expand All @@ -38,7 +38,7 @@ class ValidateListenerTest extends TestCase

public function testNotAnApiPlatformRequest()
{
$validatorProphecy = $this->prophesize(ValidatorInterface::class);
$validatorProphecy = $this->prophesize(ConstraintValidatorInterface::class);
$validatorProphecy->validate(Argument::cetera())->shouldNotBeCalled();

$resourceMetadataFactoryProphecy = $this->prophesize(ResourceMetadataFactoryInterface::class);
Expand All @@ -57,7 +57,7 @@ public function testValidatorIsCalled()
$data = new DummyEntity();
$expectedValidationGroups = ['a', 'b', 'c'];

$validatorProphecy = $this->prophesize(ValidatorInterface::class);
$validatorProphecy = $this->prophesize(ConstraintValidatorInterface::class);
$validatorProphecy->validate($data, ['groups' => $expectedValidationGroups])->shouldBeCalled();
$validator = $validatorProphecy->reveal();

Expand All @@ -69,7 +69,7 @@ public function testValidatorIsCalled()

public function testDoNotValidateWhenControllerResultIsResponse()
{
$validatorProphecy = $this->prophesize(ValidatorInterface::class);
$validatorProphecy = $this->prophesize(ConstraintValidatorInterface::class);
$validatorProphecy->validate(Argument::cetera())->shouldNotBeCalled();

$resourceMetadataFactoryProphecy = $this->prophesize(ResourceMetadataFactoryInterface::class);
Expand All @@ -92,7 +92,7 @@ public function testDoNotValidateWhenControllerResultIsResponse()

public function testDoNotValidateWhenReceiveFlagIsFalse()
{
$validatorProphecy = $this->prophesize(ValidatorInterface::class);
$validatorProphecy = $this->prophesize(ConstraintValidatorInterface::class);
$validatorProphecy->validate(Argument::cetera())->shouldNotBeCalled();

$resourceMetadataFactoryProphecy = $this->prophesize(ResourceMetadataFactoryInterface::class);
Expand All @@ -115,7 +115,7 @@ public function testDoNotValidateWhenReceiveFlagIsFalse()

public function testDoNotValidateWhenDisabledInOperationAttribute()
{
$validatorProphecy = $this->prophesize(ValidatorInterface::class);
$validatorProphecy = $this->prophesize(ConstraintValidatorInterface::class);
$validatorProphecy->validate(Argument::cetera())->shouldNotBeCalled();

$resourceMetadata = new ResourceMetadata('DummyEntity', null, null, [], [
Expand Down Expand Up @@ -150,7 +150,7 @@ public function testThrowsValidationExceptionWithViolationsFound()
$data = new DummyEntity();
$expectedValidationGroups = ['a', 'b', 'c'];

$validatorProphecy = $this->prophesize(ValidatorInterface::class);
$validatorProphecy = $this->prophesize(ConstraintValidatorInterface::class);
$validatorProphecy->validate($data, ['groups' => $expectedValidationGroups])->willThrow(new ValidationException())->shouldBeCalled();
$validator = $validatorProphecy->reveal();

Expand Down

0 comments on commit 03a575e

Please sign in to comment.