[Form] Adapted FormValidator to latest changes in the Validator

This commit is contained in:
Bernhard Schussek 2012-11-22 16:42:25 +01:00
parent 1f752e866e
commit 1858b96b7d
2 changed files with 136 additions and 154 deletions

View File

@ -51,18 +51,12 @@ class FormValidator extends ConstraintValidator
if ($form->isSynchronized()) { if ($form->isSynchronized()) {
// Validate the form data only if transformation succeeded // Validate the form data only if transformation succeeded
$path = $this->context->getPropertyPath();
$graphWalker = $this->context->getGraphWalker();
$groups = self::getValidationGroups($form); $groups = self::getValidationGroups($form);
if (!empty($path)) {
$path .= '.';
}
// Validate the data against its own constraints // Validate the data against its own constraints
if (self::allowDataWalking($form)) { if (self::allowDataWalking($form)) {
foreach ($groups as $group) { foreach ($groups as $group) {
$graphWalker->walkReference($form->getData(), $group, $path . 'data', true); $this->context->validate($form->getData(), 'data', $group, true);
} }
} }
@ -72,7 +66,7 @@ class FormValidator extends ConstraintValidator
foreach ($constraints as $constraint) { foreach ($constraints as $constraint) {
foreach ($groups as $group) { foreach ($groups as $group) {
if (in_array($group, $constraint->groups)) { if (in_array($group, $constraint->groups)) {
$graphWalker->walkConstraint($constraint, $form->getData(), $group, $path . 'data'); $this->context->validateValue($form->getData(), $constraint, 'data', $group);
// Prevent duplicate validation // Prevent duplicate validation
continue 2; continue 2;

View File

@ -22,8 +22,6 @@ use Symfony\Component\Form\Util\PropertyPath;
use Symfony\Component\Validator\Constraint; use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\Constraints\NotNull; use Symfony\Component\Validator\Constraints\NotNull;
use Symfony\Component\Validator\Constraints\NotBlank; use Symfony\Component\Validator\Constraints\NotBlank;
use Symfony\Component\Validator\GlobalExecutionContext;
use Symfony\Component\Validator\ExecutionContext;
/** /**
* @author Bernhard Schussek <bschussek@gmail.com> * @author Bernhard Schussek <bschussek@gmail.com>
@ -67,20 +65,19 @@ class FormValidatorTest extends \PHPUnit_Framework_TestCase
public function testValidate() public function testValidate()
{ {
$context = $this->getExecutionContext(); $context = $this->getMockExecutionContext();
$graphWalker = $context->getGraphWalker();
$object = $this->getMock('\stdClass'); $object = $this->getMock('\stdClass');
$options = array('validation_groups' => array('group1', 'group2')); $options = array('validation_groups' => array('group1', 'group2'));
$form = $this->getBuilder('name', '\stdClass', $options) $form = $this->getBuilder('name', '\stdClass', $options)
->setData($object) ->setData($object)
->getForm(); ->getForm();
$graphWalker->expects($this->at(0)) $context->expects($this->at(0))
->method('walkReference') ->method('validate')
->with($object, 'group1', 'data', true); ->with($object, 'data', 'group1', true);
$graphWalker->expects($this->at(1)) $context->expects($this->at(1))
->method('walkReference') ->method('validate')
->with($object, 'group2', 'data', true); ->with($object, 'data', 'group2', true);
$this->validator->initialize($context); $this->validator->initialize($context);
$this->validator->validate($form, new Form()); $this->validator->validate($form, new Form());
@ -88,8 +85,7 @@ class FormValidatorTest extends \PHPUnit_Framework_TestCase
public function testValidateConstraints() public function testValidateConstraints()
{ {
$context = $this->getExecutionContext(); $context = $this->getMockExecutionContext();
$graphWalker = $context->getGraphWalker();
$object = $this->getMock('\stdClass'); $object = $this->getMock('\stdClass');
$constraint1 = new NotNull(array('groups' => array('group1', 'group2'))); $constraint1 = new NotNull(array('groups' => array('group1', 'group2')));
$constraint2 = new NotBlank(array('groups' => 'group2')); $constraint2 = new NotBlank(array('groups' => 'group2'));
@ -103,20 +99,20 @@ class FormValidatorTest extends \PHPUnit_Framework_TestCase
->getForm(); ->getForm();
// First default constraints // First default constraints
$graphWalker->expects($this->at(0)) $context->expects($this->at(0))
->method('walkReference') ->method('validate')
->with($object, 'group1', 'data', true); ->with($object, 'data', 'group1', true);
$graphWalker->expects($this->at(1)) $context->expects($this->at(1))
->method('walkReference') ->method('validate')
->with($object, 'group2', 'data', true); ->with($object, 'data', 'group2', true);
// Then custom constraints // Then custom constraints
$graphWalker->expects($this->at(2)) $context->expects($this->at(2))
->method('walkConstraint') ->method('validateValue')
->with($constraint1, $object, 'group1', 'data'); ->with($object, $constraint1, 'data', 'group1');
$graphWalker->expects($this->at(3)) $context->expects($this->at(3))
->method('walkConstraint') ->method('validateValue')
->with($constraint2, $object, 'group2', 'data'); ->with($object, $constraint2, 'data', 'group2');
$this->validator->initialize($context); $this->validator->initialize($context);
$this->validator->validate($form, new Form()); $this->validator->validate($form, new Form());
@ -124,8 +120,7 @@ class FormValidatorTest extends \PHPUnit_Framework_TestCase
public function testDontValidateIfParentWithoutCascadeValidation() public function testDontValidateIfParentWithoutCascadeValidation()
{ {
$context = $this->getExecutionContext(); $context = $this->getMockExecutionContext();
$graphWalker = $context->getGraphWalker();
$object = $this->getMock('\stdClass'); $object = $this->getMock('\stdClass');
$parent = $this->getBuilder('parent', null, array('cascade_validation' => false)) $parent = $this->getBuilder('parent', null, array('cascade_validation' => false))
@ -138,8 +133,8 @@ class FormValidatorTest extends \PHPUnit_Framework_TestCase
$form->setData($object); $form->setData($object);
$graphWalker->expects($this->never()) $context->expects($this->never())
->method('walkReference'); ->method('validate');
$this->validator->initialize($context); $this->validator->initialize($context);
$this->validator->validate($form, new Form()); $this->validator->validate($form, new Form());
@ -147,8 +142,7 @@ class FormValidatorTest extends \PHPUnit_Framework_TestCase
public function testValidateConstraintsEvenIfNoCascadeValidation() public function testValidateConstraintsEvenIfNoCascadeValidation()
{ {
$context = $this->getExecutionContext(); $context = $this->getMockExecutionContext();
$graphWalker = $context->getGraphWalker();
$object = $this->getMock('\stdClass'); $object = $this->getMock('\stdClass');
$constraint1 = new NotNull(array('groups' => array('group1', 'group2'))); $constraint1 = new NotNull(array('groups' => array('group1', 'group2')));
$constraint2 = new NotBlank(array('groups' => 'group2')); $constraint2 = new NotBlank(array('groups' => 'group2'));
@ -166,12 +160,12 @@ class FormValidatorTest extends \PHPUnit_Framework_TestCase
->getForm(); ->getForm();
$parent->add($form); $parent->add($form);
$graphWalker->expects($this->at(0)) $context->expects($this->at(0))
->method('walkConstraint') ->method('validateValue')
->with($constraint1, $object, 'group1', 'data'); ->with($object, $constraint1, 'data', 'group1');
$graphWalker->expects($this->at(1)) $context->expects($this->at(1))
->method('walkConstraint') ->method('validateValue')
->with($constraint2, $object, 'group2', 'data'); ->with($object, $constraint2, 'data', 'group2');
$this->validator->initialize($context); $this->validator->initialize($context);
$this->validator->validate($form, new Form()); $this->validator->validate($form, new Form());
@ -179,8 +173,7 @@ class FormValidatorTest extends \PHPUnit_Framework_TestCase
public function testDontValidateIfNotSynchronized() public function testDontValidateIfNotSynchronized()
{ {
$context = $this->getExecutionContext(); $context = $this->getMockExecutionContext();
$graphWalker = $context->getGraphWalker();
$object = $this->getMock('\stdClass'); $object = $this->getMock('\stdClass');
$form = $this->getBuilder('name', '\stdClass', array( $form = $this->getBuilder('name', '\stdClass', array(
@ -200,30 +193,26 @@ class FormValidatorTest extends \PHPUnit_Framework_TestCase
// Launch transformer // Launch transformer
$form->bind('foo'); $form->bind('foo');
$graphWalker->expects($this->never()) $context->expects($this->never())
->method('walkReference'); ->method('validate');
$context->expects($this->once())
->method('addViolation')
->with(
'invalid_message_key',
array('{{ value }}' => 'foo', '{{ foo }}' => 'bar'),
'foo'
);
$context->expects($this->never())
->method('addViolationAt');
$this->validator->initialize($context); $this->validator->initialize($context);
$this->validator->validate($form, new Form()); $this->validator->validate($form, new Form());
$expectedViolation = new ConstraintViolation(
'invalid_message_key',
array('{{ value }}' => 'foo', '{{ foo }}' => 'bar'),
'Root',
null,
'foo',
null,
Form::ERR_INVALID
);
$this->assertCount(1, $context->getViolations());
$this->assertEquals($expectedViolation, $context->getViolations()->get(0));
} }
public function testDontValidateConstraintsIfNotSynchronized() public function testDontValidateConstraintsIfNotSynchronized()
{ {
$context = $this->getExecutionContext(); $context = $this->getMockExecutionContext();
$graphWalker = $context->getGraphWalker();
$object = $this->getMock('\stdClass'); $object = $this->getMock('\stdClass');
$constraint1 = $this->getMock('Symfony\Component\Validator\Constraint'); $constraint1 = $this->getMock('Symfony\Component\Validator\Constraint');
$constraint2 = $this->getMock('Symfony\Component\Validator\Constraint'); $constraint2 = $this->getMock('Symfony\Component\Validator\Constraint');
@ -243,8 +232,8 @@ class FormValidatorTest extends \PHPUnit_Framework_TestCase
// Launch transformer // Launch transformer
$form->bind(array()); $form->bind(array());
$graphWalker->expects($this->never()) $context->expects($this->never())
->method('walkReference'); ->method('validate');
$this->validator->initialize($context); $this->validator->initialize($context);
$this->validator->validate($form, new Form()); $this->validator->validate($form, new Form());
@ -253,7 +242,7 @@ class FormValidatorTest extends \PHPUnit_Framework_TestCase
// https://github.com/symfony/symfony/issues/4359 // https://github.com/symfony/symfony/issues/4359
public function testDontMarkInvalidIfAnyChildIsNotSynchronized() public function testDontMarkInvalidIfAnyChildIsNotSynchronized()
{ {
$context = $this->getExecutionContext(); $context = $this->getMockExecutionContext();
$object = $this->getMock('\stdClass'); $object = $this->getMock('\stdClass');
$failingTransformer = new CallbackTransformer( $failingTransformer = new CallbackTransformer(
@ -275,28 +264,30 @@ class FormValidatorTest extends \PHPUnit_Framework_TestCase
// Launch transformer // Launch transformer
$form->bind(array('child' => 'foo')); $form->bind(array('child' => 'foo'));
$context->expects($this->never())
->method('addViolation');
$context->expects($this->never())
->method('addViolationAt');
$this->validator->initialize($context); $this->validator->initialize($context);
$this->validator->validate($form, new Form()); $this->validator->validate($form, new Form());
$this->assertCount(0, $context->getViolations());
} }
public function testHandleCallbackValidationGroups() public function testHandleCallbackValidationGroups()
{ {
$context = $this->getExecutionContext(); $context = $this->getMockExecutionContext();
$graphWalker = $context->getGraphWalker();
$object = $this->getMock('\stdClass'); $object = $this->getMock('\stdClass');
$options = array('validation_groups' => array($this, 'getValidationGroups')); $options = array('validation_groups' => array($this, 'getValidationGroups'));
$form = $this->getBuilder('name', '\stdClass', $options) $form = $this->getBuilder('name', '\stdClass', $options)
->setData($object) ->setData($object)
->getForm(); ->getForm();
$graphWalker->expects($this->at(0)) $context->expects($this->at(0))
->method('walkReference') ->method('validate')
->with($object, 'group1', 'data', true); ->with($object, 'data', 'group1', true);
$graphWalker->expects($this->at(1)) $context->expects($this->at(1))
->method('walkReference') ->method('validate')
->with($object, 'group2', 'data', true); ->with($object, 'data', 'group2', true);
$this->validator->initialize($context); $this->validator->initialize($context);
$this->validator->validate($form, new Form()); $this->validator->validate($form, new Form());
@ -304,8 +295,7 @@ class FormValidatorTest extends \PHPUnit_Framework_TestCase
public function testHandleClosureValidationGroups() public function testHandleClosureValidationGroups()
{ {
$context = $this->getExecutionContext(); $context = $this->getMockExecutionContext();
$graphWalker = $context->getGraphWalker();
$object = $this->getMock('\stdClass'); $object = $this->getMock('\stdClass');
$options = array('validation_groups' => function(FormInterface $form){ $options = array('validation_groups' => function(FormInterface $form){
return array('group1', 'group2'); return array('group1', 'group2');
@ -314,12 +304,12 @@ class FormValidatorTest extends \PHPUnit_Framework_TestCase
->setData($object) ->setData($object)
->getForm(); ->getForm();
$graphWalker->expects($this->at(0)) $context->expects($this->at(0))
->method('walkReference') ->method('validate')
->with($object, 'group1', 'data', true); ->with($object, 'data', 'group1', true);
$graphWalker->expects($this->at(1)) $context->expects($this->at(1))
->method('walkReference') ->method('validate')
->with($object, 'group2', 'data', true); ->with($object, 'data', 'group2', true);
$this->validator->initialize($context); $this->validator->initialize($context);
$this->validator->validate($form, new Form()); $this->validator->validate($form, new Form());
@ -327,8 +317,7 @@ class FormValidatorTest extends \PHPUnit_Framework_TestCase
public function testUseInheritedValidationGroup() public function testUseInheritedValidationGroup()
{ {
$context = $this->getExecutionContext('foo.bar'); $context = $this->getMockExecutionContext();
$graphWalker = $context->getGraphWalker();
$object = $this->getMock('\stdClass'); $object = $this->getMock('\stdClass');
$parentOptions = array( $parentOptions = array(
@ -344,9 +333,9 @@ class FormValidatorTest extends \PHPUnit_Framework_TestCase
$form->setData($object); $form->setData($object);
$graphWalker->expects($this->once()) $context->expects($this->once())
->method('walkReference') ->method('validate')
->with($object, 'group', 'foo.bar.data', true); ->with($object, 'data', 'group', true);
$this->validator->initialize($context); $this->validator->initialize($context);
$this->validator->validate($form, new Form()); $this->validator->validate($form, new Form());
@ -354,8 +343,7 @@ class FormValidatorTest extends \PHPUnit_Framework_TestCase
public function testUseInheritedCallbackValidationGroup() public function testUseInheritedCallbackValidationGroup()
{ {
$context = $this->getExecutionContext('foo.bar'); $context = $this->getMockExecutionContext();
$graphWalker = $context->getGraphWalker();
$object = $this->getMock('\stdClass'); $object = $this->getMock('\stdClass');
$parentOptions = array( $parentOptions = array(
@ -371,12 +359,12 @@ class FormValidatorTest extends \PHPUnit_Framework_TestCase
$form->setData($object); $form->setData($object);
$graphWalker->expects($this->at(0)) $context->expects($this->at(0))
->method('walkReference') ->method('validate')
->with($object, 'group1', 'foo.bar.data', true); ->with($object, 'data', 'group1', true);
$graphWalker->expects($this->at(1)) $context->expects($this->at(1))
->method('walkReference') ->method('validate')
->with($object, 'group2', 'foo.bar.data', true); ->with($object, 'data', 'group2', true);
$this->validator->initialize($context); $this->validator->initialize($context);
$this->validator->validate($form, new Form()); $this->validator->validate($form, new Form());
@ -384,8 +372,7 @@ class FormValidatorTest extends \PHPUnit_Framework_TestCase
public function testUseInheritedClosureValidationGroup() public function testUseInheritedClosureValidationGroup()
{ {
$context = $this->getExecutionContext('foo.bar'); $context = $this->getMockExecutionContext();
$graphWalker = $context->getGraphWalker();
$object = $this->getMock('\stdClass'); $object = $this->getMock('\stdClass');
$parentOptions = array( $parentOptions = array(
@ -403,12 +390,12 @@ class FormValidatorTest extends \PHPUnit_Framework_TestCase
$form->setData($object); $form->setData($object);
$graphWalker->expects($this->at(0)) $context->expects($this->at(0))
->method('walkReference') ->method('validate')
->with($object, 'group1', 'foo.bar.data', true); ->with($object, 'data', 'group1', true);
$graphWalker->expects($this->at(1)) $context->expects($this->at(1))
->method('walkReference') ->method('validate')
->with($object, 'group2', 'foo.bar.data', true); ->with($object, 'data', 'group2', true);
$this->validator->initialize($context); $this->validator->initialize($context);
$this->validator->validate($form, new Form()); $this->validator->validate($form, new Form());
@ -416,16 +403,15 @@ class FormValidatorTest extends \PHPUnit_Framework_TestCase
public function testAppendPropertyPath() public function testAppendPropertyPath()
{ {
$context = $this->getExecutionContext('foo.bar'); $context = $this->getMockExecutionContext();
$graphWalker = $context->getGraphWalker();
$object = $this->getMock('\stdClass'); $object = $this->getMock('\stdClass');
$form = $this->getBuilder('name', '\stdClass') $form = $this->getBuilder('name', '\stdClass')
->setData($object) ->setData($object)
->getForm(); ->getForm();
$graphWalker->expects($this->once()) $context->expects($this->once())
->method('walkReference') ->method('validate')
->with($object, 'Default', 'foo.bar.data', true); ->with($object, 'data', 'Default', true);
$this->validator->initialize($context); $this->validator->initialize($context);
$this->validator->validate($form, new Form()); $this->validator->validate($form, new Form());
@ -433,15 +419,14 @@ class FormValidatorTest extends \PHPUnit_Framework_TestCase
public function testDontWalkScalars() public function testDontWalkScalars()
{ {
$context = $this->getExecutionContext(); $context = $this->getMockExecutionContext();
$graphWalker = $context->getGraphWalker();
$form = $this->getBuilder() $form = $this->getBuilder()
->setData('scalar') ->setData('scalar')
->getForm(); ->getForm();
$graphWalker->expects($this->never()) $context->expects($this->never())
->method('walkReference'); ->method('validate');
$this->validator->initialize($context); $this->validator->initialize($context);
$this->validator->validate($form, new Form()); $this->validator->validate($form, new Form());
@ -449,7 +434,7 @@ class FormValidatorTest extends \PHPUnit_Framework_TestCase
public function testViolationIfExtraData() public function testViolationIfExtraData()
{ {
$context = $this->getExecutionContext(); $context = $this->getMockExecutionContext();
$form = $this->getBuilder('parent', null, array('extra_fields_message' => 'Extra!')) $form = $this->getBuilder('parent', null, array('extra_fields_message' => 'Extra!'))
->setCompound(true) ->setCompound(true)
@ -459,17 +444,24 @@ class FormValidatorTest extends \PHPUnit_Framework_TestCase
$form->bind(array('foo' => 'bar')); $form->bind(array('foo' => 'bar'));
$context->expects($this->once())
->method('addViolation')
->with(
'Extra!',
array('{{ extra_fields }}' => 'foo'),
array('foo' => 'bar')
);
$context->expects($this->never())
->method('addViolationAt');
$this->validator->initialize($context); $this->validator->initialize($context);
$this->validator->validate($form, new Form()); $this->validator->validate($form, new Form());
$this->assertCount(1, $context->getViolations());
$this->assertEquals('Extra!', $context->getViolations()->get(0)->getMessage());
} }
/** /**
* @dataProvider getPostMaxSizeFixtures * @dataProvider getPostMaxSizeFixtures
*/ */
public function testPostMaxSizeViolation($contentLength, $iniMax, $nbViolation, $msg) public function testPostMaxSizeViolation($contentLength, $iniMax, $nbViolation, array $params = array())
{ {
$this->serverParams->expects($this->once()) $this->serverParams->expects($this->once())
->method('getContentLength') ->method('getContentLength')
@ -478,30 +470,39 @@ class FormValidatorTest extends \PHPUnit_Framework_TestCase
->method('getNormalizedIniPostMaxSize') ->method('getNormalizedIniPostMaxSize')
->will($this->returnValue($iniMax)); ->will($this->returnValue($iniMax));
$context = $this->getExecutionContext(); $context = $this->getMockExecutionContext();
$options = array('post_max_size_message' => 'Max {{ max }}!'); $options = array('post_max_size_message' => 'Max {{ max }}!');
$form = $this->getBuilder('name', null, $options)->getForm(); $form = $this->getBuilder('name', null, $options)->getForm();
for ($i = 0; $i < $nbViolation; ++$i) {
if (0 === $i && count($params) > 0) {
$context->expects($this->at($i))
->method('addViolation')
->with($options['post_max_size_message'], $params);
} else {
$context->expects($this->at($i))
->method('addViolation');
}
}
$context->expects($this->never())
->method('addViolationAt');
$this->validator->initialize($context); $this->validator->initialize($context);
$this->validator->validate($form, new Form()); $this->validator->validate($form, new Form());
$this->assertCount($nbViolation, $context->getViolations());
if (null !== $msg) {
$this->assertEquals($msg, $context->getViolations()->get(0)->getMessage());
}
} }
public function getPostMaxSizeFixtures() public function getPostMaxSizeFixtures()
{ {
return array( return array(
array(pow(1024, 3) + 1, '1G', 1, 'Max 1G!'), array(pow(1024, 3) + 1, '1G', 1, array('{{ max }}' => '1G')),
array(pow(1024, 3), '1G', 0, null), array(pow(1024, 3), '1G', 0),
array(pow(1024, 2) + 1, '1M', 1, 'Max 1M!'), array(pow(1024, 2) + 1, '1M', 1, array('{{ max }}' => '1M')),
array(pow(1024, 2), '1M', 0, null), array(pow(1024, 2), '1M', 0),
array(1024 + 1, '1K', 1, 'Max 1K!'), array(1024 + 1, '1K', 1, array('{{ max }}' => '1K')),
array(1024, '1K', 0, null), array(1024, '1K', 0),
array(null, '1K', 0, null), array(null, '1K', 0),
array(1024, '', 0, null), array(1024, '', 0),
); );
} }
@ -513,7 +514,7 @@ class FormValidatorTest extends \PHPUnit_Framework_TestCase
$this->serverParams->expects($this->never()) $this->serverParams->expects($this->never())
->method('getNormalizedIniPostMaxSize'); ->method('getNormalizedIniPostMaxSize');
$context = $this->getExecutionContext(); $context = $this->getMockExecutionContext();
$parent = $this->getBuilder() $parent = $this->getBuilder()
->setCompound(true) ->setCompound(true)
->setDataMapper($this->getDataMapper()) ->setDataMapper($this->getDataMapper())
@ -521,10 +522,13 @@ class FormValidatorTest extends \PHPUnit_Framework_TestCase
$form = $this->getForm(); $form = $this->getForm();
$parent->add($form); $parent->add($form);
$context->expects($this->never())
->method('addViolation');
$context->expects($this->never())
->method('addViolationAt');
$this->validator->initialize($context); $this->validator->initialize($context);
$this->validator->validate($form, new Form()); $this->validator->validate($form, new Form());
$this->assertCount(0, $context->getViolations());
} }
/** /**
@ -537,25 +541,9 @@ class FormValidatorTest extends \PHPUnit_Framework_TestCase
return array('group1', 'group2'); return array('group1', 'group2');
} }
private function getMockGraphWalker() private function getMockExecutionContext()
{ {
return $this->getMockBuilder('Symfony\Component\Validator\GraphWalker') return $this->getMock('Symfony\Component\Validator\ExecutionContextInterface');
->disableOriginalConstructor()
->getMock();
}
private function getMockMetadataFactory()
{
return $this->getMock('Symfony\Component\Validator\Mapping\ClassMetadataFactoryInterface');
}
private function getExecutionContext($propertyPath = null)
{
$graphWalker = $this->getMockGraphWalker();
$metadataFactory = $this->getMockMetadataFactory();
$globalContext = new GlobalExecutionContext('Root', $graphWalker, $metadataFactory);
return new ExecutionContext($globalContext, null, $propertyPath, null, null, null);
} }
/** /**