Skip to content

Commit

Permalink
fix setting validated fields not using the options array
Browse files Browse the repository at this point in the history
  • Loading branch information
xabbuh committed May 3, 2024
1 parent f87efa1 commit d19dfaf
Show file tree
Hide file tree
Showing 2 changed files with 241 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -951,6 +951,40 @@ public function rewind(): void
}

public function testValidateDTOUniqueness()
{
$constraint = new UniqueEntity(
message: 'myMessage',
fields: ['name'],
em: self::EM_NAME,
entityClass: Person::class,
);

$entity = new Person(1, 'Foo');
$dto = new HireAnEmployee('Foo');

$this->validator->validate($entity, $constraint);

$this->assertNoViolation();

$this->em->persist($entity);
$this->em->flush();

$this->validator->validate($entity, $constraint);

$this->assertNoViolation();

$this->validator->validate($dto, $constraint);

$this->buildViolation('myMessage')
->atPath('property.path.name')
->setInvalidValue('Foo')
->setCode(UniqueEntity::NOT_UNIQUE_ERROR)
->setCause([$entity])
->setParameters(['{{ value }}' => '"Foo"'])
->assertRaised();
}

public function testValidateDTOUniquenessDoctrineStyle()
{
$constraint = new UniqueEntity([
'message' => 'myMessage',
Expand Down Expand Up @@ -985,6 +1019,32 @@ public function testValidateDTOUniqueness()
}

public function testValidateMappingOfFieldNames()
{
$constraint = new UniqueEntity(
message: 'myMessage',
fields: ['primaryName' => 'name', 'secondaryName' => 'name2'],
em: self::EM_NAME,
entityClass: DoubleNameEntity::class,
);

$entity = new DoubleNameEntity(1, 'Foo', 'Bar');
$dto = new CreateDoubleNameEntity('Foo', 'Bar');

$this->em->persist($entity);
$this->em->flush();

$this->validator->validate($dto, $constraint);

$this->buildViolation('myMessage')
->atPath('property.path.name')
->setParameter('{{ value }}', '"Foo"')
->setInvalidValue('Foo')
->setCause([$entity])
->setCode(UniqueEntity::NOT_UNIQUE_ERROR)
->assertRaised();
}

public function testValidateMappingOfFieldNamesDoctrineStyle()
{
$constraint = new UniqueEntity([
'message' => 'myMessage',
Expand All @@ -1011,6 +1071,21 @@ public function testValidateMappingOfFieldNames()
}

public function testInvalidateDTOFieldName()
{
$this->expectException(ConstraintDefinitionException::class);
$this->expectExceptionMessage('The field "primaryName" is not a property of class "Symfony\Bridge\Doctrine\Tests\Fixtures\HireAnEmployee".');
$constraint = new UniqueEntity(
message: 'myMessage',
fields: ['primaryName' => 'name'],
em: self::EM_NAME,
entityClass: SingleStringIdEntity::class,
);

$dto = new HireAnEmployee('Foo');
$this->validator->validate($dto, $constraint);
}

public function testInvalidateDTOFieldNameDoctrineStyle()
{
$this->expectException(ConstraintDefinitionException::class);
$this->expectExceptionMessage('The field "primaryName" is not a property of class "Symfony\Bridge\Doctrine\Tests\Fixtures\HireAnEmployee".');
Expand All @@ -1026,6 +1101,21 @@ public function testInvalidateDTOFieldName()
}

public function testInvalidateEntityFieldName()
{
$this->expectException(ConstraintDefinitionException::class);
$this->expectExceptionMessage('The field "name2" is not mapped by Doctrine, so it cannot be validated for uniqueness.');
$constraint = new UniqueEntity(
message: 'myMessage',
fields: ['name2'],
em: self::EM_NAME,
entityClass: SingleStringIdEntity::class,
);

$dto = new HireAnEmployee('Foo');
$this->validator->validate($dto, $constraint);
}

public function testInvalidateEntityFieldNameDoctrineStyle()
{
$this->expectException(ConstraintDefinitionException::class);
$this->expectExceptionMessage('The field "name2" is not mapped by Doctrine, so it cannot be validated for uniqueness.');
Expand All @@ -1041,6 +1131,36 @@ public function testInvalidateEntityFieldName()
}

public function testValidateDTOUniquenessWhenUpdatingEntity()
{
$constraint = new UniqueEntity(
message: 'myMessage',
fields: ['name'],
em: self::EM_NAME,
entityClass: Person::class,
identifierFieldNames: ['id'],
);

$entity1 = new Person(1, 'Foo');
$entity2 = new Person(2, 'Bar');

$this->em->persist($entity1);
$this->em->persist($entity2);
$this->em->flush();

$dto = new UpdateEmployeeProfile(2, 'Foo');

$this->validator->validate($dto, $constraint);

$this->buildViolation('myMessage')
->atPath('property.path.name')
->setInvalidValue('Foo')
->setCode(UniqueEntity::NOT_UNIQUE_ERROR)
->setCause([$entity1])
->setParameters(['{{ value }}' => '"Foo"'])
->assertRaised();
}

public function testValidateDTOUniquenessWhenUpdatingEntityDoctrineStyle()
{
$constraint = new UniqueEntity([
'message' => 'myMessage',
Expand Down Expand Up @@ -1071,6 +1191,28 @@ public function testValidateDTOUniquenessWhenUpdatingEntity()
}

public function testValidateDTOUniquenessWhenUpdatingEntityWithTheSameValue()
{
$constraint = new UniqueEntity(
message: 'myMessage',
fields: ['name'],
em: self::EM_NAME,
entityClass: CompositeIntIdEntity::class,
identifierFieldNames: ['id1', 'id2'],
);

$entity = new CompositeIntIdEntity(1, 2, 'Foo');

$this->em->persist($entity);
$this->em->flush();

$dto = new UpdateCompositeIntIdEntity(1, 2, 'Foo');

$this->validator->validate($dto, $constraint);

$this->assertNoViolation();
}

public function testValidateDTOUniquenessWhenUpdatingEntityWithTheSameValueDoctrineStyle()
{
$constraint = new UniqueEntity([
'message' => 'myMessage',
Expand All @@ -1093,6 +1235,35 @@ public function testValidateDTOUniquenessWhenUpdatingEntityWithTheSameValue()
}

public function testValidateIdentifierMappingOfFieldNames()
{
$constraint = new UniqueEntity(
message: 'myMessage',
fields: ['object1' => 'objectOne', 'object2' => 'objectTwo'],
em: self::EM_NAME,
entityClass: CompositeObjectNoToStringIdEntity::class,
identifierFieldNames: ['object1' => 'objectOne', 'object2' => 'objectTwo'],
);

$objectOne = new SingleIntIdNoToStringEntity(1, 'foo');
$objectTwo = new SingleIntIdNoToStringEntity(2, 'bar');

$this->em->persist($objectOne);
$this->em->persist($objectTwo);
$this->em->flush();

$entity = new CompositeObjectNoToStringIdEntity($objectOne, $objectTwo);

$this->em->persist($entity);
$this->em->flush();

$dto = new UpdateCompositeObjectNoToStringIdEntity($objectOne, $objectTwo, 'Foo');

$this->validator->validate($dto, $constraint);

$this->assertNoViolation();
}

public function testValidateIdentifierMappingOfFieldNamesDoctrineStyle()
{
$constraint = new UniqueEntity([
'message' => 'myMessage',
Expand Down Expand Up @@ -1122,6 +1293,34 @@ public function testValidateIdentifierMappingOfFieldNames()
}

public function testInvalidateMissingIdentifierFieldName()
{
$this->expectException(ConstraintDefinitionException::class);
$this->expectExceptionMessage('The "Symfony\Bridge\Doctrine\Tests\Fixtures\CompositeObjectNoToStringIdEntity" entity identifier field names should be "objectOne, objectTwo", not "objectTwo".');
$constraint = new UniqueEntity(
message: 'myMessage',
fields: ['object1' => 'objectOne', 'object2' => 'objectTwo'],
em: self::EM_NAME,
entityClass: CompositeObjectNoToStringIdEntity::class,
identifierFieldNames: ['object2' => 'objectTwo'],
);

$objectOne = new SingleIntIdNoToStringEntity(1, 'foo');
$objectTwo = new SingleIntIdNoToStringEntity(2, 'bar');

$this->em->persist($objectOne);
$this->em->persist($objectTwo);
$this->em->flush();

$entity = new CompositeObjectNoToStringIdEntity($objectOne, $objectTwo);

$this->em->persist($entity);
$this->em->flush();

$dto = new UpdateCompositeObjectNoToStringIdEntity($objectOne, $objectTwo, 'Foo');
$this->validator->validate($dto, $constraint);
}

public function testInvalidateMissingIdentifierFieldNameDoctrineStyle()
{
$this->expectException(ConstraintDefinitionException::class);
$this->expectExceptionMessage('The "Symfony\Bridge\Doctrine\Tests\Fixtures\CompositeObjectNoToStringIdEntity" entity identifier field names should be "objectOne, objectTwo", not "objectTwo".');
Expand Down Expand Up @@ -1150,6 +1349,25 @@ public function testInvalidateMissingIdentifierFieldName()
}

public function testUninitializedValueThrowException()
{
$this->expectExceptionMessage('Typed property Symfony\Bridge\Doctrine\Tests\Fixtures\Dto::$foo must not be accessed before initialization');
$constraint = new UniqueEntity(
message: 'myMessage',
fields: ['foo' => 'name'],
em: self::EM_NAME,
entityClass: DoubleNameEntity::class,
);

$entity = new DoubleNameEntity(1, 'Foo', 'Bar');
$dto = new Dto();

$this->em->persist($entity);
$this->em->flush();

$this->validator->validate($dto, $constraint);
}

public function testUninitializedValueThrowExceptionDoctrineStyle()
{
$this->expectExceptionMessage('Typed property Symfony\Bridge\Doctrine\Tests\Fixtures\Dto::$foo must not be accessed before initialization');
$constraint = new UniqueEntity([
Expand All @@ -1169,6 +1387,27 @@ public function testUninitializedValueThrowException()
}

public function testEntityManagerNullObjectWhenDTO()
{
$this->expectException(ConstraintDefinitionException::class);
$this->expectExceptionMessage('Unable to find the object manager associated with an entity of class "Symfony\Bridge\Doctrine\Tests\Fixtures\Person"');
$constraint = new UniqueEntity(
message: 'myMessage',
fields: ['name'],
entityClass: Person::class,
// no "em" option set
);

$this->em = null;
$this->registry = $this->createRegistryMock($this->em);
$this->validator = $this->createValidator();
$this->validator->initialize($this->context);

$dto = new HireAnEmployee('Foo');

$this->validator->validate($dto, $constraint);
}

public function testEntityManagerNullObjectWhenDTODoctrineStyle()
{
$this->expectException(ConstraintDefinitionException::class);
$this->expectExceptionMessage('Unable to find the object manager associated with an entity of class "Symfony\Bridge\Doctrine\Tests\Fixtures\Person"');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,9 @@ public function __construct(
$payload = null,
array $options = [],
) {
if (\is_array($fields) && \is_string(key($fields))) {
if (\is_array($fields) && \is_string(key($fields)) && [] === array_diff(array_keys($fields), array_keys(get_class_vars(static::class)))) {
$options = array_merge($fields, $options);
} elseif (null !== $fields) {
} else {
$options['fields'] = $fields;
}

Expand Down

0 comments on commit d19dfaf

Please sign in to comment.