Skip to content

Commit

Permalink
[Serializer] Throw NotNormalizableValueException if it doesn't concer…
Browse files Browse the repository at this point in the history
…n a backedEnum in construct method
  • Loading branch information
alli83 committed Apr 28, 2023
1 parent c6a452d commit 53fd29d
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,7 @@ protected function instantiateObject(array &$data, string $class, array &$contex

$constructor = $this->getConstructor($data, $class, $context, $reflectionClass, $allowedAttributes);
if ($constructor) {
$context['has_constructor'] = true;
if (true !== $constructor->isPublic()) {
return $reflectionClass->newInstanceWithoutConstructor();
}
Expand Down Expand Up @@ -431,6 +432,8 @@ protected function instantiateObject(array &$data, string $class, array &$contex
}
}

unset($context['has_constructor']);

return new $class();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,11 @@ public function denormalize($data, string $type, string $format = null, array $c
try {
return $type::from($data);
} catch (\ValueError $e) {
throw new InvalidArgumentException('The data must belong to a backed enumeration of type '.$type);
if (isset($context['has_constructor'])) {
throw new InvalidArgumentException('The data must belong to a backed enumeration of type '.$type);
}

throw new NotNormalizableValueException('The data must belong to a backed enumeration of type '.$type);
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php

namespace Symfony\Component\Serializer\Tests\Fixtures;

use Symfony\Component\Serializer\Tests\Fixtures\StringBackedEnumDummy;

class DummyObjectWithEnumProperty
{
public StringBackedEnumDummy $get;
}
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ public function testDenormalizeObjectThrowsException()
*/
public function testDenormalizeBadBackingValueThrowsException()
{
$this->expectException(InvalidArgumentException::class);
$this->expectException(NotNormalizableValueException::class);
$this->expectExceptionMessage('The data must belong to a backed enumeration of type '.StringBackedEnumDummy::class);

$this->normalizer->denormalize('POST', StringBackedEnumDummy::class);
Expand Down
45 changes: 43 additions & 2 deletions src/Symfony/Component/Serializer/Tests/SerializerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@
use Symfony\Component\Serializer\Tests\Fixtures\DummyMessageNumberOne;
use Symfony\Component\Serializer\Tests\Fixtures\DummyMessageNumberTwo;
use Symfony\Component\Serializer\Tests\Fixtures\DummyObjectWithEnumConstructor;
use Symfony\Component\Serializer\Tests\Fixtures\DummyObjectWithEnumProperty;
use Symfony\Component\Serializer\Tests\Fixtures\FalseBuiltInDummy;
use Symfony\Component\Serializer\Tests\Fixtures\NormalizableTraversableDummy;
use Symfony\Component\Serializer\Tests\Fixtures\Php74Full;
Expand Down Expand Up @@ -1230,7 +1231,47 @@ public function testCollectDenormalizationErrorsWithEnumConstructor()
/**
* @requires PHP 8.1
*/
public function testNoCollectDenormalizationErrorsWithWrongEnum()
public function testCollectDenormalizationErrorsWithWrongPropertyWithoutConstruct()
{
$classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader());
$reflectionExtractor = new ReflectionExtractor();
$propertyInfoExtractor = new PropertyInfoExtractor([], [$reflectionExtractor], [], [], []);

$serializer = new Serializer(
[
new BackedEnumNormalizer(),
new ObjectNormalizer($classMetadataFactory, null, null, $propertyInfoExtractor),
],
['json' => new JsonEncoder()]
);

try {
$serializer->deserialize('{"get": "POST"}', DummyObjectWithEnumProperty::class, 'json', [
DenormalizerInterface::COLLECT_DENORMALIZATION_ERRORS => true,
]);
} catch (\Throwable $th) {
$this->assertInstanceOf(PartialDenormalizationException::class, $th);
}

$exceptionsAsArray = array_map(function (NotNormalizableValueException $e): array {
return [
'message' => $e->getMessage(),
];
}, $th->getErrors());

$expected = [
[
'message' => 'The data must belong to a backed enumeration of type Symfony\Component\Serializer\Tests\Fixtures\StringBackedEnumDummy',
],
];

$this->assertSame($expected, $exceptionsAsArray);
}

/**
* @requires PHP 8.1
*/
public function testNoCollectDenormalizationErrorsWithWrongEnumOnConstructor()
{
$serializer = new Serializer(
[
Expand All @@ -1241,7 +1282,7 @@ public function testNoCollectDenormalizationErrorsWithWrongEnum()
);

try {
$serializer->deserialize('{"get": "invalid"}', DummyObjectWithEnumConstructor::class, 'json', [
$serializer->deserialize('{"get": "POST"}', DummyObjectWithEnumConstructor::class, 'json', [
DenormalizerInterface::COLLECT_DENORMALIZATION_ERRORS => true,
]);
} catch (\Throwable $th) {
Expand Down

0 comments on commit 53fd29d

Please sign in to comment.