requiredDefinition = new PersonIdentifierDefinition( label: ['fr' => 'Identifiant requis'], engine: 'test.engine', ); $this->requiredDefinition->setPresence(IdentifierPresenceEnum::REQUIRED); $reflection = new \ReflectionClass($this->requiredDefinition); $id = $reflection->getProperty('id'); $id->setValue($this->requiredDefinition, 1); // Mock only the required methods of the engine used by the validator through the worker $engineProphecy = $this->prophesize(PersonIdentifierEngineInterface::class); $engineProphecy->isEmpty(Argument::type(PersonIdentifier::class)) ->will(function (array $args): bool { /** @var PersonIdentifier $identifier */ $identifier = $args[0]; return '' === trim($identifier->getValue()['content'] ?? ''); }); $engineProphecy->renderAsString(Argument::any(), Argument::any()) ->will(function (array $args): string { /** @var PersonIdentifier|null $identifier */ $identifier = $args[0] ?? null; return $identifier?->getValue()['content'] ?? ''; }); $worker = new PersonIdentifierWorker($engineProphecy->reveal(), $this->requiredDefinition); // Mock only the required method used by the validator $managerProphecy = $this->prophesize(PersonIdentifierManagerInterface::class); $managerProphecy->getWorkers()->willReturn([$worker]); return new RequiredIdentifierConstraintValidator($managerProphecy->reveal()); } public function testThrowsOnNonCollectionValue(): void { $this->expectException(UnexpectedValueException::class); $this->validator->validate(new \stdClass(), new RequiredIdentifierConstraint()); } public function testThrowsOnInvalidConstraintType(): void { $this->expectException(UnexpectedTypeException::class); // Provide a valid Collection value so the type check reaches the constraint check $this->validator->validate(new ArrayCollection(), new NotBlank()); } public function testNoViolationWhenRequiredIdentifierPresentAndNotEmpty(): void { $identifier = new PersonIdentifier($this->requiredDefinition); $identifier->setValue(['content' => 'ABC']); $collection = new ArrayCollection([$identifier]); $this->validator->validate($collection, new RequiredIdentifierConstraint()); $this->assertNoViolation(); } public function testViolationWhenRequiredIdentifierMissing(): void { $collection = new ArrayCollection(); $this->validator->validate($collection, new RequiredIdentifierConstraint()); $this->buildViolation('This identifier must be set') ->atPath('property.path.identifiers') ->setParameter('{{ value }}', '') ->setParameter('definition_id', '1') ->setCode('c08b7b32-947f-11f0-8608-9b8560e9bf05') ->assertRaised(); } public function testViolationWhenRequiredIdentifierIsEmpty(): void { $identifier = new PersonIdentifier($this->requiredDefinition); $identifier->setValue(['content' => ' ']); $collection = new ArrayCollection([$identifier]); $this->validator->validate($collection, new RequiredIdentifierConstraint()); $this->buildViolation('This identifier must be set') ->atPath('property.path.identifiers') ->setParameter('{{ value }}', ' ') ->setParameter('definition_id', '1') ->setCode('c08b7b32-947f-11f0-8608-9b8560e9bf05') ->assertRaised(); } }