Skip to content

Commit 81044e2

Browse files
authored
Added some tests (#1)
* added some tests * Added some readme and fixed tests
1 parent 5f776a3 commit 81044e2

File tree

4 files changed

+190
-6
lines changed

4 files changed

+190
-6
lines changed

Readme.md

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,56 @@
77
[![Quality Score](https://img.shields.io/scrutinizer/g/happyr/entity-exists-validation-constraint.svg?style=flat-square)](https://scrutinizer-ci.com/g/happyr/entity-exists-validation-constraint)
88
[![Total Downloads](https://img.shields.io/packagist/dt/happyr/entity-exists-validation-constraint.svg?style=flat-square)](https://packagist.org/packages/happyr/entity-exists-validation-constraint)
99

10+
A small validator that verifies that an Entity actually exists. This is especially useful if you use Symfony Messenger
11+
component. Now you can safely validate the message and put it on a queue for processing later.
12+
13+
14+
```php
15+
namespace App\Message\Command;
16+
17+
use Happyr\Validator\Constraint\EntityExist;
18+
use Symfony\Component\Validator\Constraints as Assert;
19+
20+
final class EmailUser
21+
{
22+
/**
23+
* @Assert\NotBlank
24+
* @Assert\Uuid
25+
* @EntityExist(entity="App\Entity\User")
26+
*
27+
* @var string UUID to user's id property
28+
*/
29+
private $user;
30+
31+
/**
32+
* @Assert\NotBlank
33+
* @EntityExist(entity="App\Entity\Other", property="name")
34+
*
35+
* @var string The name of "Other". We use its "name" property.
36+
*/
37+
private $other;
38+
39+
// ...
40+
```
41+
42+
## Install
43+
44+
```console
45+
composer require happyr/entity-exists-validation-constraint
46+
47+
```
48+
49+
Then register the services with:
50+
51+
```yaml
52+
# config/packages/happyr_entity_exists_validator.yaml
53+
services:
54+
Happyr\Validator\Constraint\EntityExistValidator:
55+
arguments: ['@doctrine.orm.entity_manager']
56+
tags: [ 'validator.constraint_validator' ]
57+
```
58+
59+
## Note
60+
61+
The Validator will not produce a violation when value is empty. This means that you should most likely use it in
62+
combination with `NotBlank`.

composer.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@
1515
],
1616
"require": {
1717
"php": "^7.2",
18-
"symfony/validator": "^3.4 || ^4.3"
18+
"symfony/validator": "^3.4 || ^4.3",
19+
"doctrine/orm": "^2.4"
1920
},
2021
"require-dev": {
2122
"symfony/phpunit-bridge": "^4.3"

src/EntityExistValidator.php

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,16 +24,12 @@ public function __construct(EntityManagerInterface $entityManager)
2424
public function validate($value, Constraint $constraint): void
2525
{
2626
if (!$constraint instanceof EntityExist) {
27-
throw new \LengthException(\sprintf(
27+
throw new \LogicException(\sprintf(
2828
'You can only pass %s constraint to this validator.',
2929
EntityExist::class
3030
));
3131
}
3232

33-
if (empty($value)) {
34-
return;
35-
}
36-
3733
if (empty($constraint->entity)) {
3834
throw new \LogicException(\sprintf('Must set "entity" on "%s" validator', EntityExist::class));
3935
}

tests/EntityExistValidatorTest.php

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Test\Happyr\Validator\Constraint;
6+
7+
use Doctrine\ORM\EntityManagerInterface;
8+
use Doctrine\ORM\EntityRepository;
9+
use Happyr\Validator\Constraint\EntityExist;
10+
use Happyr\Validator\Constraint\EntityExistValidator;
11+
use PHPUnit\Framework\MockObject\MockObject;
12+
use PHPUnit\Framework\TestCase;
13+
use Symfony\Component\Validator\Constraints\NotNull;
14+
use Symfony\Component\Validator\Context\ExecutionContextInterface;
15+
use Symfony\Component\Validator\Violation\ConstraintViolationBuilderInterface;
16+
17+
class EntityExistValidatorTest extends TestCase
18+
{
19+
/** @var MockObject */
20+
private $entityManager;
21+
22+
/** @var MockObject */
23+
private $context;
24+
25+
/** @var EntityExistValidator */
26+
private $validator;
27+
28+
protected function setUp(): void
29+
{
30+
$this->entityManager = $this->getMockBuilder(EntityManagerInterface::class)->getMock();
31+
$this->context = $this->getMockBuilder(ExecutionContextInterface::class)->getMock();
32+
33+
$this->validator = new EntityExistValidator($this->entityManager);
34+
$this->validator->initialize($this->context);
35+
}
36+
37+
public function testValidateWithWrongConstraint()
38+
{
39+
$this->expectException(\LogicException::class);
40+
$this->validator->validate('foo', new NotNull());
41+
}
42+
43+
public function testValidateWithNoEntity()
44+
{
45+
$constraint = new EntityExist();
46+
47+
$this->expectException(\LogicException::class);
48+
$this->validator->validate('foobar', $constraint);
49+
}
50+
51+
/**
52+
* @dataProvider getValidValues
53+
*/
54+
public function testValidateValidEntity($value)
55+
{
56+
$this->context->expects($this->never())->method('buildViolation');
57+
$constraint = new EntityExist();
58+
$constraint->entity = 'App\Entity\User';
59+
60+
$repository = $this->getMockBuilder(EntityRepository::class)
61+
->disableOriginalConstructor()
62+
->getMock();
63+
$repository
64+
->expects($this->once())
65+
->method('findOneBy')
66+
->with(['id' => $value])
67+
->willReturn('my_user');
68+
69+
$this->entityManager
70+
->expects($this->once())
71+
->method('getRepository')
72+
->with('App\Entity\User')
73+
->willReturn($repository);
74+
75+
$this->validator->validate($value, $constraint);
76+
}
77+
78+
public function getValidValues()
79+
{
80+
yield ['foobar'];
81+
yield [''];
82+
yield [null];
83+
}
84+
85+
public function testValidateValidEntityWithCustomProperty()
86+
{
87+
$this->context->expects($this->never())->method('buildViolation');
88+
$constraint = new EntityExist();
89+
$constraint->entity = 'App\Entity\User';
90+
$constraint->property = 'uuid';
91+
92+
$repository = $this->getMockBuilder(EntityRepository::class)
93+
->disableOriginalConstructor()
94+
->getMock();
95+
$repository
96+
->expects($this->once())
97+
->method('findOneBy')
98+
->with(['uuid' => 'foobar'])
99+
->willReturn('my_user');
100+
101+
$this->entityManager
102+
->expects($this->once())
103+
->method('getRepository')
104+
->with('App\Entity\User')
105+
->willReturn($repository);
106+
107+
$this->validator->validate('foobar', $constraint);
108+
}
109+
110+
public function testValidateInvalidEntity()
111+
{
112+
$violationBuilder = $this->getMockBuilder(ConstraintViolationBuilderInterface::class)->getMock();
113+
$violationBuilder->method('setParameter')->will($this->returnSelf());
114+
115+
$this->context->expects($this->once())->method('buildViolation')->willReturn($violationBuilder);
116+
$constraint = new EntityExist();
117+
$constraint->entity = 'App\Entity\User';
118+
119+
$repository = $this->getMockBuilder(EntityRepository::class)
120+
->disableOriginalConstructor()
121+
->getMock();
122+
$repository
123+
->expects($this->once())
124+
->method('findOneBy')
125+
->willReturn(null);
126+
127+
$this->entityManager
128+
->expects($this->once())
129+
->method('getRepository')
130+
->willReturn($repository);
131+
132+
$this->validator->validate('foobar', $constraint);
133+
}
134+
}

0 commit comments

Comments
 (0)