Skip to content

Commit

Permalink
[Serializer] Fix denormalizing custom class in UidNormalizer
Browse files Browse the repository at this point in the history
  • Loading branch information
fancyweb committed Dec 13, 2021
1 parent ad2b1c2 commit 5e409f0
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 8 deletions.
9 changes: 7 additions & 2 deletions Normalizer/UidNormalizer.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
use Symfony\Component\Serializer\Exception\LogicException;
use Symfony\Component\Serializer\Exception\NotNormalizableValueException;
use Symfony\Component\Uid\AbstractUid;
use Symfony\Component\Uid\Ulid;
use Symfony\Component\Uid\Uuid;

final class UidNormalizer implements NormalizerInterface, DenormalizerInterface, CacheableSupportsMethodInterface
Expand Down Expand Up @@ -70,9 +69,15 @@ public function supportsNormalization($data, string $format = null)
public function denormalize($data, string $type, string $format = null, array $context = [])
{
try {
return Ulid::class === $type ? Ulid::fromString($data) : Uuid::fromString($data);
return AbstractUid::class !== $type ? $type::fromString($data) : Uuid::fromString($data);
} catch (\InvalidArgumentException $exception) {
throw new NotNormalizableValueException(sprintf('The data is not a valid "%s" string representation.', $type));
} catch (\Error $e) {
if (str_starts_with($e->getMessage(), 'Cannot instantiate abstract class')) {
return $this->denormalize($data, AbstractUid::class, $format, $context);
}

throw $e;
}
}

Expand Down
36 changes: 30 additions & 6 deletions Tests/Normalizer/UidNormalizerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -116,8 +116,8 @@ public function dataProvider()
['4126dbc1-488e-4f6e-aadd-775dcbac482e', UuidV4::class],
['18cdf3d3-ea1b-5b23-a9c5-40abd0e2df22', UuidV5::class],
['1ea6ecef-eb9a-66fe-b62b-957b45f17e43', UuidV6::class],
['1ea6ecef-eb9a-66fe-b62b-957b45f17e43', AbstractUid::class],
['01E4BYF64YZ97MDV6RH0HAMN6X', Ulid::class],
['01FPT3YXZXJ1J437FES7CR5BCB', TestCustomUid::class],
];
}

Expand All @@ -134,16 +134,32 @@ public function testSupportsDenormalizationForNonUid()
$this->assertFalse($this->normalizer->supportsDenormalization('foo', \stdClass::class));
}

public function testSupportOurAbstractUid()
{
$this->assertTrue($this->normalizer->supportsDenormalization('1ea6ecef-eb9a-66fe-b62b-957b45f17e43', AbstractUid::class));
}

public function testSupportCustomAbstractUid()
{
$this->assertTrue($this->normalizer->supportsDenormalization('ccc', TestAbstractCustomUid::class));
}

/**
* @dataProvider dataProvider
*/
public function testDenormalize($uuidString, $class)
{
if (Ulid::class === $class) {
$this->assertEquals(new Ulid($uuidString), $this->normalizer->denormalize($uuidString, $class));
} else {
$this->assertEquals(Uuid::fromString($uuidString), $this->normalizer->denormalize($uuidString, $class));
}
$this->assertEquals($class::fromString($uuidString), $this->normalizer->denormalize($uuidString, $class));
}

public function testDenormalizeOurAbstractUid()
{
$this->assertEquals(Uuid::fromString($uuidString = '1ea6ecef-eb9a-66fe-b62b-957b45f17e43'), $this->normalizer->denormalize($uuidString, AbstractUid::class));
}

public function testDenormalizeCustomAbstractUid()
{
$this->assertEquals(Uuid::fromString($uuidString = '1ea6ecef-eb9a-66fe-b62b-957b45f17e43'), $this->normalizer->denormalize($uuidString, TestAbstractCustomUid::class));
}

public function testNormalizeWithNormalizationFormatPassedInConstructor()
Expand All @@ -169,3 +185,11 @@ public function testNormalizeWithNormalizationFormatNotValid()
]);
}
}

class TestCustomUid extends Ulid
{
}

abstract class TestAbstractCustomUid extends Ulid
{
}

0 comments on commit 5e409f0

Please sign in to comment.