diff --git a/src/Resources/translations/validators.de.xliff b/src/Resources/translations/validators.de.xliff index eec1868b2..104bf4352 100644 --- a/src/Resources/translations/validators.de.xliff +++ b/src/Resources/translations/validators.de.xliff @@ -13,6 +13,10 @@ Bitte wählen Sie eine übergeordnete Seite. + + error.uniq_url.no_site + Der Seite ist muss eine Webseite zugeordnet sein. + diff --git a/src/Resources/translations/validators.en.xliff b/src/Resources/translations/validators.en.xliff index c745f9b8f..8f3ea0dd6 100644 --- a/src/Resources/translations/validators.en.xliff +++ b/src/Resources/translations/validators.en.xliff @@ -12,6 +12,10 @@ The root URL '/' is already associated with another page of this site, please select a parent. + + error.uniq_url.no_site + A website must be assigned to the page. + diff --git a/src/Resources/translations/validators.fr.xliff b/src/Resources/translations/validators.fr.xliff index 12fe37ea0..f0f41e8e4 100644 --- a/src/Resources/translations/validators.fr.xliff +++ b/src/Resources/translations/validators.fr.xliff @@ -12,6 +12,10 @@ L'URL racine '/' est déjà associée à une autre page de ce site, veuillez sélectionner un parent. + + error.uniq_url.no_site + Un site Web doit être attribué à la page. + diff --git a/src/Validator/UniqueUrlValidator.php b/src/Validator/UniqueUrlValidator.php index 08ade6b32..4f7c07d88 100644 --- a/src/Validator/UniqueUrlValidator.php +++ b/src/Validator/UniqueUrlValidator.php @@ -15,14 +15,13 @@ use Sonata\PageBundle\Model\PageInterface; use Sonata\PageBundle\Model\PageManagerInterface; -use Sonata\PageBundle\Model\SiteInterface; +use Sonata\PageBundle\Validator\Constraints\UniqueUrl; use Symfony\Component\Validator\Constraint; use Symfony\Component\Validator\ConstraintValidator; +use Symfony\Component\Validator\Exception\UnexpectedTypeException; +use Symfony\Component\Validator\Exception\UnexpectedValueException; -/** - * @final since sonata-project/page-bundle 3.26 - */ -class UniqueUrlValidator extends ConstraintValidator +final class UniqueUrlValidator extends ConstraintValidator { /** * @var PageManagerInterface @@ -36,14 +35,21 @@ public function __construct(PageManagerInterface $manager) public function validate($value, Constraint $constraint): void { - if (!$value instanceof PageInterface) { - $this->context->addViolation('The page is not valid, expected a PageInterface'); - + if (!$constraint instanceof UniqueUrl) { + throw new UnexpectedTypeException($constraint, UniqueUrl::class); + } + // do not validate on null, use NotNull instead + if (null === $value) { return; } + if (!$value instanceof PageInterface) { + throw new UnexpectedValueException($value, PageInterface::class); + } - if (!$value->getSite() instanceof SiteInterface) { - $this->context->addViolation('The page is not linked to a Site'); + if (null === $value->getSite()) { + $this->context->buildViolation('error.uniq_url.no_site') + ->atPath('site') + ->addViolation(); return; } diff --git a/tests/Validator/UniqueUrlValidatorTest.php b/tests/Validator/UniqueUrlValidatorTest.php index 68eb4640b..5cab0b7df 100644 --- a/tests/Validator/UniqueUrlValidatorTest.php +++ b/tests/Validator/UniqueUrlValidatorTest.php @@ -13,19 +13,43 @@ namespace Sonata\PageBundle\Tests\Validator; -use PHPUnit\Framework\TestCase; use Sonata\PageBundle\Model\PageInterface; use Sonata\PageBundle\Model\PageManagerInterface; use Sonata\PageBundle\Model\SiteInterface; use Sonata\PageBundle\Validator\Constraints\UniqueUrl; use Sonata\PageBundle\Validator\UniqueUrlValidator; -use Symfony\Component\Translation\TranslatorInterface; -use Symfony\Component\Validator\Context\ExecutionContext; -use Symfony\Component\Validator\Validator\ContextualValidatorInterface; -use Symfony\Component\Validator\Validator\ValidatorInterface; +use Symfony\Component\Validator\Test\ConstraintValidatorTestCase; -final class UniqueUrlValidatorTest extends TestCase +final class UniqueUrlValidatorTest extends ConstraintValidatorTestCase { + /** + * @var PageManagerInterface + */ + protected $manager; + + protected function setUp(): void + { + $this->manager = $this->createMock(PageManagerInterface::class); + + parent::setUp(); + } + + public function testValidateWithoutSite(): void + { + $page = $this->createMock(PageInterface::class); + $page->expects(static::exactly(1))->method('getSite')->willReturn(null); + $page->expects(static::never())->method('isError'); + + $this->manager->expects(static::never())->method('fixUrl'); + $this->manager->expects(static::never())->method('findBy'); + + $this->validator->validate($page, new UniqueUrl()); + + $this->buildViolation('error.uniq_url.no_site') + ->atPath($this->propertyPath.'.site') + ->assertRaised(); + } + /** * @group legacy */ @@ -37,40 +61,36 @@ public function testValidateWithNoPageFound(): void $page->expects(static::exactly(2))->method('getSite')->willReturn($site); $page->expects(static::exactly(2))->method('isError')->willReturn(false); - $manager = $this->createMock(PageManagerInterface::class); - $manager->expects(static::once())->method('fixUrl'); - $manager->expects(static::once())->method('findBy')->willReturn([$page]); - - $context = $this->getContext(); + $this->manager->expects(static::once())->method('fixUrl'); + $this->manager->expects(static::once())->method('findBy')->willReturn([$page]); - $validator = new UniqueUrlValidator($manager); - $validator->initialize($context); + $this->validator->validate($page, new UniqueUrl()); - $validator->validate($page, new UniqueUrl()); + $this->assertNoViolation(); } public function testValidateWithPageFound(): void { + $url = '/salut'; $site = $this->createMock(SiteInterface::class); $page = $this->createMock(PageInterface::class); $page->expects(static::exactly(2))->method('getSite')->willReturn($site); $page->expects(static::exactly(2))->method('isError')->willReturn(false); - $page->method('getUrl')->willReturn('/salut'); + $page->method('getUrl')->willReturn($url); $pageFound = $this->createMock(PageInterface::class); - $pageFound->method('getUrl')->willReturn('/salut'); - - $manager = $this->createMock(PageManagerInterface::class); - $manager->expects(static::once())->method('fixUrl'); - $manager->expects(static::once())->method('findBy')->willReturn([$page, $pageFound]); + $pageFound->method('getUrl')->willReturn($url); - $context = $this->getContext(); + $this->manager->expects(static::once())->method('fixUrl'); + $this->manager->expects(static::once())->method('findBy')->willReturn([$page, $pageFound]); - $validator = new UniqueUrlValidator($manager); - $validator->initialize($context); + $this->validator->validate($page, new UniqueUrl()); - $validator->validate($page, new UniqueUrl()); + $this->buildViolation('error.uniq_url') + ->setParameter('%url%', $url) + ->atPath($this->propertyPath.'.url') + ->assertRaised(); } public function testValidateWithRootUrlAndNoParent(): void @@ -86,16 +106,14 @@ public function testValidateWithRootUrlAndNoParent(): void $pageFound = $this->createMock(PageInterface::class); $pageFound->method('getUrl')->willReturn('/'); - $manager = $this->createMock(PageManagerInterface::class); - $manager->expects(static::once())->method('fixUrl'); - $manager->expects(static::once())->method('findBy')->willReturn([$page, $pageFound]); - - $context = $this->getContext(); + $this->manager->expects(static::once())->method('fixUrl'); + $this->manager->expects(static::once())->method('findBy')->willReturn([$page, $pageFound]); - $validator = new UniqueUrlValidator($manager); - $validator->initialize($context); + $this->validator->validate($page, new UniqueUrl()); - $validator->validate($page, new UniqueUrl()); + $this->buildViolation('error.uniq_url.parent_unselect') + ->atPath($this->propertyPath.'.parent') + ->assertRaised(); } public function testValidateWithPageDynamic(): void @@ -108,32 +126,12 @@ public function testValidateWithPageDynamic(): void $page->expects(static::once())->method('isDynamic')->willReturn(true); $page->method('getUrl')->willReturn('/salut'); - $manager = $this->createMock(PageManagerInterface::class); - - $context = $this->getContext(); - - $validator = new UniqueUrlValidator($manager); - $validator->initialize($context); - - $validator->validate($page, new UniqueUrl()); + $this->validator->validate($page, new UniqueUrl()); + $this->assertNoViolation(); } - private function getContext(): ExecutionContext + protected function createValidator(): UniqueUrlValidator { - $translator = $this->createMock(TranslatorInterface::class); - $validator = $this->createMock(ValidatorInterface::class); - $contextualValidator = $this->createMock(ContextualValidatorInterface::class); - - $context = new ExecutionContext($validator, 'root', $translator); - - $context->setGroup('MyGroup'); - $context->setNode('InvalidValue', null, null, 'property.path'); - $context->setConstraint(new UniqueUrl()); - $validator - ->method('inContext') - ->with($context) - ->willReturn($contextualValidator); - - return $context; + return new UniqueUrlValidator($this->manager); } }