Вход Регистрация
Файл: symfony-2.7/src/Symfony/Component/Form/Tests/Extension/Validator/Constraints/FormValidatorTest.php
Строк: 685
<?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 SymfonyComponentFormTestsExtensionValidatorConstraints;

use 
SymfonyComponentFormFormBuilder;
use 
SymfonyComponentFormExceptionTransformationFailedException;
use 
SymfonyComponentFormCallbackTransformer;
use 
SymfonyComponentFormFormInterface;
use 
SymfonyComponentFormExtensionValidatorConstraintsForm;
use 
SymfonyComponentFormExtensionValidatorConstraintsFormValidator;
use 
SymfonyComponentFormSubmitButtonBuilder;
use 
SymfonyComponentValidatorContextExecutionContextInterface;
use 
SymfonyComponentValidatorConstraintsNotNull;
use 
SymfonyComponentValidatorConstraintsNotBlank;
use 
SymfonyComponentValidatorTestsConstraintsAbstractConstraintValidatorTest;
use 
SymfonyComponentValidatorValidation;

/**
 * @author Bernhard Schussek <bschussek@gmail.com>
 */
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->getMock('SymfonyComponentEventDispatcherEventDispatcherInterface');
        
$this->factory $this->getMock('SymfonyComponentFormFormFactoryInterface');
        
$this->serverParams $this->getMock(
            
'SymfonyComponentFormExtensionValidatorUtilServerParams',
            array(
'getNormalizedIniPostMaxSize''getContentLength')
        );

        
parent::setUp();
    }

    protected function 
getApiVersion()
    {
        return 
Validation::API_VERSION_2_5;
    }

    protected function 
createValidator()
    {
        return new 
FormValidator($this->serverParams);
    }

    public function 
testValidate()
    {
        
$object $this->getMock('stdClass');
        
$options = array('validation_groups' => array('group1''group2'));
        
$form $this->getBuilder('name''stdClass'$options)
            ->
setData($object)
            ->
getForm();

        
$this->expectValidateAt(0'data'$object'group1');
        
$this->expectValidateAt(1'data'$object'group2');

        
$this->validator->validate($form, new Form());

        
$this->assertNoViolation();
    }

    public function 
testValidateConstraints()
    {
        
$object $this->getMock('stdClass');
        
$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'group1');
        
$this->expectValidateAt(1'data'$object'group2');

        
// Then custom constraints
        
$this->expectValidateValueAt(2'data'$object$constraint1'group1');
        
$this->expectValidateValueAt(3'data'$object$constraint2'group2');

        
$this->validator->validate($form, new Form());

        
$this->assertNoViolation();
    }

    public function 
testDontValidateIfParentWithoutCascadeValidation()
    {
        
$object $this->getMock('stdClass');

        
$parent $this->getBuilder('parent'null, array('cascade_validation' => false))
            ->
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 
testValidateConstraintsEvenIfNoCascadeValidation()
    {
        
$object $this->getMock('stdClass');
        
$constraint1 = new NotNull(array('groups' => array('group1''group2')));
        
$constraint2 = new NotBlank(array('groups' => 'group2'));

        
$parent $this->getBuilder('parent'null, array('cascade_validation' => false))
            ->
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->getMock('stdClass');

        
$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->getMock('stdClass');
        
$constraint1 $this->getMock('SymfonyComponentValidatorConstraint');
        
$constraint2 $this->getMock('SymfonyComponentValidatorConstraint');

        
$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->getMock('stdClass');

        
$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->getMock('stdClass');

        
$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->getMock('stdClass');
        
$constraint1 $this->getMock('SymfonyComponentValidatorConstraint');
        
$constraint2 $this->getMock('SymfonyComponentValidatorConstraint');

        
$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->getMock('stdClass');

        
$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 
testHandleCallbackValidationGroups()
    {
        
$object $this->getMock('stdClass');
        
$options = array('validation_groups' => array($this'getValidationGroups'));
        
$form $this->getBuilder('name''stdClass'$options)
            ->
setData($object)
            ->
getForm();

        
$this->expectValidateAt(0'data'$object'group1');
        
$this->expectValidateAt(1'data'$object'group2');

        
$this->validator->validate($form, new Form());

        
$this->assertNoViolation();
    }

    public function 
testDontExecuteFunctionNames()
    {
        
$object $this->getMock('stdClass');
        
$options = array('validation_groups' => 'header');
        
$form $this->getBuilder('name''stdClass'$options)
            ->
setData($object)
            ->
getForm();

        
$this->expectValidateAt(0'data'$object'header');

        
$this->validator->validate($form, new Form());

        
$this->assertNoViolation();
    }

    public function 
testHandleClosureValidationGroups()
    {
        
$object $this->getMock('stdClass');
        
$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'group1');
        
$this->expectValidateAt(1'data'$object'group2');

        
$this->validator->validate($form, new Form());

        
$this->assertNoViolation();
    }

    public function 
testUseValidationGroupOfClickedButton()
    {
        
$object $this->getMock('stdClass');

        
$parent $this->getBuilder('parent'null, array('cascade_validation' => true))
            ->
setCompound(true)
            ->
setDataMapper($this->getDataMapper())
            ->
getForm();
        
$form $this->getForm('name''stdClass', array(
            
'validation_groups' => 'form_group',
        ));

        
$parent->add($form);
        
$parent->add($this->getSubmitButton('submit', array(
            
'validation_groups' => 'button_group',
        )));

        
$parent->submit(array('name' => $object'submit' => ''));

        
$this->expectValidateAt(0'data'$object'button_group');

        
$this->validator->validate($form, new Form());

        
$this->assertNoViolation();
    }

    public function 
testDontUseValidationGroupOfUnclickedButton()
    {
        
$object $this->getMock('stdClass');

        
$parent $this->getBuilder('parent'null, array('cascade_validation' => true))
            ->
setCompound(true)
            ->
setDataMapper($this->getDataMapper())
            ->
getForm();
        
$form $this->getForm('name''stdClass', array(
            
'validation_groups' => 'form_group',
        ));

        
$parent->add($form);
        
$parent->add($this->getSubmitButton('submit', array(
            
'validation_groups' => 'button_group',
        )));

        
$form->setData($object);

        
$this->expectValidateAt(0'data'$object'form_group');

        
$this->validator->validate($form, new Form());

        
$this->assertNoViolation();
    }

    public function 
testUseInheritedValidationGroup()
    {
        
$object $this->getMock('stdClass');

        
$parentOptions = array(
            
'validation_groups' => 'group',
            
'cascade_validation' => true,
        );
        
$parent $this->getBuilder('parent'null$parentOptions)
            ->
setCompound(true)
            ->
setDataMapper($this->getDataMapper())
            ->
getForm();
        
$form $this->getBuilder('name''stdClass')->getForm();
        
$parent->add($form);

        
$form->setData($object);

        
$this->expectValidateAt(0'data'$object'group');

        
$this->validator->validate($form, new Form());

        
$this->assertNoViolation();
    }

    public function 
testUseInheritedCallbackValidationGroup()
    {
        
$object $this->getMock('stdClass');

        
$parentOptions = array(
            
'validation_groups' => array($this'getValidationGroups'),
            
'cascade_validation' => true,
        );
        
$parent $this->getBuilder('parent'null$parentOptions)
            ->
setCompound(true)
            ->
setDataMapper($this->getDataMapper())
            ->
getForm();
        
$form $this->getBuilder('name''stdClass')->getForm();
        
$parent->add($form);

        
$form->setData($object);

        
$this->expectValidateAt(0'data'$object'group1');
        
$this->expectValidateAt(1'data'$object'group2');

        
$this->validator->validate($form, new Form());

        
$this->assertNoViolation();
    }

    public function 
testUseInheritedClosureValidationGroup()
    {
        
$object $this->getMock('stdClass');

        
$parentOptions = array(
            
'validation_groups' => function (FormInterface $form) {
                return array(
'group1''group2');
            },
            
'cascade_validation' => true,
        );
        
$parent $this->getBuilder('parent'null$parentOptions)
            ->
setCompound(true)
            ->
setDataMapper($this->getDataMapper())
            ->
getForm();
        
$form $this->getBuilder('name''stdClass')->getForm();
        
$parent->add($form);

        
$form->setData($object);

        
$this->expectValidateAt(0'data'$object'group1');
        
$this->expectValidateAt(1'data'$object'group2');

        
$this->validator->validate($form, new Form());

        
$this->assertNoViolation();
    }

    public function 
testAppendPropertyPath()
    {
        
$object $this->getMock('stdClass');
        
$form $this->getBuilder('name''stdClass')
            ->
setData($object)
            ->
getForm();

        
$this->expectValidateAt(0'data'$object'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');
        
$context->expects($this->never())
            ->
method('addViolationAt');

        
$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->getMock('SymfonyComponentValidatorContextExecutionContextInterface');
        
$validator $this->getMock('SymfonyComponentValidatorValidatorValidatorInterface');
        
$contextualValidator $this->getMock('SymfonyComponentValidatorValidatorContextualValidatorInterface');

        
$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->getMock('SymfonyComponentFormDataMapperInterface');
    }
}
Онлайн: 0
Реклама