mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-09-27 00:55:01 +00:00
Add validation and support for identifiers
in PersonJsonDenormalizer
, enhance altNames
handling, and update tests for improved coverage. Adjust PersonIdentifierManager
to handle identifier definitions by ID.
This commit is contained in:
@@ -11,11 +11,218 @@ declare(strict_types=1);
|
||||
|
||||
namespace Chill\PersonBundle\Tests\Serializer\Normalizer;
|
||||
|
||||
use Chill\MainBundle\Entity\Center;
|
||||
use Chill\MainBundle\Entity\Civility;
|
||||
use Chill\MainBundle\Entity\Gender;
|
||||
use Chill\PersonBundle\Entity\Identifier\PersonIdentifierDefinition;
|
||||
use Chill\PersonBundle\Entity\Person;
|
||||
use Chill\PersonBundle\PersonIdentifier\PersonIdentifierEngineInterface;
|
||||
use Chill\PersonBundle\PersonIdentifier\PersonIdentifierManagerInterface;
|
||||
use Chill\PersonBundle\PersonIdentifier\PersonIdentifierWorker;
|
||||
use Chill\PersonBundle\Serializer\Normalizer\PersonJsonDenormalizer;
|
||||
use libphonenumber\PhoneNumber;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @coversNothing
|
||||
* @covers \Chill\PersonBundle\Serializer\Normalizer\PersonJsonDenormalizer
|
||||
*/
|
||||
class PersonJsonDenormalizerTest extends TestCase {}
|
||||
final class PersonJsonDenormalizerTest extends TestCase
|
||||
{
|
||||
private function createIdentifierManager(): PersonIdentifierManagerInterface
|
||||
{
|
||||
return new class () implements PersonIdentifierManagerInterface {
|
||||
public function getWorkers(): array
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
public function buildWorkerByPersonIdentifierDefinition(int|PersonIdentifierDefinition $personIdentifierDefinition): PersonIdentifierWorker
|
||||
{
|
||||
if (is_int($personIdentifierDefinition)) {
|
||||
$definition = new PersonIdentifierDefinition(['en' => 'Test'], 'dummy');
|
||||
// Force the id for testing purposes
|
||||
$r = new \ReflectionProperty(PersonIdentifierDefinition::class, 'id');
|
||||
$r->setAccessible(true);
|
||||
$r->setValue($definition, $personIdentifierDefinition);
|
||||
} else {
|
||||
$definition = $personIdentifierDefinition;
|
||||
}
|
||||
|
||||
$engine = new class () implements PersonIdentifierEngineInterface {
|
||||
public static function getName(): string
|
||||
{
|
||||
return 'dummy';
|
||||
}
|
||||
|
||||
public function canonicalizeValue(array $value, PersonIdentifierDefinition $definition): ?string
|
||||
{
|
||||
// trivial canonicalization for tests
|
||||
return isset($value['content']) ? (string) $value['content'] : null;
|
||||
}
|
||||
|
||||
public function buildForm(\Symfony\Component\Form\FormBuilderInterface $builder, PersonIdentifierDefinition $personIdentifierDefinition): void {}
|
||||
|
||||
public function renderAsString(?\Chill\PersonBundle\Entity\Identifier\PersonIdentifier $identifier, PersonIdentifierDefinition $definition): string
|
||||
{
|
||||
return '';
|
||||
}
|
||||
};
|
||||
|
||||
return new PersonIdentifierWorker($engine, $definition);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public function testSupportsDenormalizationReturnsTrueForValidData(): void
|
||||
{
|
||||
$denormalizer = new PersonJsonDenormalizer($this->createIdentifierManager());
|
||||
|
||||
$data = [
|
||||
'type' => 'person',
|
||||
// important: new Person (creation) must not contain an id
|
||||
];
|
||||
|
||||
self::assertTrue($denormalizer->supportsDenormalization($data, Person::class));
|
||||
}
|
||||
|
||||
public function testSupportsDenormalizationReturnsFalseForInvalidData(): void
|
||||
{
|
||||
$denormalizer = new PersonJsonDenormalizer($this->createIdentifierManager());
|
||||
|
||||
// not an array
|
||||
self::assertFalse($denormalizer->supportsDenormalization('not-an-array', Person::class));
|
||||
|
||||
// missing type
|
||||
self::assertFalse($denormalizer->supportsDenormalization([], Person::class));
|
||||
|
||||
// wrong type value
|
||||
self::assertFalse($denormalizer->supportsDenormalization(['type' => 'not-person'], Person::class));
|
||||
|
||||
// id present means it's not a create payload for this denormalizer
|
||||
self::assertFalse($denormalizer->supportsDenormalization(['type' => 'person', 'id' => 123], Person::class));
|
||||
|
||||
// wrong target class
|
||||
self::assertFalse($denormalizer->supportsDenormalization(['type' => 'person'], \stdClass::class));
|
||||
}
|
||||
|
||||
public function testDenormalizeMapsPayloadToPersonProperties(): void
|
||||
{
|
||||
$json = <<<'JSON'
|
||||
{
|
||||
"type": "person",
|
||||
"firstName": "Jérome",
|
||||
"lastName": "diallo",
|
||||
"altNames": [
|
||||
{
|
||||
"key": "jeune_fille",
|
||||
"value": "FJ"
|
||||
}
|
||||
],
|
||||
"birthdate": null,
|
||||
"deathdate": null,
|
||||
"phonenumber": "",
|
||||
"mobilenumber": "",
|
||||
"email": "",
|
||||
"gender": {
|
||||
"id": 5,
|
||||
"type": "chill_main_gender"
|
||||
},
|
||||
"center": {
|
||||
"id": 1,
|
||||
"type": "center"
|
||||
},
|
||||
"civility": null,
|
||||
"identifiers": [
|
||||
{
|
||||
"type": "person_identifier",
|
||||
"value": {
|
||||
"content": "789456"
|
||||
},
|
||||
"definition_id": 5
|
||||
}
|
||||
]
|
||||
}
|
||||
JSON;
|
||||
$data = json_decode($json, true, 512, JSON_THROW_ON_ERROR);
|
||||
|
||||
$inner = new class () implements DenormalizerInterface {
|
||||
public ?Gender $gender = null;
|
||||
public ?Center $center = null;
|
||||
|
||||
public function denormalize($data, $type, $format = null, array $context = [])
|
||||
{
|
||||
if (PhoneNumber::class === $type) {
|
||||
return '' === $data ? null : new PhoneNumber();
|
||||
}
|
||||
if (\DateTime::class === $type || \DateTimeImmutable::class === $type) {
|
||||
return null === $data ? null : new \DateTimeImmutable((string) $data);
|
||||
}
|
||||
if (Gender::class === $type) {
|
||||
return $this->gender ??= new Gender();
|
||||
}
|
||||
if (Center::class === $type) {
|
||||
return $this->center ??= new Center();
|
||||
}
|
||||
if (Civility::class === $type) {
|
||||
return null; // input is null in our payload
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function supportsDenormalization($data, $type, $format = null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
$denormalizer = new PersonJsonDenormalizer($this->createIdentifierManager());
|
||||
$denormalizer->setDenormalizer($inner);
|
||||
|
||||
$person = $denormalizer->denormalize($data, Person::class);
|
||||
|
||||
self::assertInstanceOf(Person::class, $person);
|
||||
self::assertSame('Jérome', $person->getFirstName());
|
||||
self::assertSame('diallo', $person->getLastName());
|
||||
|
||||
// phone numbers: empty strings map to null via the inner denormalizer stub
|
||||
self::assertNull($person->getPhonenumber());
|
||||
self::assertNull($person->getMobilenumber());
|
||||
|
||||
// email passes through as is
|
||||
self::assertSame('', $person->getEmail());
|
||||
|
||||
// nested objects are provided by our inner denormalizer and must be set back on the Person
|
||||
self::assertSame($inner->gender, $person->getGender());
|
||||
self::assertSame($inner->center, $person->getCenter());
|
||||
|
||||
// dates are null in the provided payload
|
||||
self::assertNull($person->getBirthdate());
|
||||
self::assertNull($person->getDeathdate());
|
||||
|
||||
// civility is null as provided
|
||||
self::assertNull($person->getCivility());
|
||||
|
||||
// altNames: make sure the alt name with key jeune_fille has label FJ
|
||||
$found = false;
|
||||
foreach ($person->getAltNames() as $altName) {
|
||||
if ('jeune_fille' === $altName->getKey()) {
|
||||
$found = true;
|
||||
self::assertSame('FJ', $altName->getLabel());
|
||||
}
|
||||
}
|
||||
self::assertTrue($found, 'Expected altNames to contain key "jeune_fille"');
|
||||
|
||||
$found = false;
|
||||
foreach ($person->getIdentifiers() as $identifier) {
|
||||
if (5 === $identifier->getDefinition()->getId()) {
|
||||
$found = true;
|
||||
self::assertSame(['content' => '789456'], $identifier->getValue());
|
||||
}
|
||||
}
|
||||
self::assertTrue($found, 'Expected identifiers with definition id 5');
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user