mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-10-06 21:39:42 +00:00
Add validate
method to PersonIdentifierEngineInterface and related classes
- Introduced `validate` method in `PersonIdentifierEngineInterface`. - Added `ValidIdentifierConstraint` to `PersonIdentifier` entity. - Updated `PersonIdentifierWorker` to implement the new `validate` method.
This commit is contained in:
@@ -13,6 +13,7 @@ namespace Chill\PersonBundle\Entity\Identifier;
|
||||
|
||||
use Chill\PersonBundle\Entity\Person;
|
||||
use Chill\PersonBundle\PersonIdentifier\Validator\UniqueIdentifierConstraint;
|
||||
use Chill\PersonBundle\PersonIdentifier\Validator\ValidIdentifierConstraint;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
|
||||
#[ORM\Entity]
|
||||
@@ -20,6 +21,7 @@ use Doctrine\ORM\Mapping as ORM;
|
||||
#[ORM\UniqueConstraint(name: 'chill_person_identifier_unique', columns: ['definition_id', 'canonical'])]
|
||||
#[ORM\UniqueConstraint(name: 'chill_person_identifier_unique_person_definition', columns: ['definition_id', 'person_id'])]
|
||||
#[UniqueIdentifierConstraint]
|
||||
#[ValidIdentifierConstraint]
|
||||
class PersonIdentifier
|
||||
{
|
||||
#[ORM\Id]
|
||||
|
@@ -14,6 +14,7 @@ namespace Chill\PersonBundle\PersonIdentifier;
|
||||
use Chill\PersonBundle\Entity\Identifier\PersonIdentifier;
|
||||
use Chill\PersonBundle\Entity\Identifier\PersonIdentifierDefinition;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Component\Validator\Context\ExecutionContextInterface;
|
||||
|
||||
interface PersonIdentifierEngineInterface
|
||||
{
|
||||
@@ -32,4 +33,6 @@ interface PersonIdentifierEngineInterface
|
||||
* by the definition, the validation will fails.
|
||||
*/
|
||||
public function isEmpty(PersonIdentifier $identifier): bool;
|
||||
|
||||
public function validate(ExecutionContextInterface $context, PersonIdentifier $identifier, PersonIdentifierDefinition $definition): void;
|
||||
}
|
||||
|
@@ -24,6 +24,8 @@ interface PersonIdentifierManagerInterface
|
||||
|
||||
/**
|
||||
* @param int|PersonIdentifierDefinition $personIdentifierDefinition an instance of PersonIdentifierDefinition, or his id
|
||||
*
|
||||
* @throw PersonIdentifierNotFoundException
|
||||
*/
|
||||
public function buildWorkerByPersonIdentifierDefinition(int|PersonIdentifierDefinition $personIdentifierDefinition): PersonIdentifierWorker;
|
||||
}
|
||||
|
@@ -14,8 +14,9 @@ namespace Chill\PersonBundle\PersonIdentifier;
|
||||
use Chill\PersonBundle\Entity\Identifier\PersonIdentifier;
|
||||
use Chill\PersonBundle\Entity\Identifier\PersonIdentifierDefinition;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Component\Validator\Context\ExecutionContextInterface;
|
||||
|
||||
final readonly class PersonIdentifierWorker
|
||||
readonly class PersonIdentifierWorker
|
||||
{
|
||||
public function __construct(
|
||||
private PersonIdentifierEngineInterface $identifierEngine,
|
||||
@@ -54,4 +55,9 @@ final readonly class PersonIdentifierWorker
|
||||
{
|
||||
return $this->identifierEngine->isEmpty($identifier);
|
||||
}
|
||||
|
||||
public function validate(ExecutionContextInterface $context, PersonIdentifier $identifier, PersonIdentifierDefinition $definition): void
|
||||
{
|
||||
$this->identifierEngine->validate($context, $identifier, $definition);
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* Chill is a software for social workers
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Chill\PersonBundle\PersonIdentifier\Validator;
|
||||
|
||||
use Symfony\Component\Validator\Constraint;
|
||||
|
||||
#[\Attribute]
|
||||
class ValidIdentifierConstraint extends Constraint
|
||||
{
|
||||
public function getTargets(): string
|
||||
{
|
||||
return self::CLASS_CONSTRAINT;
|
||||
}
|
||||
}
|
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* Chill is a software for social workers
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Chill\PersonBundle\PersonIdentifier\Validator;
|
||||
|
||||
use Chill\PersonBundle\Entity\Identifier\PersonIdentifier;
|
||||
use Chill\PersonBundle\PersonIdentifier\PersonIdentifierManagerInterface;
|
||||
use Symfony\Component\Validator\Constraint;
|
||||
use Symfony\Component\Validator\ConstraintValidator;
|
||||
use Symfony\Component\Validator\Exception\UnexpectedTypeException;
|
||||
use Symfony\Component\Validator\Exception\UnexpectedValueException;
|
||||
|
||||
final class ValidIdentifierConstraintValidator extends ConstraintValidator
|
||||
{
|
||||
public function __construct(private readonly PersonIdentifierManagerInterface $personIdentifierManager) {}
|
||||
|
||||
public function validate($value, Constraint $constraint): void
|
||||
{
|
||||
if (!$constraint instanceof ValidIdentifierConstraint) {
|
||||
throw new UnexpectedTypeException($constraint, ValidIdentifierConstraint::class);
|
||||
}
|
||||
|
||||
if (!$value instanceof PersonIdentifier) {
|
||||
throw new UnexpectedValueException($value, PersonIdentifier::class);
|
||||
}
|
||||
|
||||
$worker = $this->personIdentifierManager->buildWorkerByPersonIdentifierDefinition($value->getDefinition());
|
||||
|
||||
$worker->validate($this->context, $value, $value->getDefinition());
|
||||
}
|
||||
}
|
@@ -14,6 +14,7 @@ namespace Chill\PersonBundle\Tests\Controller;
|
||||
use Chill\MainBundle\Pagination\PaginatorFactoryInterface;
|
||||
use Chill\MainBundle\Serializer\Normalizer\CollectionNormalizer;
|
||||
use Chill\PersonBundle\Controller\PersonIdentifierListApiController;
|
||||
use Chill\PersonBundle\Entity\Identifier\PersonIdentifier;
|
||||
use Chill\PersonBundle\Entity\Identifier\PersonIdentifierDefinition;
|
||||
use Chill\PersonBundle\PersonIdentifier\Normalizer\PersonIdentifierWorkerNormalizer;
|
||||
use Chill\PersonBundle\PersonIdentifier\PersonIdentifierEngineInterface;
|
||||
@@ -25,6 +26,7 @@ use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
|
||||
use Symfony\Component\Security\Core\Security;
|
||||
use Symfony\Component\Serializer\Encoder\JsonEncoder;
|
||||
use Symfony\Component\Serializer\Serializer;
|
||||
use Symfony\Component\Validator\Context\ExecutionContextInterface;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
@@ -72,10 +74,12 @@ class PersonIdentifierListApiControllerTest extends TestCase
|
||||
|
||||
public function buildForm(\Symfony\Component\Form\FormBuilderInterface $builder, PersonIdentifierDefinition $personIdentifierDefinition): void {}
|
||||
|
||||
public function renderAsString(?\Chill\PersonBundle\Entity\Identifier\PersonIdentifier $identifier, PersonIdentifierDefinition $definition): string
|
||||
public function renderAsString(?PersonIdentifier $identifier, PersonIdentifierDefinition $definition): string
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
public function validate(ExecutionContextInterface $context, PersonIdentifier $identifier, PersonIdentifierDefinition $definition): void {}
|
||||
};
|
||||
|
||||
$definition1 = new PersonIdentifierDefinition(['en' => 'Label 1'], 'dummy');
|
||||
|
@@ -11,12 +11,14 @@ declare(strict_types=1);
|
||||
|
||||
namespace Chill\PersonBundle\Tests\PersonIdentifier\Normalizer;
|
||||
|
||||
use Chill\PersonBundle\Entity\Identifier\PersonIdentifier;
|
||||
use Chill\PersonBundle\Entity\Identifier\PersonIdentifierDefinition;
|
||||
use Chill\PersonBundle\PersonIdentifier\Normalizer\PersonIdentifierWorkerNormalizer;
|
||||
use Chill\PersonBundle\PersonIdentifier\PersonIdentifierEngineInterface;
|
||||
use Chill\PersonBundle\PersonIdentifier\PersonIdentifierWorker;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Symfony\Component\Serializer\Exception\UnexpectedValueException;
|
||||
use Symfony\Component\Validator\Context\ExecutionContextInterface;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
@@ -40,7 +42,7 @@ class PersonIdentifierWorkerNormalizerTest extends TestCase
|
||||
|
||||
public function buildForm(\Symfony\Component\Form\FormBuilderInterface $builder, PersonIdentifierDefinition $personIdentifierDefinition): void {}
|
||||
|
||||
public function renderAsString(?\Chill\PersonBundle\Entity\Identifier\PersonIdentifier $identifier, PersonIdentifierDefinition $definition): string
|
||||
public function renderAsString(?PersonIdentifier $identifier, PersonIdentifierDefinition $definition): string
|
||||
{
|
||||
return '';
|
||||
}
|
||||
@@ -70,10 +72,12 @@ class PersonIdentifierWorkerNormalizerTest extends TestCase
|
||||
|
||||
public function buildForm(\Symfony\Component\Form\FormBuilderInterface $builder, PersonIdentifierDefinition $personIdentifierDefinition): void {}
|
||||
|
||||
public function renderAsString(?\Chill\PersonBundle\Entity\Identifier\PersonIdentifier $identifier, PersonIdentifierDefinition $definition): string
|
||||
public function renderAsString(?PersonIdentifier $identifier, PersonIdentifierDefinition $definition): string
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
public function validate(ExecutionContextInterface $context, PersonIdentifier $identifier, PersonIdentifierDefinition $definition): void {}
|
||||
};
|
||||
|
||||
$definition = new PersonIdentifierDefinition(label: ['en' => 'SSN'], engine: 'string');
|
||||
|
@@ -24,6 +24,7 @@ use PHPUnit\Framework\TestCase;
|
||||
use Prophecy\Argument;
|
||||
use Prophecy\PhpUnit\ProphecyTrait;
|
||||
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
|
||||
use Symfony\Component\Validator\Context\ExecutionContextInterface;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
@@ -71,6 +72,8 @@ class PersonIdRenderingTest extends TestCase
|
||||
// same behavior as StringIdentifier::renderAsString
|
||||
return $identifier?->getValue()['content'] ?? '';
|
||||
}
|
||||
|
||||
public function validate(ExecutionContextInterface $context, PersonIdentifier $identifier, PersonIdentifierDefinition $definition): void {}
|
||||
};
|
||||
|
||||
return new PersonIdentifierWorker($engine, $definition);
|
||||
|
@@ -0,0 +1,79 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* Chill is a software for social workers
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Chill\PersonBundle\Tests\PersonIdentifier\Validator;
|
||||
|
||||
use Chill\PersonBundle\Entity\Identifier\PersonIdentifier;
|
||||
use Chill\PersonBundle\Entity\Identifier\PersonIdentifierDefinition;
|
||||
use Chill\PersonBundle\PersonIdentifier\PersonIdentifierManagerInterface;
|
||||
use Chill\PersonBundle\PersonIdentifier\PersonIdentifierWorker;
|
||||
use Chill\PersonBundle\PersonIdentifier\Validator\ValidIdentifierConstraint;
|
||||
use Chill\PersonBundle\PersonIdentifier\Validator\ValidIdentifierConstraintValidator;
|
||||
use PHPUnit\Framework\Attributes\CoversClass;
|
||||
use Prophecy\PhpUnit\ProphecyTrait;
|
||||
use Symfony\Component\Validator\Test\ConstraintValidatorTestCase;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
#[CoversClass(ValidIdentifierConstraintValidator::class)]
|
||||
final class ValidIdentifierConstraintValidatorTest extends ConstraintValidatorTestCase
|
||||
{
|
||||
use ProphecyTrait;
|
||||
|
||||
private object $manager;
|
||||
private PersonIdentifierManagerInterface|\Prophecy\Prophecy\ObjectProphecy $managerProphecy;
|
||||
|
||||
protected function createValidator(): ValidIdentifierConstraintValidator
|
||||
{
|
||||
// $this->manager is set in setUp() before parent::setUp() calls this method
|
||||
return new ValidIdentifierConstraintValidator($this->manager);
|
||||
}
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
// Prepare manager prophecy and reveal it before parent::setUp()
|
||||
$managerProphecy = $this->prophesize(PersonIdentifierManagerInterface::class);
|
||||
$this->manager = $managerProphecy->reveal();
|
||||
|
||||
// Store the prophecy itself for later configuration in tests
|
||||
$this->managerProphecy = $managerProphecy; // dynamic property for test methods
|
||||
|
||||
parent::setUp();
|
||||
}
|
||||
|
||||
public function testItCallsEngineValidateThroughWorker(): void
|
||||
{
|
||||
// Arrange a definition and corresponding identifier
|
||||
$definition = new PersonIdentifierDefinition(label: ['en' => 'Any'], engine: 'any.engine');
|
||||
$identifier = new PersonIdentifier($definition);
|
||||
|
||||
// Create an engine prophecy; we only care that validate() is called once with expected args
|
||||
$engineProphecy = $this->prophesize(\Chill\PersonBundle\PersonIdentifier\PersonIdentifierEngineInterface::class);
|
||||
$engineProphecy
|
||||
->validate($this->context, $identifier, $definition)
|
||||
->shouldBeCalled();
|
||||
|
||||
// Build a real worker that wraps our mocked engine and the concrete definition
|
||||
$worker = new PersonIdentifierWorker($engineProphecy->reveal(), $definition);
|
||||
|
||||
// Configure the manager to return our worker for this definition
|
||||
$this->managerProphecy
|
||||
->buildWorkerByPersonIdentifierDefinition($definition)
|
||||
->willReturn($worker);
|
||||
|
||||
// Act: run the validator
|
||||
$this->validator->validate($identifier, new ValidIdentifierConstraint());
|
||||
|
||||
// Assert: no explicit assertion needed; Prophecy will fail if method wasn't called
|
||||
$this->assertNoViolation();
|
||||
}
|
||||
}
|
@@ -25,6 +25,7 @@ use libphonenumber\PhoneNumber;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
|
||||
use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;
|
||||
use Symfony\Component\Validator\Context\ExecutionContextInterface;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
@@ -79,6 +80,8 @@ final class PersonJsonDenormalizerTest extends TestCase
|
||||
|
||||
return '' === $content;
|
||||
}
|
||||
|
||||
public function validate(ExecutionContextInterface $context, PersonIdentifier $identifier, PersonIdentifierDefinition $definition): void {}
|
||||
};
|
||||
|
||||
return new PersonIdentifierWorker($engine, $definition);
|
||||
|
@@ -0,0 +1,7 @@
|
||||
person_identifier:
|
||||
fixed_length: >-
|
||||
{limit, plural,
|
||||
=1 {L'identifier doit contenir exactement 1 caractère}
|
||||
other {L'identifiant doit contenir exactement # caractères}
|
||||
}
|
||||
only_number: "L'identifiant ne doit contenir que des chiffres"
|
Reference in New Issue
Block a user