From f45f1ab20c2aa82545f5d01db45abc5e6c2e121c Mon Sep 17 00:00:00 2001 From: Bernhard Schussek Date: Wed, 6 Aug 2014 13:24:01 +0200 Subject: [PATCH] [DoctrineBridge] Changed UniqueEntityValidator to use the 2.5 Validation API --- ...egacyUniqueEntityValidator2Dot4ApiTest.php | 26 + ...gacyUniqueEntityValidatorLegacyApiTest.php | 26 + .../Constraints/UniqueEntityValidatorTest.php | 445 ++++++++++++++++++ .../Constraints/UniqueValidatorTest.php | 424 ----------------- .../Constraints/UniqueEntityValidator.php | 11 +- .../AbstractConstraintValidatorTest.php | 2 +- 6 files changed, 508 insertions(+), 426 deletions(-) create mode 100644 src/Symfony/Bridge/Doctrine/Tests/Validator/Constraints/LegacyUniqueEntityValidator2Dot4ApiTest.php create mode 100644 src/Symfony/Bridge/Doctrine/Tests/Validator/Constraints/LegacyUniqueEntityValidatorLegacyApiTest.php create mode 100644 src/Symfony/Bridge/Doctrine/Tests/Validator/Constraints/UniqueEntityValidatorTest.php delete mode 100644 src/Symfony/Bridge/Doctrine/Tests/Validator/Constraints/UniqueValidatorTest.php diff --git a/src/Symfony/Bridge/Doctrine/Tests/Validator/Constraints/LegacyUniqueEntityValidator2Dot4ApiTest.php b/src/Symfony/Bridge/Doctrine/Tests/Validator/Constraints/LegacyUniqueEntityValidator2Dot4ApiTest.php new file mode 100644 index 0000000000..3e1151d520 --- /dev/null +++ b/src/Symfony/Bridge/Doctrine/Tests/Validator/Constraints/LegacyUniqueEntityValidator2Dot4ApiTest.php @@ -0,0 +1,26 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bridge\Doctrine\Tests\Validator\Constraints; + +use Symfony\Component\Validator\Validation; + +/** + * @since 2.5.4 + * @author Bernhard Schussek + */ +class LegacyUniqueEntityValidator2Dot4ApiTest extends UniqueEntityValidatorTest +{ + protected function getApiVersion() + { + return Validation::API_VERSION_2_4; + } +} diff --git a/src/Symfony/Bridge/Doctrine/Tests/Validator/Constraints/LegacyUniqueEntityValidatorLegacyApiTest.php b/src/Symfony/Bridge/Doctrine/Tests/Validator/Constraints/LegacyUniqueEntityValidatorLegacyApiTest.php new file mode 100644 index 0000000000..07382d90e9 --- /dev/null +++ b/src/Symfony/Bridge/Doctrine/Tests/Validator/Constraints/LegacyUniqueEntityValidatorLegacyApiTest.php @@ -0,0 +1,26 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bridge\Doctrine\Tests\Validator\Constraints; + +use Symfony\Component\Validator\Validation; + +/** + * @since 2.5.4 + * @author Bernhard Schussek + */ +class LegacyUniqueEntityValidatorLegacyApiTest extends UniqueEntityValidatorTest +{ + protected function getApiVersion() + { + return Validation::API_VERSION_2_5_BC; + } +} diff --git a/src/Symfony/Bridge/Doctrine/Tests/Validator/Constraints/UniqueEntityValidatorTest.php b/src/Symfony/Bridge/Doctrine/Tests/Validator/Constraints/UniqueEntityValidatorTest.php new file mode 100644 index 0000000000..940a89f069 --- /dev/null +++ b/src/Symfony/Bridge/Doctrine/Tests/Validator/Constraints/UniqueEntityValidatorTest.php @@ -0,0 +1,445 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bridge\Doctrine\Tests\Validator\Constraints; + +use Doctrine\Common\Persistence\ManagerRegistry; +use Doctrine\Common\Persistence\ObjectManager; +use Doctrine\Common\Persistence\ObjectRepository; +use Symfony\Bridge\Doctrine\Test\DoctrineTestHelper; +use Symfony\Bridge\Doctrine\Tests\Fixtures\CompositeIntIdEntity; +use Symfony\Component\Validator\Tests\Constraints\AbstractConstraintValidatorTest; +use Symfony\Bridge\Doctrine\Tests\Fixtures\SingleIntIdEntity; +use Symfony\Bridge\Doctrine\Tests\Fixtures\DoubleNameEntity; +use Symfony\Bridge\Doctrine\Tests\Fixtures\AssociationEntity; +use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity; +use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntityValidator; +use Symfony\Component\Validator\Validation; +use Symfony\Component\Validator\Validator; +use Doctrine\ORM\Tools\SchemaTool; + +/** + * @author Bernhard Schussek + */ +class UniqueEntityValidatorTest extends AbstractConstraintValidatorTest +{ + const EM_NAME = 'foo'; + + /** + * @var ObjectManager + */ + protected $em; + + /** + * @var ManagerRegistry + */ + protected $registry; + + /** + * @var ObjectRepository + */ + protected $repository; + + protected function getApiVersion() + { + return Validation::API_VERSION_2_5; + } + + protected function setUp() + { + $this->em = DoctrineTestHelper::createTestEntityManager(); + $this->registry = $this->createRegistryMock($this->em); + $this->createSchema($this->em); + + parent::setUp(); + } + + protected function createRegistryMock(ObjectManager $em = null) + { + $registry = $this->getMock('Doctrine\Common\Persistence\ManagerRegistry'); + $registry->expects($this->any()) + ->method('getManager') + ->with($this->equalTo(self::EM_NAME)) + ->will($this->returnValue($em)); + + return $registry; + } + + protected function createRepositoryMock() + { + $repository = $this->getMockBuilder('Doctrine\Common\Persistence\ObjectRepository') + ->setMethods(array('findByCustom', 'find', 'findAll', 'findOneBy', 'findBy', 'getClassName')) + ->getMock() + ; + + return $repository; + } + + protected function createEntityManagerMock($repositoryMock) + { + $em = $this->getMockBuilder('Doctrine\Common\Persistence\ObjectManager') + ->getMock() + ; + $em->expects($this->any()) + ->method('getRepository') + ->will($this->returnValue($repositoryMock)) + ; + + $classMetadata = $this->getMock('Doctrine\Common\Persistence\Mapping\ClassMetadata'); + $classMetadata + ->expects($this->any()) + ->method('hasField') + ->will($this->returnValue(true)) + ; + $reflParser = $this->getMockBuilder('Doctrine\Common\Reflection\StaticReflectionParser') + ->disableOriginalConstructor() + ->getMock() + ; + $refl = $this->getMockBuilder('Doctrine\Common\Reflection\StaticReflectionProperty') + ->setConstructorArgs(array($reflParser, 'property-name')) + ->setMethods(array('getValue')) + ->getMock() + ; + $refl + ->expects($this->any()) + ->method('getValue') + ->will($this->returnValue(true)) + ; + $classMetadata->reflFields = array('name' => $refl); + $em->expects($this->any()) + ->method('getClassMetadata') + ->will($this->returnValue($classMetadata)) + ; + + return $em; + } + + protected function createValidator() + { + return new UniqueEntityValidator($this->registry); + } + + private function createSchema(ObjectManager $em) + { + $schemaTool = new SchemaTool($em); + $schemaTool->createSchema(array( + $em->getClassMetadata('Symfony\Bridge\Doctrine\Tests\Fixtures\SingleIntIdEntity'), + $em->getClassMetadata('Symfony\Bridge\Doctrine\Tests\Fixtures\DoubleNameEntity'), + $em->getClassMetadata('Symfony\Bridge\Doctrine\Tests\Fixtures\CompositeIntIdEntity'), + $em->getClassMetadata('Symfony\Bridge\Doctrine\Tests\Fixtures\AssociationEntity'), + )); + } + + /** + * This is a functional test as there is a large integration necessary to get the validator working. + */ + public function testValidateUniqueness() + { + $constraint = new UniqueEntity(array( + 'message' => 'myMessage', + 'fields' => array('name'), + 'em' => self::EM_NAME, + )); + + $entity1 = new SingleIntIdEntity(1, 'Foo'); + $entity2 = new SingleIntIdEntity(2, 'Foo'); + + $this->validator->validate($entity1, $constraint); + + $this->assertNoViolation(); + + $this->em->persist($entity1); + $this->em->flush(); + + $this->validator->validate($entity1, $constraint); + + $this->assertNoViolation(); + + $this->validator->validate($entity2, $constraint); + + $this->assertViolation('myMessage', array(), 'property.path.name', 'Foo'); + } + + public function testValidateCustomErrorPath() + { + $constraint = new UniqueEntity(array( + 'message' => 'myMessage', + 'fields' => array('name'), + 'em' => self::EM_NAME, + 'errorPath' => 'bar', + )); + + $entity1 = new SingleIntIdEntity(1, 'Foo'); + $entity2 = new SingleIntIdEntity(2, 'Foo'); + + $this->em->persist($entity1); + $this->em->flush(); + + $this->validator->validate($entity2, $constraint); + + $this->assertViolation('myMessage', array(), 'property.path.bar', 'Foo'); + } + + public function testValidateUniquenessWithNull() + { + $constraint = new UniqueEntity(array( + 'message' => 'myMessage', + 'fields' => array('name'), + 'em' => self::EM_NAME, + )); + + $entity1 = new SingleIntIdEntity(1, null); + $entity2 = new SingleIntIdEntity(2, null); + + $this->em->persist($entity1); + $this->em->persist($entity2); + $this->em->flush(); + + $this->validator->validate($entity1, $constraint); + + $this->assertNoViolation(); + } + + public function testValidateUniquenessWithIgnoreNull() + { + $constraint = new UniqueEntity(array( + 'message' => 'myMessage', + 'fields' => array('name', 'name2'), + 'em' => self::EM_NAME, + 'ignoreNull' => false, + )); + + $entity1 = new DoubleNameEntity(1, 'Foo', null); + $entity2 = new DoubleNameEntity(2, 'Foo', null); + + $this->validator->validate($entity1, $constraint); + + $this->assertNoViolation(); + + $this->em->persist($entity1); + $this->em->flush(); + + $this->validator->validate($entity1, $constraint); + + $this->assertNoViolation(); + + $this->validator->validate($entity2, $constraint); + + $this->assertViolation('myMessage', array(), 'property.path.name', 'Foo'); + } + + public function testValidateUniquenessAfterConsideringMultipleQueryResults() + { + $constraint = new UniqueEntity(array( + 'message' => 'myMessage', + 'fields' => array('name'), + 'em' => self::EM_NAME, + )); + + $entity1 = new SingleIntIdEntity(1, 'Foo'); + $entity2 = new SingleIntIdEntity(2, 'Foo'); + + $this->em->persist($entity1); + $this->em->persist($entity2); + $this->em->flush(); + + $this->validator->validate($entity1, $constraint); + + $this->assertViolation('myMessage', array(), 'property.path.name', 'Foo'); + $this->context->getViolations()->remove(0); + + $this->validator->validate($entity2, $constraint); + + $this->assertViolation('myMessage', array(), 'property.path.name', 'Foo'); + } + + public function testValidateUniquenessUsingCustomRepositoryMethod() + { + $constraint = new UniqueEntity(array( + 'message' => 'myMessage', + 'fields' => array('name'), + 'em' => self::EM_NAME, + 'repositoryMethod' => 'findByCustom', + )); + + $repository = $this->createRepositoryMock(); + $repository->expects($this->once()) + ->method('findByCustom') + ->will($this->returnValue(array())) + ; + $this->em = $this->createEntityManagerMock($repository); + $this->registry = $this->createRegistryMock($this->em); + $this->validator = $this->createValidator(); + $this->validator->initialize($this->context); + + $entity1 = new SingleIntIdEntity(1, 'foo'); + + $this->validator->validate($entity1, $constraint); + + $this->assertNoViolation(); + } + + public function testValidateUniquenessWithUnrewoundArray() + { + $constraint = new UniqueEntity(array( + 'message' => 'myMessage', + 'fields' => array('name'), + 'em' => self::EM_NAME, + 'repositoryMethod' => 'findByCustom', + )); + + $entity = new SingleIntIdEntity(1, 'foo'); + + $repository = $this->createRepositoryMock(); + $repository->expects($this->once()) + ->method('findByCustom') + ->will( + $this->returnCallback(function () use ($entity) { + $returnValue = array( + $entity, + ); + next($returnValue); + + return $returnValue; + }) + ) + ; + $this->em = $this->createEntityManagerMock($repository); + $this->registry = $this->createRegistryMock($this->em); + $this->validator = $this->createValidator(); + $this->validator->initialize($this->context); + + $this->validator->validate($entity, $constraint); + + $this->assertNoViolation(); + } + + /** + * @group GH-1635 + */ + public function testAssociatedEntity() + { + $constraint = new UniqueEntity(array( + 'message' => 'myMessage', + 'fields' => array('single'), + 'em' => self::EM_NAME, + )); + + $entity1 = new SingleIntIdEntity(1, 'foo'); + $associated = new AssociationEntity(); + $associated->single = $entity1; + $associated2 = new AssociationEntity(); + $associated2->single = $entity1; + + $this->em->persist($entity1); + $this->em->persist($associated); + $this->em->flush(); + + $this->validator->validate($associated, $constraint); + + $this->assertNoViolation(); + + $this->em->persist($associated2); + $this->em->flush(); + + $this->validator->validate($associated2, $constraint); + + $this->assertViolation('myMessage', array(), 'property.path.single', 1); + } + + public function testAssociatedEntityWithNull() + { + $constraint = new UniqueEntity(array( + 'message' => 'myMessage', + 'fields' => array('single'), + 'em' => self::EM_NAME, + 'ignoreNull' => false, + )); + + $associated = new AssociationEntity(); + $associated->single = null; + + $this->em->persist($associated); + $this->em->flush(); + + $this->validator->validate($associated, $constraint); + + $this->assertNoViolation(); + } + + /** + * @expectedException \Symfony\Component\Validator\Exception\ConstraintDefinitionException + * @expectedExceptionMessage Associated entities are not allowed to have more than one identifier field + * @group GH-1635 + */ + public function testAssociatedCompositeEntity() + { + $constraint = new UniqueEntity(array( + 'message' => 'myMessage', + 'fields' => array('composite'), + 'em' => self::EM_NAME, + )); + + $composite = new CompositeIntIdEntity(1, 1, "test"); + $associated = new AssociationEntity(); + $associated->composite = $composite; + + $this->em->persist($composite); + $this->em->persist($associated); + $this->em->flush(); + + $this->validator->validate($associated, $constraint); + } + + /** + * @expectedException \Symfony\Component\Validator\Exception\ConstraintDefinitionException + * @expectedExceptionMessage Object manager "foo" does not exist. + */ + public function testDedicatedEntityManagerNullObject() + { + $constraint = new UniqueEntity(array( + 'message' => 'myMessage', + 'fields' => array('name'), + 'em' => self::EM_NAME, + )); + + $this->em = null; + $this->registry = $this->createRegistryMock($this->em); + $this->validator = $this->createValidator(); + $this->validator->initialize($this->context); + + $entity = new SingleIntIdEntity(1, null); + + $this->validator->validate($entity, $constraint); + } + + /** + * @expectedException \Symfony\Component\Validator\Exception\ConstraintDefinitionException + * @expectedExceptionMessage Unable to find the object manager associated with an entity of class "Symfony\Bridge\Doctrine\Tests\Fixtures\SingleIntIdEntity" + */ + public function testEntityManagerNullObject() + { + $constraint = new UniqueEntity(array( + 'message' => 'myMessage', + 'fields' => array('name'), + // no "em" option set + )); + + $this->em = null; + $this->registry = $this->createRegistryMock($this->em); + $this->validator = $this->createValidator(); + $this->validator->initialize($this->context); + + $entity = new SingleIntIdEntity(1, null); + + $this->validator->validate($entity, $constraint); + } +} diff --git a/src/Symfony/Bridge/Doctrine/Tests/Validator/Constraints/UniqueValidatorTest.php b/src/Symfony/Bridge/Doctrine/Tests/Validator/Constraints/UniqueValidatorTest.php deleted file mode 100644 index c96418de4a..0000000000 --- a/src/Symfony/Bridge/Doctrine/Tests/Validator/Constraints/UniqueValidatorTest.php +++ /dev/null @@ -1,424 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Bridge\Doctrine\Tests\Validator\Constraints; - -use Symfony\Bridge\Doctrine\Test\DoctrineTestHelper; -use Symfony\Bridge\Doctrine\Tests\Fixtures\CompositeIntIdEntity; -use Symfony\Component\Validator\DefaultTranslator; -use Symfony\Component\Validator\Tests\Fixtures\FakeMetadataFactory; -use Symfony\Bridge\Doctrine\Tests\Fixtures\SingleIntIdEntity; -use Symfony\Bridge\Doctrine\Tests\Fixtures\DoubleNameEntity; -use Symfony\Bridge\Doctrine\Tests\Fixtures\AssociationEntity; -use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity; -use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntityValidator; -use Symfony\Component\Validator\Mapping\ClassMetadata; -use Symfony\Component\Validator\Validator; -use Doctrine\ORM\Tools\SchemaTool; - -class UniqueValidatorTest extends \PHPUnit_Framework_TestCase -{ - protected function createRegistryMock($entityManagerName, $em) - { - $registry = $this->getMock('Doctrine\Common\Persistence\ManagerRegistry'); - $registry->expects($this->any()) - ->method('getManager') - ->with($this->equalTo($entityManagerName)) - ->will($this->returnValue($em)); - - return $registry; - } - - protected function createRepositoryMock() - { - $repository = $this->getMockBuilder('Doctrine\Common\Persistence\ObjectRepository') - ->setMethods(array('findByCustom', 'find', 'findAll', 'findOneBy', 'findBy', 'getClassName')) - ->getMock() - ; - - return $repository; - } - - protected function createEntityManagerMock($repositoryMock) - { - $em = $this->getMockBuilder('Doctrine\Common\Persistence\ObjectManager') - ->getMock() - ; - $em->expects($this->any()) - ->method('getRepository') - ->will($this->returnValue($repositoryMock)) - ; - - $classMetadata = $this->getMock('Doctrine\Common\Persistence\Mapping\ClassMetadata'); - $classMetadata - ->expects($this->any()) - ->method('hasField') - ->will($this->returnValue(true)) - ; - $reflParser = $this->getMockBuilder('Doctrine\Common\Reflection\StaticReflectionParser') - ->disableOriginalConstructor() - ->getMock() - ; - $refl = $this->getMockBuilder('Doctrine\Common\Reflection\StaticReflectionProperty') - ->setConstructorArgs(array($reflParser, 'property-name')) - ->setMethods(array('getValue')) - ->getMock() - ; - $refl - ->expects($this->any()) - ->method('getValue') - ->will($this->returnValue(true)) - ; - $classMetadata->reflFields = array('name' => $refl); - $em->expects($this->any()) - ->method('getClassMetadata') - ->will($this->returnValue($classMetadata)) - ; - - return $em; - } - - protected function createValidatorFactory($uniqueValidator) - { - $validatorFactory = $this->getMock('Symfony\Component\Validator\ConstraintValidatorFactoryInterface'); - $validatorFactory->expects($this->any()) - ->method('getInstance') - ->with($this->isInstanceOf('Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity')) - ->will($this->returnValue($uniqueValidator)); - - return $validatorFactory; - } - - public function createValidator($entityManagerName, $em, $validateClass = null, $uniqueFields = null, $errorPath = null, $repositoryMethod = 'findBy', $ignoreNull = true) - { - if (!$validateClass) { - $validateClass = 'Symfony\Bridge\Doctrine\Tests\Fixtures\SingleIntIdEntity'; - } - if (!$uniqueFields) { - $uniqueFields = array('name'); - } - - $registry = $this->createRegistryMock($entityManagerName, $em); - - $uniqueValidator = new UniqueEntityValidator($registry); - - $metadata = new ClassMetadata($validateClass); - $constraint = new UniqueEntity(array( - 'fields' => $uniqueFields, - 'em' => $entityManagerName, - 'errorPath' => $errorPath, - 'repositoryMethod' => $repositoryMethod, - 'ignoreNull' => $ignoreNull - )); - $metadata->addConstraint($constraint); - - $metadataFactory = new FakeMetadataFactory(); - $metadataFactory->addMetadata($metadata); - $validatorFactory = $this->createValidatorFactory($uniqueValidator); - - return new Validator($metadataFactory, $validatorFactory, new DefaultTranslator()); - } - - private function createSchema($em) - { - $schemaTool = new SchemaTool($em); - $schemaTool->createSchema(array( - $em->getClassMetadata('Symfony\Bridge\Doctrine\Tests\Fixtures\SingleIntIdEntity'), - $em->getClassMetadata('Symfony\Bridge\Doctrine\Tests\Fixtures\DoubleNameEntity'), - $em->getClassMetadata('Symfony\Bridge\Doctrine\Tests\Fixtures\CompositeIntIdEntity'), - $em->getClassMetadata('Symfony\Bridge\Doctrine\Tests\Fixtures\AssociationEntity'), - )); - } - - /** - * This is a functional test as there is a large integration necessary to get the validator working. - */ - public function testValidateUniqueness() - { - $entityManagerName = "foo"; - $em = DoctrineTestHelper::createTestEntityManager(); - $this->createSchema($em); - $validator = $this->createValidator($entityManagerName, $em); - - $entity1 = new SingleIntIdEntity(1, 'Foo'); - $violationsList = $validator->validate($entity1); - $this->assertEquals(0, $violationsList->count(), "No violations found on entity before it is saved to the database."); - - $em->persist($entity1); - $em->flush(); - - $violationsList = $validator->validate($entity1); - $this->assertEquals(0, $violationsList->count(), "No violations found on entity after it was saved to the database."); - - $entity2 = new SingleIntIdEntity(2, 'Foo'); - - $violationsList = $validator->validate($entity2); - $this->assertEquals(1, $violationsList->count(), "Violation found on entity with conflicting entity existing in the database."); - - $violation = $violationsList[0]; - $this->assertEquals('This value is already used.', $violation->getMessage()); - $this->assertEquals('name', $violation->getPropertyPath()); - $this->assertEquals('Foo', $violation->getInvalidValue()); - } - - public function testValidateCustomErrorPath() - { - $entityManagerName = "foo"; - $em = DoctrineTestHelper::createTestEntityManager(); - $this->createSchema($em); - $validator = $this->createValidator($entityManagerName, $em, null, null, 'bar'); - - $entity1 = new SingleIntIdEntity(1, 'Foo'); - - $em->persist($entity1); - $em->flush(); - - $entity2 = new SingleIntIdEntity(2, 'Foo'); - - $violationsList = $validator->validate($entity2); - $this->assertEquals(1, $violationsList->count(), "Violation found on entity with conflicting entity existing in the database."); - - $violation = $violationsList[0]; - $this->assertEquals('This value is already used.', $violation->getMessage()); - $this->assertEquals('bar', $violation->getPropertyPath()); - $this->assertEquals('Foo', $violation->getInvalidValue()); - } - - public function testValidateUniquenessWithNull() - { - $entityManagerName = "foo"; - $em = DoctrineTestHelper::createTestEntityManager(); - $this->createSchema($em); - $validator = $this->createValidator($entityManagerName, $em); - - $entity1 = new SingleIntIdEntity(1, null); - $entity2 = new SingleIntIdEntity(2, null); - - $em->persist($entity1); - $em->persist($entity2); - $em->flush(); - - $violationsList = $validator->validate($entity1); - $this->assertEquals(0, $violationsList->count(), "No violations found on entity having a null value."); - } - - public function testValidateUniquenessWithIgnoreNull() - { - $entityManagerName = "foo"; - $validateClass = 'Symfony\Bridge\Doctrine\Tests\Fixtures\DoubleNameEntity'; - $em = DoctrineTestHelper::createTestEntityManager(); - $this->createSchema($em); - $validator = $this->createValidator($entityManagerName, $em, $validateClass, array('name', 'name2'), 'bar', 'findby', false); - - $entity1 = new DoubleNameEntity(1, 'Foo', null); - $violationsList = $validator->validate($entity1); - $this->assertEquals(0, $violationsList->count(), "No violations found on entity before it is saved to the database."); - - $em->persist($entity1); - $em->flush(); - - $violationsList = $validator->validate($entity1); - $this->assertEquals(0, $violationsList->count(), "No violations found on entity after it was saved to the database."); - - $entity2 = new DoubleNameEntity(2, 'Foo', null); - - $violationsList = $validator->validate($entity2); - $this->assertEquals(1, $violationsList->count(), "Violation found on entity with conflicting entity existing in the database."); - - $violation = $violationsList[0]; - $this->assertEquals('This value is already used.', $violation->getMessage()); - $this->assertEquals('bar', $violation->getPropertyPath()); - $this->assertEquals('Foo', $violation->getInvalidValue()); - } - - public function testValidateUniquenessAfterConsideringMultipleQueryResults() - { - $entityManagerName = "foo"; - $em = DoctrineTestHelper::createTestEntityManager(); - $this->createSchema($em); - $validator = $this->createValidator($entityManagerName, $em); - - $entity1 = new SingleIntIdEntity(1, 'foo'); - $entity2 = new SingleIntIdEntity(2, 'foo'); - - $em->persist($entity1); - $em->persist($entity2); - $em->flush(); - - $violationsList = $validator->validate($entity1); - $this->assertEquals(1, $violationsList->count(), 'Violation found on entity with conflicting entity existing in the database.'); - - $violationsList = $validator->validate($entity2); - $this->assertEquals(1, $violationsList->count(), 'Violation found on entity with conflicting entity existing in the database.'); - } - - public function testValidateUniquenessUsingCustomRepositoryMethod() - { - $entityManagerName = 'foo'; - $repository = $this->createRepositoryMock(); - $repository->expects($this->once()) - ->method('findByCustom') - ->will($this->returnValue(array())) - ; - $em = $this->createEntityManagerMock($repository); - $validator = $this->createValidator($entityManagerName, $em, null, array(), null, 'findByCustom'); - - $entity1 = new SingleIntIdEntity(1, 'foo'); - - $violationsList = $validator->validate($entity1); - $this->assertEquals(0, $violationsList->count(), 'Violation is using custom repository method.'); - } - - public function testValidateUniquenessWithUnrewoundArray() - { - $entity = new SingleIntIdEntity(1, 'foo'); - - $entityManagerName = 'foo'; - $repository = $this->createRepositoryMock(); - $repository->expects($this->once()) - ->method('findByCustom') - ->will( - $this->returnCallback(function () use ($entity) { - $returnValue = array( - $entity, - ); - next($returnValue); - - return $returnValue; - }) - ) - ; - $em = $this->createEntityManagerMock($repository); - $validator = $this->createValidator($entityManagerName, $em, null, array(), null, 'findByCustom'); - - $violationsList = $validator->validate($entity); - $this->assertCount(0, $violationsList, 'Violation is using unrewound array as return value in the repository method.'); - } - - /** - * @group GH-1635 - */ - public function testAssociatedEntity() - { - $entityManagerName = "foo"; - $em = DoctrineTestHelper::createTestEntityManager(); - $this->createSchema($em); - $validator = $this->createValidator($entityManagerName, $em, 'Symfony\Bridge\Doctrine\Tests\Fixtures\AssociationEntity', array('single')); - - $entity1 = new SingleIntIdEntity(1, 'foo'); - $associated = new AssociationEntity(); - $associated->single = $entity1; - - $em->persist($entity1); - $em->persist($associated); - $em->flush(); - - $violationsList = $validator->validate($associated); - $this->assertEquals(0, $violationsList->count()); - - $associated2 = new AssociationEntity(); - $associated2->single = $entity1; - - $em->persist($associated2); - $em->flush(); - - $violationsList = $validator->validate($associated2); - $this->assertEquals(1, $violationsList->count()); - } - - public function testAssociatedEntityWithNull() - { - $entityManagerName = "foo"; - $em = DoctrineTestHelper::createTestEntityManager(); - $this->createSchema($em); - $validator = $this->createValidator($entityManagerName, $em, 'Symfony\Bridge\Doctrine\Tests\Fixtures\AssociationEntity', array('single'), null, 'findBy', false); - - $associated = new AssociationEntity(); - $associated->single = null; - - $em->persist($associated); - $em->flush(); - - $violationsList = $validator->validate($associated); - $this->assertEquals(0, $violationsList->count()); - } - - /** - * @group GH-1635 - */ - public function testAssociatedCompositeEntity() - { - $entityManagerName = "foo"; - $em = DoctrineTestHelper::createTestEntityManager(); - $this->createSchema($em); - $validator = $this->createValidator($entityManagerName, $em, 'Symfony\Bridge\Doctrine\Tests\Fixtures\AssociationEntity', array('composite')); - - $composite = new CompositeIntIdEntity(1, 1, "test"); - $associated = new AssociationEntity(); - $associated->composite = $composite; - - $em->persist($composite); - $em->persist($associated); - $em->flush(); - - $this->setExpectedException( - 'Symfony\Component\Validator\Exception\ConstraintDefinitionException', - 'Associated entities are not allowed to have more than one identifier field' - ); - $violationsList = $validator->validate($associated); - } - - public function testDedicatedEntityManagerNullObject() - { - $uniqueFields = array('name'); - $entityManagerName = 'foo'; - - $registry = $this->getMock('Doctrine\Common\Persistence\ManagerRegistry'); - - $constraint = new UniqueEntity(array( - 'fields' => $uniqueFields, - 'em' => $entityManagerName, - )); - - $uniqueValidator = new UniqueEntityValidator($registry); - - $entity = new SingleIntIdEntity(1, null); - - $this->setExpectedException( - 'Symfony\Component\Validator\Exception\ConstraintDefinitionException', - 'Object manager "foo" does not exist.' - ); - - $uniqueValidator->validate($entity, $constraint); - } - - public function testEntityManagerNullObject() - { - $uniqueFields = array('name'); - - $registry = $this->getMock('Doctrine\Common\Persistence\ManagerRegistry'); - - $constraint = new UniqueEntity(array( - 'fields' => $uniqueFields, - )); - - $uniqueValidator = new UniqueEntityValidator($registry); - - $entity = new SingleIntIdEntity(1, null); - - $this->setExpectedException( - 'Symfony\Component\Validator\Exception\ConstraintDefinitionException', - 'Unable to find the object manager associated with an entity of class "Symfony\Bridge\Doctrine\Tests\Fixtures\SingleIntIdEntity"' - ); - - $uniqueValidator->validate($entity, $constraint); - } -} diff --git a/src/Symfony/Bridge/Doctrine/Validator/Constraints/UniqueEntityValidator.php b/src/Symfony/Bridge/Doctrine/Validator/Constraints/UniqueEntityValidator.php index 54e667972d..0a690251fe 100644 --- a/src/Symfony/Bridge/Doctrine/Validator/Constraints/UniqueEntityValidator.php +++ b/src/Symfony/Bridge/Doctrine/Validator/Constraints/UniqueEntityValidator.php @@ -13,6 +13,7 @@ namespace Symfony\Bridge\Doctrine\Validator\Constraints; use Doctrine\Common\Persistence\ManagerRegistry; use Symfony\Component\Validator\Constraint; +use Symfony\Component\Validator\Context\ExecutionContextInterface; use Symfony\Component\Validator\Exception\UnexpectedTypeException; use Symfony\Component\Validator\Exception\ConstraintDefinitionException; use Symfony\Component\Validator\ConstraintValidator; @@ -136,6 +137,14 @@ class UniqueEntityValidator extends ConstraintValidator $errorPath = null !== $constraint->errorPath ? $constraint->errorPath : $fields[0]; - $this->context->addViolationAt($errorPath, $constraint->message, array(), $criteria[$fields[0]]); + if ($this->context instanceof ExecutionContextInterface) { + $this->context->buildViolation($constraint->message) + ->atPath($errorPath) + ->setInvalidValue($criteria[$fields[0]]) + ->addViolation(); + } else { + // 2.4 API + $this->context->addViolationAt($errorPath, $constraint->message, array(), $criteria[$fields[0]]); + } } } diff --git a/src/Symfony/Component/Validator/Tests/Constraints/AbstractConstraintValidatorTest.php b/src/Symfony/Component/Validator/Tests/Constraints/AbstractConstraintValidatorTest.php index 678c20ff1f..cedb34c3a9 100644 --- a/src/Symfony/Component/Validator/Tests/Constraints/AbstractConstraintValidatorTest.php +++ b/src/Symfony/Component/Validator/Tests/Constraints/AbstractConstraintValidatorTest.php @@ -298,7 +298,7 @@ abstract class AbstractConstraintValidatorTest extends \PHPUnit_Framework_TestCa $violations = $this->context->getViolations(); $this->assertCount(1, $violations); - $this->assertEquals($this->createViolation($message, $parameters, $propertyPath, $invalidValue, $plural, $code), $violations[0]); + $this->assertEquals($this->createViolation($message, $parameters, $propertyPath, $invalidValue, $plural, $code), current(iterator_to_array($violations))); } protected function assertViolations(array $expected)