336 lines
11 KiB
PHP
336 lines
11 KiB
PHP
|
<?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\Validator\Tests;
|
||
|
|
||
|
use PHPUnit\Framework\TestCase;
|
||
|
use Symfony\Component\Validator\Constraints\Collection;
|
||
|
use Symfony\Component\Validator\Constraints\All;
|
||
|
use Symfony\Component\Validator\ConstraintValidatorFactory;
|
||
|
use Symfony\Component\Validator\ConstraintViolation;
|
||
|
use Symfony\Component\Validator\ConstraintViolationList;
|
||
|
use Symfony\Component\Validator\ExecutionContext;
|
||
|
use Symfony\Component\Validator\Tests\Fixtures\ConstraintA;
|
||
|
use Symfony\Component\Validator\ValidationVisitor;
|
||
|
|
||
|
/**
|
||
|
* @group legacy
|
||
|
*/
|
||
|
class LegacyExecutionContextTest extends TestCase
|
||
|
{
|
||
|
const TRANS_DOMAIN = 'trans_domain';
|
||
|
|
||
|
private $visitor;
|
||
|
private $violations;
|
||
|
private $metadata;
|
||
|
private $metadataFactory;
|
||
|
private $globalContext;
|
||
|
private $translator;
|
||
|
|
||
|
/**
|
||
|
* @var ExecutionContext
|
||
|
*/
|
||
|
private $context;
|
||
|
|
||
|
protected function setUp()
|
||
|
{
|
||
|
$this->visitor = $this->getMockBuilder('Symfony\Component\Validator\ValidationVisitor')
|
||
|
->disableOriginalConstructor()
|
||
|
->getMock();
|
||
|
$this->violations = new ConstraintViolationList();
|
||
|
$this->metadata = $this->getMockBuilder('Symfony\Component\Validator\MetadataInterface')->getMock();
|
||
|
$this->metadataFactory = $this->getMockBuilder('Symfony\Component\Validator\MetadataFactoryInterface')->getMock();
|
||
|
$this->globalContext = $this->getMockBuilder('Symfony\Component\Validator\GlobalExecutionContextInterface')->getMock();
|
||
|
$this->globalContext->expects($this->any())
|
||
|
->method('getRoot')
|
||
|
->will($this->returnValue('Root'));
|
||
|
$this->globalContext->expects($this->any())
|
||
|
->method('getViolations')
|
||
|
->will($this->returnValue($this->violations));
|
||
|
$this->globalContext->expects($this->any())
|
||
|
->method('getVisitor')
|
||
|
->will($this->returnValue($this->visitor));
|
||
|
$this->globalContext->expects($this->any())
|
||
|
->method('getMetadataFactory')
|
||
|
->will($this->returnValue($this->metadataFactory));
|
||
|
$this->translator = $this->getMockBuilder('Symfony\Component\Translation\TranslatorInterface')->getMock();
|
||
|
$this->context = new ExecutionContext($this->globalContext, $this->translator, self::TRANS_DOMAIN, $this->metadata, 'currentValue', 'Group', 'foo.bar');
|
||
|
}
|
||
|
|
||
|
protected function tearDown()
|
||
|
{
|
||
|
$this->globalContext = null;
|
||
|
$this->context = null;
|
||
|
}
|
||
|
|
||
|
public function testInit()
|
||
|
{
|
||
|
$this->assertCount(0, $this->context->getViolations());
|
||
|
$this->assertSame('Root', $this->context->getRoot());
|
||
|
$this->assertSame('foo.bar', $this->context->getPropertyPath());
|
||
|
$this->assertSame('Group', $this->context->getGroup());
|
||
|
}
|
||
|
|
||
|
public function testClone()
|
||
|
{
|
||
|
$clone = clone $this->context;
|
||
|
|
||
|
// Cloning the context keeps the reference to the original violation
|
||
|
// list. This way we can efficiently duplicate context instances during
|
||
|
// the validation run and only modify the properties that need to be
|
||
|
// changed.
|
||
|
$this->assertSame($this->context->getViolations(), $clone->getViolations());
|
||
|
}
|
||
|
|
||
|
public function testAddViolation()
|
||
|
{
|
||
|
$this->translator->expects($this->once())
|
||
|
->method('trans')
|
||
|
->with('Error', array('foo' => 'bar'))
|
||
|
->will($this->returnValue('Translated error'));
|
||
|
|
||
|
$this->context->addViolation('Error', array('foo' => 'bar'), 'invalid');
|
||
|
|
||
|
$this->assertEquals(new ConstraintViolationList(array(
|
||
|
new ConstraintViolation(
|
||
|
'Translated error',
|
||
|
'Error',
|
||
|
array('foo' => 'bar'),
|
||
|
'Root',
|
||
|
'foo.bar',
|
||
|
'invalid'
|
||
|
),
|
||
|
)), $this->context->getViolations());
|
||
|
}
|
||
|
|
||
|
public function testAddViolationUsesPreconfiguredValueIfNotPassed()
|
||
|
{
|
||
|
$this->translator->expects($this->once())
|
||
|
->method('trans')
|
||
|
->with('Error', array())
|
||
|
->will($this->returnValue('Translated error'));
|
||
|
|
||
|
$this->context->addViolation('Error');
|
||
|
|
||
|
$this->assertEquals(new ConstraintViolationList(array(
|
||
|
new ConstraintViolation(
|
||
|
'Translated error',
|
||
|
'Error',
|
||
|
array(),
|
||
|
'Root',
|
||
|
'foo.bar',
|
||
|
'currentValue'
|
||
|
),
|
||
|
)), $this->context->getViolations());
|
||
|
}
|
||
|
|
||
|
public function testAddViolationUsesPassedNullValue()
|
||
|
{
|
||
|
$this->translator->expects($this->once())
|
||
|
->method('trans')
|
||
|
->with('Error', array('foo1' => 'bar1'))
|
||
|
->will($this->returnValue('Translated error'));
|
||
|
$this->translator->expects($this->once())
|
||
|
->method('transChoice')
|
||
|
->with('Choice error', 1, array('foo2' => 'bar2'))
|
||
|
->will($this->returnValue('Translated choice error'));
|
||
|
|
||
|
// passed null value should override preconfigured value "invalid"
|
||
|
$this->context->addViolation('Error', array('foo1' => 'bar1'), null);
|
||
|
$this->context->addViolation('Choice error', array('foo2' => 'bar2'), null, 1);
|
||
|
|
||
|
$this->assertEquals(new ConstraintViolationList(array(
|
||
|
new ConstraintViolation(
|
||
|
'Translated error',
|
||
|
'Error',
|
||
|
array('foo1' => 'bar1'),
|
||
|
'Root',
|
||
|
'foo.bar',
|
||
|
null
|
||
|
),
|
||
|
new ConstraintViolation(
|
||
|
'Translated choice error',
|
||
|
'Choice error',
|
||
|
array('foo2' => 'bar2'),
|
||
|
'Root',
|
||
|
'foo.bar',
|
||
|
null,
|
||
|
1
|
||
|
),
|
||
|
)), $this->context->getViolations());
|
||
|
}
|
||
|
|
||
|
public function testAddViolationAt()
|
||
|
{
|
||
|
$this->translator->expects($this->once())
|
||
|
->method('trans')
|
||
|
->with('Error', array('foo' => 'bar'))
|
||
|
->will($this->returnValue('Translated error'));
|
||
|
|
||
|
// override preconfigured property path
|
||
|
$this->context->addViolationAt('bam.baz', 'Error', array('foo' => 'bar'), 'invalid');
|
||
|
|
||
|
$this->assertEquals(new ConstraintViolationList(array(
|
||
|
new ConstraintViolation(
|
||
|
'Translated error',
|
||
|
'Error',
|
||
|
array('foo' => 'bar'),
|
||
|
'Root',
|
||
|
'foo.bar.bam.baz',
|
||
|
'invalid'
|
||
|
),
|
||
|
)), $this->context->getViolations());
|
||
|
}
|
||
|
|
||
|
public function testAddViolationAtUsesPreconfiguredValueIfNotPassed()
|
||
|
{
|
||
|
$this->translator->expects($this->once())
|
||
|
->method('trans')
|
||
|
->with('Error', array())
|
||
|
->will($this->returnValue('Translated error'));
|
||
|
|
||
|
$this->context->addViolationAt('bam.baz', 'Error');
|
||
|
|
||
|
$this->assertEquals(new ConstraintViolationList(array(
|
||
|
new ConstraintViolation(
|
||
|
'Translated error',
|
||
|
'Error',
|
||
|
array(),
|
||
|
'Root',
|
||
|
'foo.bar.bam.baz',
|
||
|
'currentValue'
|
||
|
),
|
||
|
)), $this->context->getViolations());
|
||
|
}
|
||
|
|
||
|
public function testAddViolationAtUsesPassedNullValue()
|
||
|
{
|
||
|
$this->translator->expects($this->once())
|
||
|
->method('trans')
|
||
|
->with('Error', array('foo' => 'bar'))
|
||
|
->will($this->returnValue('Translated error'));
|
||
|
$this->translator->expects($this->once())
|
||
|
->method('transChoice')
|
||
|
->with('Choice error', 2, array('foo' => 'bar'))
|
||
|
->will($this->returnValue('Translated choice error'));
|
||
|
|
||
|
// passed null value should override preconfigured value "invalid"
|
||
|
$this->context->addViolationAt('bam.baz', 'Error', array('foo' => 'bar'), null);
|
||
|
$this->context->addViolationAt('bam.baz', 'Choice error', array('foo' => 'bar'), null, 2);
|
||
|
|
||
|
$this->assertEquals(new ConstraintViolationList(array(
|
||
|
new ConstraintViolation(
|
||
|
'Translated error',
|
||
|
'Error',
|
||
|
array('foo' => 'bar'),
|
||
|
'Root',
|
||
|
'foo.bar.bam.baz',
|
||
|
null
|
||
|
),
|
||
|
new ConstraintViolation(
|
||
|
'Translated choice error',
|
||
|
'Choice error',
|
||
|
array('foo' => 'bar'),
|
||
|
'Root',
|
||
|
'foo.bar.bam.baz',
|
||
|
null,
|
||
|
2
|
||
|
),
|
||
|
)), $this->context->getViolations());
|
||
|
}
|
||
|
|
||
|
public function testAddViolationPluralTranslationError()
|
||
|
{
|
||
|
$this->translator->expects($this->once())
|
||
|
->method('transChoice')
|
||
|
->with('foo')
|
||
|
->will($this->throwException(new \InvalidArgumentException()));
|
||
|
$this->translator->expects($this->once())
|
||
|
->method('trans')
|
||
|
->with('foo');
|
||
|
|
||
|
$this->context->addViolation('foo', array(), null, 2);
|
||
|
}
|
||
|
|
||
|
public function testGetPropertyPath()
|
||
|
{
|
||
|
$this->assertEquals('foo.bar', $this->context->getPropertyPath());
|
||
|
}
|
||
|
|
||
|
public function testGetPropertyPathWithIndexPath()
|
||
|
{
|
||
|
$this->assertEquals('foo.bar[bam]', $this->context->getPropertyPath('[bam]'));
|
||
|
}
|
||
|
|
||
|
public function testGetPropertyPathWithEmptyPath()
|
||
|
{
|
||
|
$this->assertEquals('foo.bar', $this->context->getPropertyPath(''));
|
||
|
}
|
||
|
|
||
|
public function testGetPropertyPathWithEmptyCurrentPropertyPath()
|
||
|
{
|
||
|
$this->context = new ExecutionContext($this->globalContext, $this->translator, self::TRANS_DOMAIN, $this->metadata, 'currentValue', 'Group', '');
|
||
|
|
||
|
$this->assertEquals('bam.baz', $this->context->getPropertyPath('bam.baz'));
|
||
|
}
|
||
|
|
||
|
public function testGetPropertyPathWithNestedCollectionsAndAllMixed()
|
||
|
{
|
||
|
$constraints = new Collection(array(
|
||
|
'shelves' => new All(array('constraints' => array(
|
||
|
new Collection(array(
|
||
|
'name' => new ConstraintA(),
|
||
|
'books' => new All(array('constraints' => array(
|
||
|
new ConstraintA(),
|
||
|
))),
|
||
|
)),
|
||
|
))),
|
||
|
'name' => new ConstraintA(),
|
||
|
));
|
||
|
$data = array(
|
||
|
'shelves' => array(
|
||
|
array(
|
||
|
'name' => 'Research',
|
||
|
'books' => array('foo', 'bar'),
|
||
|
),
|
||
|
array(
|
||
|
'name' => 'VALID',
|
||
|
'books' => array('foozy', 'VALID', 'bazzy'),
|
||
|
),
|
||
|
),
|
||
|
'name' => 'Library',
|
||
|
);
|
||
|
$expectedViolationPaths = array(
|
||
|
'[shelves][0][name]',
|
||
|
'[shelves][0][books][0]',
|
||
|
'[shelves][0][books][1]',
|
||
|
'[shelves][1][books][0]',
|
||
|
'[shelves][1][books][2]',
|
||
|
'[name]',
|
||
|
);
|
||
|
|
||
|
$visitor = new ValidationVisitor('Root', $this->metadataFactory, new ConstraintValidatorFactory(), $this->translator);
|
||
|
$context = new ExecutionContext($visitor, $this->translator, self::TRANS_DOMAIN);
|
||
|
$context->validateValue($data, $constraints);
|
||
|
|
||
|
foreach ($context->getViolations() as $violation) {
|
||
|
$violationPaths[] = $violation->getPropertyPath();
|
||
|
}
|
||
|
|
||
|
$this->assertEquals($expectedViolationPaths, $violationPaths);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
class ExecutionContextTest_TestClass
|
||
|
{
|
||
|
public $myProperty;
|
||
|
}
|