mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-10-06 21:39:42 +00:00
Add validation logic and tests for StringIdentifier
- Implemented `validate` method in `StringIdentifier` to enforce `only_numbers` and `fixed_length` constraints. - Created `StringIdentifierValidationTest` to cover validation rules.
This commit is contained in:
@@ -16,11 +16,15 @@ use Chill\PersonBundle\Entity\Identifier\PersonIdentifierDefinition;
|
||||
use Chill\PersonBundle\PersonIdentifier\PersonIdentifierEngineInterface;
|
||||
use Symfony\Component\Form\Extension\Core\Type\TextType;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Component\Validator\Context\ExecutionContextInterface;
|
||||
|
||||
final readonly class StringIdentifier implements PersonIdentifierEngineInterface
|
||||
{
|
||||
public const NAME = 'chill-person-bundle.string-identifier';
|
||||
|
||||
private const ONLY_NUMBERS = 'only_numbers';
|
||||
private const FIXED_LENGTH = 'fixed_length';
|
||||
|
||||
public static function getName(): string
|
||||
{
|
||||
return self::NAME;
|
||||
@@ -45,4 +49,21 @@ final readonly class StringIdentifier implements PersonIdentifierEngineInterface
|
||||
{
|
||||
return '' === trim($identifier->getValue()['content'] ?? '');
|
||||
}
|
||||
|
||||
public function validate(ExecutionContextInterface $context, PersonIdentifier $identifier, PersonIdentifierDefinition $definition): void
|
||||
{
|
||||
$config = $definition->getData();
|
||||
$content = (string) ($identifier->getValue()['content'] ?? '');
|
||||
|
||||
if (($config[self::ONLY_NUMBERS] ?? false) && !preg_match('/^[0-9]+$/', $content)) {
|
||||
$context->buildViolation('person_identifier.only_number')
|
||||
->addViolation();
|
||||
}
|
||||
|
||||
if (null !== ($config[self::FIXED_LENGTH] ?? null) && strlen($content) !== $config[self::FIXED_LENGTH]) {
|
||||
$context->buildViolation('person_identifier.fixed_length')
|
||||
->setParameter('limit', (string) $config[self::FIXED_LENGTH])
|
||||
->addViolation();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,128 @@
|
||||
<?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\Identifier;
|
||||
|
||||
use Chill\PersonBundle\Entity\Identifier\PersonIdentifier;
|
||||
use Chill\PersonBundle\Entity\Identifier\PersonIdentifierDefinition;
|
||||
use Chill\PersonBundle\PersonIdentifier\Identifier\StringIdentifier;
|
||||
use PHPUnit\Framework\MockObject\MockObject;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Symfony\Component\Validator\Context\ExecutionContextInterface;
|
||||
use Symfony\Component\Validator\Violation\ConstraintViolationBuilderInterface;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @coversNothing
|
||||
*/
|
||||
class StringIdentifierValidationTest extends TestCase
|
||||
{
|
||||
private function makeDefinition(array $data = []): PersonIdentifierDefinition
|
||||
{
|
||||
return new PersonIdentifierDefinition(label: ['en' => 'String'], engine: StringIdentifier::getName(), data: $data);
|
||||
}
|
||||
|
||||
private function makeIdentifier(PersonIdentifierDefinition $definition, string $content): PersonIdentifier
|
||||
{
|
||||
$identifier = new PersonIdentifier($definition);
|
||||
$identifier->setValue(['content' => $content]);
|
||||
|
||||
return $identifier;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper creating a context mock expecting zero violations.
|
||||
*/
|
||||
private function expectNoViolation(): ExecutionContextInterface
|
||||
{
|
||||
$context = $this->createMock(ExecutionContextInterface::class);
|
||||
$context->expects(self::never())->method('buildViolation');
|
||||
|
||||
return $context;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper creating a context mock expecting a single violation with a given message and optional parameters chain.
|
||||
*/
|
||||
private function expectSingleViolation(string $message, array $parameters = []): ExecutionContextInterface
|
||||
{
|
||||
/** @var ConstraintViolationBuilderInterface&MockObject $builder */
|
||||
$builder = $this->createMock(ConstraintViolationBuilderInterface::class);
|
||||
|
||||
// If parameters are provided, ensure setParameter is called with each, in any order, and returns builder for chaining
|
||||
if ($parameters) {
|
||||
foreach ($parameters as $name => $value) {
|
||||
$builder->expects(self::atLeastOnce())
|
||||
->method('setParameter')
|
||||
->with($name, $value)
|
||||
->willReturn($builder);
|
||||
}
|
||||
} else {
|
||||
$builder->expects(self::any())->method('setParameter')->willReturn($builder);
|
||||
}
|
||||
|
||||
$builder->expects(self::once())->method('addViolation');
|
||||
|
||||
$context = $this->createMock(ExecutionContextInterface::class);
|
||||
$context->expects(self::once())
|
||||
->method('buildViolation')
|
||||
->with($message)
|
||||
->willReturn($builder);
|
||||
|
||||
return $context;
|
||||
}
|
||||
|
||||
public function testNoOptionsAcceptsAnyString(): void
|
||||
{
|
||||
$engine = new StringIdentifier();
|
||||
$definition = $this->makeDefinition([]);
|
||||
$identifier = $this->makeIdentifier($definition, 'abc123');
|
||||
|
||||
$engine->validate($this->expectNoViolation(), $identifier, $definition);
|
||||
}
|
||||
|
||||
public function testOnlyNumbersValid(): void
|
||||
{
|
||||
$engine = new StringIdentifier();
|
||||
$definition = $this->makeDefinition(['only_numbers' => true]);
|
||||
$identifier = $this->makeIdentifier($definition, '123456');
|
||||
|
||||
$engine->validate($this->expectNoViolation(), $identifier, $definition);
|
||||
}
|
||||
|
||||
public function testOnlyNumbersInvalid(): void
|
||||
{
|
||||
$engine = new StringIdentifier();
|
||||
$definition = $this->makeDefinition(['only_numbers' => true]);
|
||||
$identifier = $this->makeIdentifier($definition, '12AB');
|
||||
|
||||
$engine->validate($this->expectSingleViolation('person_identifier.only_number'), $identifier, $definition);
|
||||
}
|
||||
|
||||
public function testFixedLengthValid(): void
|
||||
{
|
||||
$engine = new StringIdentifier();
|
||||
$definition = $this->makeDefinition(['fixed_length' => 5]);
|
||||
$identifier = $this->makeIdentifier($definition, '12345');
|
||||
|
||||
$engine->validate($this->expectNoViolation(), $identifier, $definition);
|
||||
}
|
||||
|
||||
public function testFixedLengthInvalid(): void
|
||||
{
|
||||
$engine = new StringIdentifier();
|
||||
$definition = $this->makeDefinition(['fixed_length' => 5]);
|
||||
$identifier = $this->makeIdentifier($definition, '1234');
|
||||
|
||||
$engine->validate($this->expectSingleViolation('person_identifier.fixed_length', ['limit' => 5]), $identifier, $definition);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user