Actualización

This commit is contained in:
Xes
2025-04-10 12:24:57 +02:00
parent 8969cc929d
commit 45420b6f0d
39760 changed files with 4303286 additions and 0 deletions

View File

@@ -0,0 +1,54 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Form\Tests\Extension\Validator\Constraints;
use Symfony\Component\Form\Extension\Validator\ValidatorExtension;
use Symfony\Component\Form\Test\FormPerformanceTestCase;
use Symfony\Component\Validator\Validation;
/**
* @author Bernhard Schussek <bschussek@gmail.com>
*/
class FormValidatorPerformanceTest extends FormPerformanceTestCase
{
protected function getExtensions()
{
return array(
new ValidatorExtension(Validation::createValidator()),
);
}
/**
* findClickedButton() used to have an exponential number of calls.
*
* @group benchmark
*/
public function testValidationPerformance()
{
$this->setMaxRunningTime(1);
$builder = $this->factory->createBuilder('Symfony\Component\Form\Extension\Core\Type\FormType');
for ($i = 0; $i < 40; ++$i) {
$builder->add($i, 'Symfony\Component\Form\Extension\Core\Type\FormType');
$builder->get($i)
->add('a')
->add('b')
->add('c');
}
$form = $builder->getForm();
$form->submit(null);
}
}

View File

@@ -0,0 +1,684 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Form\Tests\Extension\Validator\Constraints;
use Symfony\Component\Form\FormBuilder;
use Symfony\Component\Form\Exception\TransformationFailedException;
use Symfony\Component\Form\CallbackTransformer;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\Form\Extension\Validator\Constraints\Form;
use Symfony\Component\Form\Extension\Validator\Constraints\FormValidator;
use Symfony\Component\Form\SubmitButtonBuilder;
use Symfony\Component\Validator\Constraints\GroupSequence;
use Symfony\Component\Validator\Constraints\NotNull;
use Symfony\Component\Validator\Constraints\NotBlank;
use Symfony\Component\Validator\Constraints\Valid;
use Symfony\Component\Validator\Tests\Constraints\AbstractConstraintValidatorTest;
/**
* @author Bernhard Schussek <bschussek@gmail.com>
*
* @todo use ConstraintValidatorTestCase when symfony/validator ~3.2 is required.
*/
class FormValidatorTest extends AbstractConstraintValidatorTest
{
/**
* @var \PHPUnit_Framework_MockObject_MockObject
*/
private $dispatcher;
/**
* @var \PHPUnit_Framework_MockObject_MockObject
*/
private $factory;
/**
* @var \PHPUnit_Framework_MockObject_MockObject
*/
protected $serverParams;
protected function setUp()
{
$this->dispatcher = $this->getMockBuilder('Symfony\Component\EventDispatcher\EventDispatcherInterface')->getMock();
$this->factory = $this->getMockBuilder('Symfony\Component\Form\FormFactoryInterface')->getMock();
$this->serverParams = $this->getMockBuilder('Symfony\Component\Form\Extension\Validator\Util\ServerParams')->setMethods(array('getNormalizedIniPostMaxSize', 'getContentLength'))->getMock();
parent::setUp();
}
protected function createValidator()
{
return new FormValidator($this->serverParams);
}
public function testValidate()
{
$object = $this->getMockBuilder('\stdClass')->getMock();
$options = array('validation_groups' => array('group1', 'group2'));
$form = $this->getBuilder('name', '\stdClass', $options)
->setData($object)
->getForm();
$this->expectValidateAt(0, 'data', $object, array('group1', 'group2'));
$this->validator->validate($form, new Form());
$this->assertNoViolation();
}
public function testValidateConstraints()
{
$object = $this->getMockBuilder('\stdClass')->getMock();
$constraint1 = new NotNull(array('groups' => array('group1', 'group2')));
$constraint2 = new NotBlank(array('groups' => 'group2'));
$options = array(
'validation_groups' => array('group1', 'group2'),
'constraints' => array($constraint1, $constraint2),
);
$form = $this->getBuilder('name', '\stdClass', $options)
->setData($object)
->getForm();
// First default constraints
$this->expectValidateAt(0, 'data', $object, array('group1', 'group2'));
// Then custom constraints
$this->expectValidateValueAt(1, 'data', $object, $constraint1, 'group1');
$this->expectValidateValueAt(2, 'data', $object, $constraint2, 'group2');
$this->validator->validate($form, new Form());
$this->assertNoViolation();
}
public function testValidateChildIfValidConstraint()
{
$object = $this->getMockBuilder('\stdClass')->getMock();
$parent = $this->getBuilder('parent')
->setCompound(true)
->setDataMapper($this->getDataMapper())
->getForm();
$options = array(
'validation_groups' => array('group1', 'group2'),
'constraints' => array(new Valid()),
);
$form = $this->getBuilder('name', '\stdClass', $options)->getForm();
$parent->add($form);
$form->setData($object);
$this->expectValidateAt(0, 'data', $object, array('group1', 'group2'));
$this->validator->validate($form, new Form());
$this->assertNoViolation();
}
public function testDontValidateIfParentWithoutValidConstraint()
{
$object = $this->getMockBuilder('\stdClass')->getMock();
$parent = $this->getBuilder('parent', null)
->setCompound(true)
->setDataMapper($this->getDataMapper())
->getForm();
$options = array('validation_groups' => array('group1', 'group2'));
$form = $this->getBuilder('name', '\stdClass', $options)->getForm();
$parent->add($form);
$form->setData($object);
$this->expectNoValidate();
$this->validator->validate($form, new Form());
$this->assertNoViolation();
}
public function testMissingConstraintIndex()
{
$object = new \stdClass();
$form = new FormBuilder('name', '\stdClass', $this->dispatcher, $this->factory);
$form = $form->setData($object)->getForm();
$this->expectValidateAt(0, 'data', $object, array('Default'));
$this->validator->validate($form, new Form());
$this->assertNoViolation();
}
public function testValidateConstraintsOptionEvenIfNoValidConstraint()
{
$object = $this->getMockBuilder('\stdClass')->getMock();
$constraint1 = new NotNull(array('groups' => array('group1', 'group2')));
$constraint2 = new NotBlank(array('groups' => 'group2'));
$parent = $this->getBuilder('parent', null)
->setCompound(true)
->setDataMapper($this->getDataMapper())
->getForm();
$options = array(
'validation_groups' => array('group1', 'group2'),
'constraints' => array($constraint1, $constraint2),
);
$form = $this->getBuilder('name', '\stdClass', $options)
->setData($object)
->getForm();
$parent->add($form);
$this->expectValidateValueAt(0, 'data', $object, $constraint1, 'group1');
$this->expectValidateValueAt(1, 'data', $object, $constraint2, 'group2');
$this->validator->validate($form, new Form());
$this->assertNoViolation();
}
public function testDontValidateIfNoValidationGroups()
{
$object = $this->getMockBuilder('\stdClass')->getMock();
$form = $this->getBuilder('name', '\stdClass', array(
'validation_groups' => array(),
))
->setData($object)
->getForm();
$form->setData($object);
$this->expectNoValidate();
$this->validator->validate($form, new Form());
$this->assertNoViolation();
}
public function testDontValidateConstraintsIfNoValidationGroups()
{
$object = $this->getMockBuilder('\stdClass')->getMock();
$constraint1 = $this->getMockBuilder('Symfony\Component\Validator\Constraint')->getMock();
$constraint2 = $this->getMockBuilder('Symfony\Component\Validator\Constraint')->getMock();
$options = array(
'validation_groups' => array(),
'constraints' => array($constraint1, $constraint2),
);
$form = $this->getBuilder('name', '\stdClass', $options)
->setData($object)
->getForm();
// Launch transformer
$form->submit(array());
$this->expectNoValidate();
$this->validator->validate($form, new Form());
$this->assertNoViolation();
}
public function testDontValidateIfNotSynchronized()
{
$object = $this->getMockBuilder('\stdClass')->getMock();
$form = $this->getBuilder('name', '\stdClass', array(
'invalid_message' => 'invalid_message_key',
// Invalid message parameters must be supported, because the
// invalid message can be a translation key
// see https://github.com/symfony/symfony/issues/5144
'invalid_message_parameters' => array('{{ foo }}' => 'bar'),
))
->setData($object)
->addViewTransformer(new CallbackTransformer(
function ($data) { return $data; },
function () { throw new TransformationFailedException(); }
))
->getForm();
// Launch transformer
$form->submit('foo');
$this->expectNoValidate();
$this->validator->validate($form, new Form());
$this->buildViolation('invalid_message_key')
->setParameter('{{ value }}', 'foo')
->setParameter('{{ foo }}', 'bar')
->setInvalidValue('foo')
->setCode(Form::NOT_SYNCHRONIZED_ERROR)
->setCause($form->getTransformationFailure())
->assertRaised();
}
public function testAddInvalidErrorEvenIfNoValidationGroups()
{
$object = $this->getMockBuilder('\stdClass')->getMock();
$form = $this->getBuilder('name', '\stdClass', array(
'invalid_message' => 'invalid_message_key',
// Invalid message parameters must be supported, because the
// invalid message can be a translation key
// see https://github.com/symfony/symfony/issues/5144
'invalid_message_parameters' => array('{{ foo }}' => 'bar'),
'validation_groups' => array(),
))
->setData($object)
->addViewTransformer(new CallbackTransformer(
function ($data) { return $data; },
function () { throw new TransformationFailedException(); }
))
->getForm();
// Launch transformer
$form->submit('foo');
$this->expectNoValidate();
$this->validator->validate($form, new Form());
$this->buildViolation('invalid_message_key')
->setParameter('{{ value }}', 'foo')
->setParameter('{{ foo }}', 'bar')
->setInvalidValue('foo')
->setCode(Form::NOT_SYNCHRONIZED_ERROR)
->setCause($form->getTransformationFailure())
->assertRaised();
}
public function testDontValidateConstraintsIfNotSynchronized()
{
$object = $this->getMockBuilder('\stdClass')->getMock();
$constraint1 = $this->getMockBuilder('Symfony\Component\Validator\Constraint')->getMock();
$constraint2 = $this->getMockBuilder('Symfony\Component\Validator\Constraint')->getMock();
$options = array(
'invalid_message' => 'invalid_message_key',
'validation_groups' => array('group1', 'group2'),
'constraints' => array($constraint1, $constraint2),
);
$form = $this->getBuilder('name', '\stdClass', $options)
->setData($object)
->addViewTransformer(new CallbackTransformer(
function ($data) { return $data; },
function () { throw new TransformationFailedException(); }
))
->getForm();
// Launch transformer
$form->submit('foo');
$this->expectNoValidate();
$this->validator->validate($form, new Form());
$this->buildViolation('invalid_message_key')
->setParameter('{{ value }}', 'foo')
->setInvalidValue('foo')
->setCode(Form::NOT_SYNCHRONIZED_ERROR)
->setCause($form->getTransformationFailure())
->assertRaised();
}
// https://github.com/symfony/symfony/issues/4359
public function testDontMarkInvalidIfAnyChildIsNotSynchronized()
{
$object = $this->getMockBuilder('\stdClass')->getMock();
$failingTransformer = new CallbackTransformer(
function ($data) { return $data; },
function () { throw new TransformationFailedException(); }
);
$form = $this->getBuilder('name', '\stdClass')
->setData($object)
->addViewTransformer($failingTransformer)
->setCompound(true)
->setDataMapper($this->getDataMapper())
->add(
$this->getBuilder('child')
->addViewTransformer($failingTransformer)
)
->getForm();
// Launch transformer
$form->submit(array('child' => 'foo'));
$this->expectNoValidate();
$this->validator->validate($form, new Form());
$this->assertNoViolation();
}
public function testHandleGroupSequenceValidationGroups()
{
$object = $this->getMockBuilder('\stdClass')->getMock();
$options = array('validation_groups' => new GroupSequence(array('group1', 'group2')));
$form = $this->getBuilder('name', '\stdClass', $options)
->setData($object)
->getForm();
$this->expectValidateAt(0, 'data', $object, new GroupSequence(array('group1', 'group2')));
$this->validator->validate($form, new Form());
$this->assertNoViolation();
}
public function testHandleCallbackValidationGroups()
{
$object = $this->getMockBuilder('\stdClass')->getMock();
$options = array('validation_groups' => array($this, 'getValidationGroups'));
$form = $this->getBuilder('name', '\stdClass', $options)
->setData($object)
->getForm();
$this->expectValidateAt(0, 'data', $object, array('group1', 'group2'));
$this->validator->validate($form, new Form());
$this->assertNoViolation();
}
public function testDontExecuteFunctionNames()
{
$object = $this->getMockBuilder('\stdClass')->getMock();
$options = array('validation_groups' => 'header');
$form = $this->getBuilder('name', '\stdClass', $options)
->setData($object)
->getForm();
$this->expectValidateAt(0, 'data', $object, array('header'));
$this->validator->validate($form, new Form());
$this->assertNoViolation();
}
public function testHandleClosureValidationGroups()
{
$object = $this->getMockBuilder('\stdClass')->getMock();
$options = array('validation_groups' => function (FormInterface $form) {
return array('group1', 'group2');
});
$form = $this->getBuilder('name', '\stdClass', $options)
->setData($object)
->getForm();
$this->expectValidateAt(0, 'data', $object, array('group1', 'group2'));
$this->validator->validate($form, new Form());
$this->assertNoViolation();
}
public function testUseValidationGroupOfClickedButton()
{
$object = $this->getMockBuilder('\stdClass')->getMock();
$parent = $this->getBuilder('parent')
->setCompound(true)
->setDataMapper($this->getDataMapper())
->getForm();
$form = $this->getForm('name', '\stdClass', array(
'validation_groups' => 'form_group',
'constraints' => array(new Valid()),
));
$parent->add($form);
$parent->add($this->getSubmitButton('submit', array(
'validation_groups' => 'button_group',
)));
$parent->submit(array('name' => $object, 'submit' => ''));
$this->expectValidateAt(0, 'data', $object, array('button_group'));
$this->validator->validate($form, new Form());
$this->assertNoViolation();
}
public function testDontUseValidationGroupOfUnclickedButton()
{
$object = $this->getMockBuilder('\stdClass')->getMock();
$parent = $this->getBuilder('parent')
->setCompound(true)
->setDataMapper($this->getDataMapper())
->getForm();
$form = $this->getForm('name', '\stdClass', array(
'validation_groups' => 'form_group',
'constraints' => array(new Valid()),
));
$parent->add($form);
$parent->add($this->getSubmitButton('submit', array(
'validation_groups' => 'button_group',
)));
$form->setData($object);
$this->expectValidateAt(0, 'data', $object, array('form_group'));
$this->validator->validate($form, new Form());
$this->assertNoViolation();
}
public function testUseInheritedValidationGroup()
{
$object = $this->getMockBuilder('\stdClass')->getMock();
$parentOptions = array('validation_groups' => 'group');
$parent = $this->getBuilder('parent', null, $parentOptions)
->setCompound(true)
->setDataMapper($this->getDataMapper())
->getForm();
$formOptions = array('constraints' => array(new Valid()));
$form = $this->getBuilder('name', '\stdClass', $formOptions)->getForm();
$parent->add($form);
$form->setData($object);
$this->expectValidateAt(0, 'data', $object, array('group'));
$this->validator->validate($form, new Form());
$this->assertNoViolation();
}
public function testUseInheritedCallbackValidationGroup()
{
$object = $this->getMockBuilder('\stdClass')->getMock();
$parentOptions = array('validation_groups' => array($this, 'getValidationGroups'));
$parent = $this->getBuilder('parent', null, $parentOptions)
->setCompound(true)
->setDataMapper($this->getDataMapper())
->getForm();
$formOptions = array('constraints' => array(new Valid()));
$form = $this->getBuilder('name', '\stdClass', $formOptions)->getForm();
$parent->add($form);
$form->setData($object);
$this->expectValidateAt(0, 'data', $object, array('group1', 'group2'));
$this->validator->validate($form, new Form());
$this->assertNoViolation();
}
public function testUseInheritedClosureValidationGroup()
{
$object = $this->getMockBuilder('\stdClass')->getMock();
$parentOptions = array(
'validation_groups' => function (FormInterface $form) {
return array('group1', 'group2');
},
);
$parent = $this->getBuilder('parent', null, $parentOptions)
->setCompound(true)
->setDataMapper($this->getDataMapper())
->getForm();
$formOptions = array('constraints' => array(new Valid()));
$form = $this->getBuilder('name', '\stdClass', $formOptions)->getForm();
$parent->add($form);
$form->setData($object);
$this->expectValidateAt(0, 'data', $object, array('group1', 'group2'));
$this->validator->validate($form, new Form());
$this->assertNoViolation();
}
public function testAppendPropertyPath()
{
$object = $this->getMockBuilder('\stdClass')->getMock();
$form = $this->getBuilder('name', '\stdClass')
->setData($object)
->getForm();
$this->expectValidateAt(0, 'data', $object, array('Default'));
$this->validator->validate($form, new Form());
$this->assertNoViolation();
}
public function testDontWalkScalars()
{
$form = $this->getBuilder()
->setData('scalar')
->getForm();
$this->expectNoValidate();
$this->validator->validate($form, new Form());
$this->assertNoViolation();
}
public function testViolationIfExtraData()
{
$form = $this->getBuilder('parent', null, array('extra_fields_message' => 'Extra!'))
->setCompound(true)
->setDataMapper($this->getDataMapper())
->add($this->getBuilder('child'))
->getForm();
$form->submit(array('foo' => 'bar'));
$this->expectNoValidate();
$this->validator->validate($form, new Form());
$this->buildViolation('Extra!')
->setParameter('{{ extra_fields }}', 'foo')
->setInvalidValue(array('foo' => 'bar'))
->setCode(Form::NO_SUCH_FIELD_ERROR)
->assertRaised();
}
public function testNoViolationIfAllowExtraData()
{
$context = $this->getMockExecutionContext();
$form = $this
->getBuilder('parent', null, array('allow_extra_fields' => true))
->setCompound(true)
->setDataMapper($this->getDataMapper())
->add($this->getBuilder('child'))
->getForm();
$form->submit(array('foo' => 'bar'));
$context->expects($this->never())
->method('addViolation');
$this->validator->initialize($context);
$this->validator->validate($form, new Form());
}
/**
* Access has to be public, as this method is called via callback array
* in {@link testValidateFormDataCanHandleCallbackValidationGroups()}
* and {@link testValidateFormDataUsesInheritedCallbackValidationGroup()}.
*/
public function getValidationGroups(FormInterface $form)
{
return array('group1', 'group2');
}
private function getMockExecutionContext()
{
$context = $this->getMockBuilder('Symfony\Component\Validator\Context\ExecutionContextInterface')->getMock();
$validator = $this->getMockBuilder('Symfony\Component\Validator\Validator\ValidatorInterface')->getMock();
$contextualValidator = $this->getMockBuilder('Symfony\Component\Validator\Validator\ContextualValidatorInterface')->getMock();
$validator->expects($this->any())
->method('inContext')
->with($context)
->will($this->returnValue($contextualValidator));
$context->expects($this->any())
->method('getValidator')
->will($this->returnValue($validator));
return $context;
}
/**
* @param string $name
* @param string $dataClass
* @param array $options
*
* @return FormBuilder
*/
private function getBuilder($name = 'name', $dataClass = null, array $options = array())
{
$options = array_replace(array(
'constraints' => array(),
'invalid_message_parameters' => array(),
), $options);
return new FormBuilder($name, $dataClass, $this->dispatcher, $this->factory, $options);
}
private function getForm($name = 'name', $dataClass = null, array $options = array())
{
return $this->getBuilder($name, $dataClass, $options)->getForm();
}
private function getSubmitButton($name = 'name', array $options = array())
{
$builder = new SubmitButtonBuilder($name, $options);
return $builder->getForm();
}
/**
* @return \PHPUnit_Framework_MockObject_MockObject
*/
private function getDataMapper()
{
return $this->getMockBuilder('Symfony\Component\Form\DataMapperInterface')->getMock();
}
}

View File

@@ -0,0 +1,170 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Form\Tests\Extension\Validator\EventListener;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Form\FormBuilder;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\Extension\Validator\Constraints\Form;
use Symfony\Component\Form\Extension\Validator\EventListener\ValidationListener;
use Symfony\Component\PropertyAccess\PropertyPath;
use Symfony\Component\Validator\ConstraintViolation;
use Symfony\Component\Validator\ConstraintViolationList;
class ValidationListenerTest extends TestCase
{
/**
* @var \PHPUnit_Framework_MockObject_MockObject
*/
private $dispatcher;
/**
* @var \PHPUnit_Framework_MockObject_MockObject
*/
private $factory;
/**
* @var \PHPUnit_Framework_MockObject_MockObject
*/
private $validator;
/**
* @var \PHPUnit_Framework_MockObject_MockObject
*/
private $violationMapper;
/**
* @var ValidationListener
*/
private $listener;
private $message;
private $messageTemplate;
private $params;
protected function setUp()
{
$this->dispatcher = $this->getMockBuilder('Symfony\Component\EventDispatcher\EventDispatcherInterface')->getMock();
$this->factory = $this->getMockBuilder('Symfony\Component\Form\FormFactoryInterface')->getMock();
$this->validator = $this->getMockBuilder('Symfony\Component\Validator\Validator\ValidatorInterface')->getMock();
$this->violationMapper = $this->getMockBuilder('Symfony\Component\Form\Extension\Validator\ViolationMapper\ViolationMapperInterface')->getMock();
$this->listener = new ValidationListener($this->validator, $this->violationMapper);
$this->message = 'Message';
$this->messageTemplate = 'Message template';
$this->params = array('foo' => 'bar');
}
private function getConstraintViolation($code = null)
{
return new ConstraintViolation($this->message, $this->messageTemplate, $this->params, null, 'prop.path', null, null, $code, new Form());
}
private function getBuilder($name = 'name', $propertyPath = null, $dataClass = null)
{
$builder = new FormBuilder($name, $dataClass, $this->dispatcher, $this->factory);
$builder->setPropertyPath(new PropertyPath($propertyPath ?: $name));
$builder->setAttribute('error_mapping', array());
$builder->setErrorBubbling(false);
$builder->setMapped(true);
return $builder;
}
private function getForm($name = 'name', $propertyPath = null, $dataClass = null)
{
return $this->getBuilder($name, $propertyPath, $dataClass)->getForm();
}
private function getMockForm()
{
return $this->getMockBuilder('Symfony\Component\Form\Test\FormInterface')->getMock();
}
// More specific mapping tests can be found in ViolationMapperTest
public function testMapViolation()
{
$violation = $this->getConstraintViolation();
$form = $this->getForm('street');
$this->validator->expects($this->once())
->method('validate')
->will($this->returnValue(array($violation)));
$this->violationMapper->expects($this->once())
->method('mapViolation')
->with($violation, $form, false);
$this->listener->validateForm(new FormEvent($form, null));
}
public function testMapViolationAllowsNonSyncIfInvalid()
{
$violation = $this->getConstraintViolation(Form::NOT_SYNCHRONIZED_ERROR);
$form = $this->getForm('street');
$this->validator->expects($this->once())
->method('validate')
->will($this->returnValue(array($violation)));
$this->violationMapper->expects($this->once())
->method('mapViolation')
// pass true now
->with($violation, $form, true);
$this->listener->validateForm(new FormEvent($form, null));
}
public function testValidateIgnoresNonRoot()
{
$form = $this->getMockForm();
$form->expects($this->once())
->method('isRoot')
->will($this->returnValue(false));
$this->validator->expects($this->never())
->method('validate');
$this->violationMapper->expects($this->never())
->method('mapViolation');
$this->listener->validateForm(new FormEvent($form, null));
}
public function testValidateWithEmptyViolationList()
{
$form = $this->getMockForm();
$form->expects($this->once())
->method('isRoot')
->will($this->returnValue(true));
$this->validator
->expects($this->once())
->method('validate')
->will($this->returnValue(new ConstraintViolationList()));
$this->violationMapper
->expects($this->never())
->method('mapViolation');
$this->listener->validateForm(new FormEvent($form, null));
}
public function testValidatorInterface()
{
$validator = $this->getMockBuilder('Symfony\Component\Validator\Validator\ValidatorInterface')->getMock();
$listener = new ValidationListener($validator, $this->violationMapper);
$this->assertAttributeSame($validator, 'validator', $listener);
}
}

View File

@@ -0,0 +1,84 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Form\Tests\Extension\Validator\Type;
use Symfony\Component\Form\Test\FormInterface;
use Symfony\Component\Validator\Constraints\GroupSequence;
/**
* @author Bernhard Schussek <bschussek@gmail.com>
*/
abstract class BaseValidatorExtensionTest extends TypeTestCase
{
public function testValidationGroupNullByDefault()
{
$form = $this->createForm();
$this->assertNull($form->getConfig()->getOption('validation_groups'));
}
public function testValidationGroupsTransformedToArray()
{
$form = $this->createForm(array(
'validation_groups' => 'group',
));
$this->assertEquals(array('group'), $form->getConfig()->getOption('validation_groups'));
}
public function testValidationGroupsCanBeSetToArray()
{
$form = $this->createForm(array(
'validation_groups' => array('group1', 'group2'),
));
$this->assertEquals(array('group1', 'group2'), $form->getConfig()->getOption('validation_groups'));
}
public function testValidationGroupsCanBeSetToFalse()
{
$form = $this->createForm(array(
'validation_groups' => false,
));
$this->assertEquals(array(), $form->getConfig()->getOption('validation_groups'));
}
public function testValidationGroupsCanBeSetToCallback()
{
$form = $this->createForm(array(
'validation_groups' => array($this, 'testValidationGroupsCanBeSetToCallback'),
));
$this->assertInternalType('callable', $form->getConfig()->getOption('validation_groups'));
}
public function testValidationGroupsCanBeSetToClosure()
{
$form = $this->createForm(array(
'validation_groups' => function (FormInterface $form) { },
));
$this->assertInternalType('callable', $form->getConfig()->getOption('validation_groups'));
}
public function testValidationGroupsCanBeSetToGroupSequence()
{
$form = $this->createForm(array(
'validation_groups' => new GroupSequence(array('group1', 'group2')),
));
$this->assertInstanceOf('Symfony\Component\Validator\Constraints\GroupSequence', $form->getConfig()->getOption('validation_groups'));
}
abstract protected function createForm(array $options = array());
}

View File

@@ -0,0 +1,60 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Form\Tests\Extension\Validator\Type;
use Symfony\Component\Form\Extension\Validator\Type\FormTypeValidatorExtension;
use Symfony\Component\Validator\Constraints\Valid;
use Symfony\Component\Validator\ConstraintViolationList;
class FormTypeValidatorExtensionTest extends BaseValidatorExtensionTest
{
public function testSubmitValidatesData()
{
$builder = $this->factory->createBuilder(
'Symfony\Component\Form\Extension\Core\Type\FormType',
null,
array(
'validation_groups' => 'group',
)
);
$builder->add('firstName', 'Symfony\Component\Form\Extension\Core\Type\FormType');
$form = $builder->getForm();
$this->validator->expects($this->once())
->method('validate')
->with($this->equalTo($form))
->will($this->returnValue(new ConstraintViolationList()));
// specific data is irrelevant
$form->submit(array());
}
public function testValidConstraint()
{
$form = $this->createForm(array('constraints' => $valid = new Valid()));
$this->assertSame(array($valid), $form->getConfig()->getOption('constraints'));
}
public function testValidatorInterface()
{
$validator = $this->getMockBuilder('Symfony\Component\Validator\Validator\ValidatorInterface')->getMock();
$formTypeValidatorExtension = new FormTypeValidatorExtension($validator);
$this->assertAttributeSame($validator, 'validator', $formTypeValidatorExtension);
}
protected function createForm(array $options = array())
{
return $this->factory->create('Symfony\Component\Form\Extension\Core\Type\FormType', null, $options);
}
}

View File

@@ -0,0 +1,20 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Form\Tests\Extension\Validator\Type;
class SubmitTypeValidatorExtensionTest extends BaseValidatorExtensionTest
{
protected function createForm(array $options = array())
{
return $this->factory->create('Symfony\Component\Form\Extension\Core\Type\SubmitType', null, $options);
}
}

View File

@@ -0,0 +1,44 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Form\Tests\Extension\Validator\Type;
use Symfony\Component\Form\Test\TypeTestCase as BaseTypeTestCase;
use Symfony\Component\Form\Extension\Validator\ValidatorExtension;
abstract class TypeTestCase extends BaseTypeTestCase
{
protected $validator;
protected function setUp()
{
$this->validator = $this->getMockBuilder('Symfony\Component\Validator\Validator\ValidatorInterface')->getMock();
$metadata = $this->getMockBuilder('Symfony\Component\Validator\Mapping\ClassMetadata')->disableOriginalConstructor()->getMock();
$this->validator->expects($this->once())->method('getMetadataFor')->will($this->returnValue($metadata));
$this->validator->expects($this->any())->method('validate')->will($this->returnValue(array()));
parent::setUp();
}
protected function tearDown()
{
$this->validator = null;
parent::tearDown();
}
protected function getExtensions()
{
return array_merge(parent::getExtensions(), array(
new ValidatorExtension($this->validator),
));
}
}

View File

@@ -0,0 +1,44 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Form\Tests\Extension\Validator\Type;
use Symfony\Component\Form\Extension\Validator\Type\UploadValidatorExtension;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\OptionsResolver\Options;
class UploadValidatorExtensionTest extends TypeTestCase
{
public function testPostMaxSizeTranslation()
{
$translator = $this->getMockBuilder('Symfony\Component\Translation\TranslatorInterface')->getMock();
$translator->expects($this->any())
->method('trans')
->with($this->equalTo('old max {{ max }}!'))
->willReturn('translated max {{ max }}!');
$extension = new UploadValidatorExtension($translator);
$resolver = new OptionsResolver();
$resolver->setDefault('post_max_size_message', 'old max {{ max }}!');
$resolver->setDefault('upload_max_size_message', function (Options $options, $message) {
return function () use ($options) {
return $options['post_max_size_message'];
};
});
$extension->configureOptions($resolver);
$options = $resolver->resolve();
$this->assertEquals('translated max {{ max }}!', call_user_func($options['upload_max_size_message']));
}
}

View File

@@ -0,0 +1,72 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Form\Tests\Extension\Validator\Util;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Form\Extension\Validator\Util\ServerParams;
use Symfony\Component\HttpFoundation\Request;
class ServerParamsTest extends TestCase
{
public function testGetContentLengthFromSuperglobals()
{
$serverParams = new ServerParams();
$this->assertNull($serverParams->getContentLength());
$_SERVER['CONTENT_LENGTH'] = 1024;
$this->assertEquals(1024, $serverParams->getContentLength());
unset($_SERVER['CONTENT_LENGTH']);
}
public function testGetContentLengthFromRequest()
{
$request = Request::create('http://foo', 'GET', array(), array(), array(), array('CONTENT_LENGTH' => 1024));
$requestStack = $this->getMockBuilder('Symfony\Component\HttpFoundation\RequestStack')->setMethods(array('getCurrentRequest'))->getMock();
$requestStack->expects($this->once())->method('getCurrentRequest')->will($this->returnValue($request));
$serverParams = new ServerParams($requestStack);
$this->assertEquals(1024, $serverParams->getContentLength());
}
/** @dataProvider getGetPostMaxSizeTestData */
public function testGetPostMaxSize($size, $bytes)
{
$serverParams = $this->getMockBuilder('Symfony\Component\Form\Extension\Validator\Util\ServerParams')->setMethods(array('getNormalizedIniPostMaxSize'))->getMock();
$serverParams
->expects($this->any())
->method('getNormalizedIniPostMaxSize')
->will($this->returnValue(strtoupper($size)));
$this->assertEquals($bytes, $serverParams->getPostMaxSize());
}
public function getGetPostMaxSizeTestData()
{
return array(
array('2k', 2048),
array('2 k', 2048),
array('8m', 8 * 1024 * 1024),
array('+2 k', 2048),
array('+2???k', 2048),
array('0x10', 16),
array('0xf', 15),
array('010', 8),
array('+0x10 k', 16 * 1024),
array('1g', 1024 * 1024 * 1024),
array('-1', -1),
array('0', 0),
array('2mk', 2048), // the unit must be the last char, so in this case 'k', not 'm'
);
}
}

View File

@@ -0,0 +1,47 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Form\Tests\Extension\Validator;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Form\Extension\Validator\ValidatorExtension;
class ValidatorExtensionTest extends TestCase
{
public function test2Dot5ValidationApi()
{
$validator = $this->getMockBuilder('Symfony\Component\Validator\Validator\RecursiveValidator')
->disableOriginalConstructor()
->getMock();
$metadata = $this->getMockBuilder('Symfony\Component\Validator\Mapping\ClassMetadata')
->disableOriginalConstructor()
->getMock();
$validator->expects($this->once())
->method('getMetadataFor')
->with($this->identicalTo('Symfony\Component\Form\Form'))
->will($this->returnValue($metadata));
// Verify that the constraints are added
$metadata->expects($this->once())
->method('addConstraint')
->with($this->isInstanceOf('Symfony\Component\Form\Extension\Validator\Constraints\Form'));
$metadata->expects($this->once())
->method('addPropertyConstraint')
->with('children', $this->isInstanceOf('Symfony\Component\Validator\Constraints\Valid'));
$extension = new ValidatorExtension($validator);
$guesser = $extension->loadTypeGuesser();
$this->assertInstanceOf('Symfony\Component\Form\Extension\Validator\ValidatorTypeGuesser', $guesser);
}
}

View File

@@ -0,0 +1,138 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Form\Tests\Extension\Validator;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Form\Extension\Validator\ValidatorTypeGuesser;
use Symfony\Component\Form\Guess\Guess;
use Symfony\Component\Form\Guess\ValueGuess;
use Symfony\Component\Validator\Constraints\Email;
use Symfony\Component\Validator\Constraints\Length;
use Symfony\Component\Validator\Constraints\NotBlank;
use Symfony\Component\Validator\Constraints\NotNull;
use Symfony\Component\Validator\Constraints\Range;
use Symfony\Component\Validator\Constraints\IsTrue;
use Symfony\Component\Validator\Constraints\Type;
use Symfony\Component\Validator\Mapping\ClassMetadata;
/**
* @author franek <franek@chicour.net>
* @author Bernhard Schussek <bschussek@gmail.com>
*/
class ValidatorTypeGuesserTest extends TestCase
{
const TEST_CLASS = 'Symfony\Component\Form\Tests\Extension\Validator\ValidatorTypeGuesserTest_TestClass';
const TEST_PROPERTY = 'property';
/**
* @var ValidatorTypeGuesser
*/
private $guesser;
/**
* @var ClassMetadata
*/
private $metadata;
/**
* @var \PHPUnit_Framework_MockObject_MockObject
*/
private $metadataFactory;
protected function setUp()
{
$this->metadata = new ClassMetadata(self::TEST_CLASS);
$this->metadataFactory = $this->getMockBuilder('Symfony\Component\Validator\Mapping\Factory\MetadataFactoryInterface')->getMock();
$this->metadataFactory->expects($this->any())
->method('getMetadataFor')
->with(self::TEST_CLASS)
->will($this->returnValue($this->metadata));
$this->guesser = new ValidatorTypeGuesser($this->metadataFactory);
}
public function guessRequiredProvider()
{
return array(
array(new NotNull(), new ValueGuess(true, Guess::HIGH_CONFIDENCE)),
array(new NotBlank(), new ValueGuess(true, Guess::HIGH_CONFIDENCE)),
array(new IsTrue(), new ValueGuess(true, Guess::HIGH_CONFIDENCE)),
array(new Length(10), new ValueGuess(false, Guess::LOW_CONFIDENCE)),
array(new Range(array('min' => 1, 'max' => 20)), new ValueGuess(false, Guess::LOW_CONFIDENCE)),
);
}
/**
* @dataProvider guessRequiredProvider
*/
public function testGuessRequired($constraint, $guess)
{
// add distracting constraint
$this->metadata->addPropertyConstraint(self::TEST_PROPERTY, new Email());
// add constraint under test
$this->metadata->addPropertyConstraint(self::TEST_PROPERTY, $constraint);
$this->assertEquals($guess, $this->guesser->guessRequired(self::TEST_CLASS, self::TEST_PROPERTY));
}
public function testGuessRequiredReturnsFalseForUnmappedProperties()
{
$this->assertEquals(new ValueGuess(false, Guess::LOW_CONFIDENCE), $this->guesser->guessRequired(self::TEST_CLASS, self::TEST_PROPERTY));
}
public function testGuessMaxLengthForConstraintWithMaxValue()
{
$constraint = new Length(array('max' => '2'));
$result = $this->guesser->guessMaxLengthForConstraint($constraint);
$this->assertInstanceOf('Symfony\Component\Form\Guess\ValueGuess', $result);
$this->assertEquals(2, $result->getValue());
$this->assertEquals(Guess::HIGH_CONFIDENCE, $result->getConfidence());
}
public function testGuessMaxLengthForConstraintWithMinValue()
{
$constraint = new Length(array('min' => '2'));
$result = $this->guesser->guessMaxLengthForConstraint($constraint);
$this->assertNull($result);
}
public function maxLengthTypeProvider()
{
return array(
array('double'),
array('float'),
array('numeric'),
array('real'),
);
}
/**
* @dataProvider maxLengthTypeProvider
*/
public function testGuessMaxLengthForConstraintWithType($type)
{
$constraint = new Type($type);
$result = $this->guesser->guessMaxLengthForConstraint($constraint);
$this->assertInstanceOf('Symfony\Component\Form\Guess\ValueGuess', $result);
$this->assertNull($result->getValue());
$this->assertEquals(Guess::MEDIUM_CONFIDENCE, $result->getConfidence());
}
}
class ValidatorTypeGuesserTest_TestClass
{
private $property;
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,247 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Form\Tests\Extension\Validator\ViolationMapper;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Form\Extension\Validator\ViolationMapper\ViolationPath;
/**
* @author Bernhard Schussek <bschussek@gmail.com>
*/
class ViolationPathTest extends TestCase
{
public function providePaths()
{
return array(
array('children[address]', array(
array('address', true, true),
)),
array('children[address].children[street]', array(
array('address', true, true),
array('street', true, true),
)),
array('children[address][street]', array(
array('address', true, true),
array('street', true, true),
), 'children[address].children[street]'),
array('children[address].data', array(
array('address', true, true),
), 'children[address]'),
array('children[address].data.street', array(
array('address', true, true),
array('street', false, false),
)),
array('children[address].data[street]', array(
array('address', true, true),
array('street', false, true),
)),
array('children[address].children[street].data.name', array(
array('address', true, true),
array('street', true, true),
array('name', false, false),
)),
array('children[address].children[street].data[name]', array(
array('address', true, true),
array('street', true, true),
array('name', false, true),
)),
array('data.address', array(
array('address', false, false),
)),
array('data[address]', array(
array('address', false, true),
)),
array('data.address.street', array(
array('address', false, false),
array('street', false, false),
)),
array('data[address].street', array(
array('address', false, true),
array('street', false, false),
)),
array('data.address[street]', array(
array('address', false, false),
array('street', false, true),
)),
array('data[address][street]', array(
array('address', false, true),
array('street', false, true),
)),
// A few invalid examples
array('data', array(), ''),
array('children', array(), ''),
array('children.address', array(), ''),
array('children.address[street]', array(), ''),
);
}
/**
* @dataProvider providePaths
*/
public function testCreatePath($string, $entries, $slicedPath = null)
{
if (null === $slicedPath) {
$slicedPath = $string;
}
$path = new ViolationPath($string);
$this->assertSame($slicedPath, $path->__toString());
$this->assertSame(count($entries), count($path->getElements()));
$this->assertSame(count($entries), $path->getLength());
foreach ($entries as $index => $entry) {
$this->assertEquals($entry[0], $path->getElement($index));
$this->assertSame($entry[1], $path->mapsForm($index));
$this->assertSame($entry[2], $path->isIndex($index));
$this->assertSame(!$entry[2], $path->isProperty($index));
}
}
public function provideParents()
{
return array(
array('children[address]', null),
array('children[address].children[street]', 'children[address]'),
array('children[address].data.street', 'children[address]'),
array('children[address].data[street]', 'children[address]'),
array('data.address', null),
array('data.address.street', 'data.address'),
array('data.address[street]', 'data.address'),
array('data[address].street', 'data[address]'),
array('data[address][street]', 'data[address]'),
);
}
/**
* @dataProvider provideParents
*/
public function testGetParent($violationPath, $parentPath)
{
$path = new ViolationPath($violationPath);
$parent = null === $parentPath ? null : new ViolationPath($parentPath);
$this->assertEquals($parent, $path->getParent());
}
public function testGetElement()
{
$path = new ViolationPath('children[address].data[street].name');
$this->assertEquals('street', $path->getElement(1));
}
/**
* @expectedException \OutOfBoundsException
*/
public function testGetElementDoesNotAcceptInvalidIndices()
{
$path = new ViolationPath('children[address].data[street].name');
$path->getElement(3);
}
/**
* @expectedException \OutOfBoundsException
*/
public function testGetElementDoesNotAcceptNegativeIndices()
{
$path = new ViolationPath('children[address].data[street].name');
$path->getElement(-1);
}
public function testIsProperty()
{
$path = new ViolationPath('children[address].data[street].name');
$this->assertFalse($path->isProperty(1));
$this->assertTrue($path->isProperty(2));
}
/**
* @expectedException \OutOfBoundsException
*/
public function testIsPropertyDoesNotAcceptInvalidIndices()
{
$path = new ViolationPath('children[address].data[street].name');
$path->isProperty(3);
}
/**
* @expectedException \OutOfBoundsException
*/
public function testIsPropertyDoesNotAcceptNegativeIndices()
{
$path = new ViolationPath('children[address].data[street].name');
$path->isProperty(-1);
}
public function testIsIndex()
{
$path = new ViolationPath('children[address].data[street].name');
$this->assertTrue($path->isIndex(1));
$this->assertFalse($path->isIndex(2));
}
/**
* @expectedException \OutOfBoundsException
*/
public function testIsIndexDoesNotAcceptInvalidIndices()
{
$path = new ViolationPath('children[address].data[street].name');
$path->isIndex(3);
}
/**
* @expectedException \OutOfBoundsException
*/
public function testIsIndexDoesNotAcceptNegativeIndices()
{
$path = new ViolationPath('children[address].data[street].name');
$path->isIndex(-1);
}
public function testMapsForm()
{
$path = new ViolationPath('children[address].data[street].name');
$this->assertTrue($path->mapsForm(0));
$this->assertFalse($path->mapsForm(1));
$this->assertFalse($path->mapsForm(2));
}
/**
* @expectedException \OutOfBoundsException
*/
public function testMapsFormDoesNotAcceptInvalidIndices()
{
$path = new ViolationPath('children[address].data[street].name');
$path->mapsForm(3);
}
/**
* @expectedException \OutOfBoundsException
*/
public function testMapsFormDoesNotAcceptNegativeIndices()
{
$path = new ViolationPath('children[address].data[street].name');
$path->mapsForm(-1);
}
}