Add external identifiers for person, editable in edit form, with minimal features associated

This commit is contained in:
2025-09-01 08:05:11 +00:00
parent 76433e2512
commit ea06a96f91
40 changed files with 1274 additions and 128 deletions

View File

@@ -0,0 +1,145 @@
<?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\Rendering;
use Chill\PersonBundle\Entity\Identifier\PersonIdentifier;
use Chill\PersonBundle\Entity\Identifier\PersonIdentifierDefinition;
use Chill\PersonBundle\Entity\Person;
use Chill\PersonBundle\PersonIdentifier\Identifier\StringIdentifier;
use Chill\PersonBundle\PersonIdentifier\PersonIdentifierEngineInterface;
use Chill\PersonBundle\PersonIdentifier\PersonIdentifierManager;
use Chill\PersonBundle\PersonIdentifier\PersonIdentifierManagerInterface;
use Chill\PersonBundle\PersonIdentifier\PersonIdentifierWorker;
use Chill\PersonBundle\PersonIdentifier\Rendering\PersonIdRendering;
use PHPUnit\Framework\TestCase;
use Prophecy\Argument;
use Prophecy\PhpUnit\ProphecyTrait;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
/**
* @internal
*
* @coversNothing
*/
class PersonIdRenderingTest extends TestCase
{
use ProphecyTrait;
/**
* @dataProvider provideRenderCases
*/
public function testRenderPersonId(Person $person, string $idContentText, string $expected): void
{
// Parameter bag mock returning the provided id_content_text
$parameterBag = $this->prophesize(ParameterBagInterface::class);
$parameterBag->get('chill_person')
->willReturn(['person_render' => ['id_content_text' => $idContentText]]);
// PersonIdentifierManager is explicitly requested to be mocked in the spec.
// It will return a PersonIdentifierWorker whose renderAsString behaves like StringIdentifier::renderAsString
$personIdentifierManager = $this->prophesize(PersonIdentifierManagerInterface::class);
$personIdentifierManager
->buildWorkerByPersonIdentifierDefinition(Argument::type(PersonIdentifierDefinition::class))
->will(function ($args) {
/** @var PersonIdentifierDefinition $definition */
$definition = $args[0];
$engine = new class () implements PersonIdentifierEngineInterface {
public static function getName(): string
{
return 'test';
}
public function canonicalizeValue(array $value, PersonIdentifierDefinition $definition): ?string
{
return $value['content'] ?? '';
}
public function buildForm(\Symfony\Component\Form\FormBuilderInterface $builder, PersonIdentifierDefinition $personIdentifierDefinition): void {}
public function renderAsString(?PersonIdentifier $identifier, PersonIdentifierDefinition $definition): string
{
// same behavior as StringIdentifier::renderAsString
return $identifier?->getValue()['content'] ?? '';
}
};
return new PersonIdentifierWorker($engine, $definition);
});
$service = new PersonIdRendering($parameterBag->reveal(), $personIdentifierManager->reveal());
self::assertSame($expected, $service->renderPersonId($person));
}
public function provideRenderCases(): iterable
{
// Case 1: one active identifier, one inactive identifier, should render person id and only active identifier
$person1 = new Person();
$this->setEntityId($person1, 123);
$defActive = new PersonIdentifierDefinition(label: ['en' => 'Active'], engine: 'string');
$this->setEntityId($defActive, 10);
$defActive->setActive(true);
$idActive = new PersonIdentifier($defActive);
$idActive->setPerson($person1);
$idActive->setValue(['content' => 'ABC']);
$person1->addIdentifier($idActive);
$defInactive = new PersonIdentifierDefinition(label: ['en' => 'Inactive'], engine: 'string');
$this->setEntityId($defInactive, 99);
$defInactive->setActive(false);
$idInactive = new PersonIdentifier($defInactive);
$idInactive->setPerson($person1);
$idInactive->setValue(['content' => 'SHOULD_NOT_APPEAR']);
$person1->addIdentifier($idInactive);
$template1 = 'ID: [[ person_id ]] - Active: [[ identifier_10 ]] - Inactive: [[ identifier_99 ]]';
$expected1 = 'ID: 123 - Active: ABC - Inactive: [[ identifier_99 ]]';
yield
'with active and inactive identifiers' => [$person1, $template1, $expected1]
;
$template2 = 'ID: [[ person_id ]][[ if:identifier_10 ]] - Active: [[ identifier_10 ]][[ endif:identifier_10 ]]';
$expected2 = 'ID: 123 - Active: ABC';
yield
'rendering with conditional: condition are removed' => [$person1, $template2, $expected2]
;
$template3 = 'ID: [[ person_id ]][[ if:identifier_99 ]] - Inactive: [[ identifier_10 ]][[ endif:identifier_99 ]]';
$expected3 = 'ID: 123';
yield
'rendering with conditional: the content between condition is removed' => [$person1, $template3, $expected3]
;
$template4 = 'ID: [[ person_id ]][[ if:identifier_105 ]] - not present: [[ identifier_105 ]][[ endif:identifier_105 ]]';
$expected4 = 'ID: 123';
yield
'rendering with conditional: the content between condition is removed, the identifier is not associated with the person' => [$person1, $template4, $expected4]
;
}
private function setEntityId(object $entity, int $id): void
{
$refl = new \ReflectionClass($entity);
$prop = $refl->getProperty('id');
$prop->setAccessible(true);
$prop->setValue($entity, $id);
}
}