8000 [Serializer] Throw NotNormalizableValueException if it doesn't concer… · symfony/symfony@5549493 · GitHub
[go: up one dir, main page]

Skip to content

Commit 5549493

Browse files
committed
[Serializer] Throw NotNormalizableValueException if it doesn't concern a backedEnum in construct method
1 parent c6a452d commit 5549493

File tree

5 files changed

+66
-4
lines changed

5 files changed

+66
-4
lines changed

src/Symfony/Component/Serializer/Normalizer/AbstractNormalizer.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,7 @@ protected function instantiateObject(array &$data, string $class, array &$contex
342342

343343
$constructor = $this->getConstructor($data, $class, $context, $reflectionClass, $allowedAttributes);
344344
if ($constructor) {
345+
$context['has_constructor'] = true;
345346
if (true !== $constructor->isPublic()) {
346347
return $reflectionClass->newInstanceWithoutConstructor();
347348
}
@@ -431,6 +432,8 @@ protected function instantiateObject(array &$data, string $class, array &$contex
431432
}
432433
}
433434

435+
unset($context['has_constructor']);
436+
434437
return new $class();
435438
}
436439

src/Symfony/Component/Serializer/Normalizer/BackedEnumNormalizer.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,11 @@ public function denormalize($data, string $type, string $format = null, array $c
6464
try {
6565
return $type::from($data);
6666
} catch (\ValueError $e) {
67-
throw new InvalidArgumentException('The data must belong to a backed enumeration of type '.$type);
67+
if (isset($context['has_constructor'])) {
68+
throw new InvalidArgumentException('The data must belong to a backed enumeration of type '.$type);
69+
}
70+
71+
throw NotNormalizableValueException::createForUnexpectedDataType('The data must belong to a backed enumeration of type '.$type, $data, [$type], $context['deserialization_path'] ?? null, true, 0, $e);
6872
}
6973
}
7074

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?php
2+
3+
namespace Symfony\Component\Serializer\Tests\Fixtures;
4+
5+
use Symfony\Component\Serializer\Tests\Fixtures\StringBackedEnumDummy;
6+
7+
class DummyObjectWithEnumProperty
8+
{
9+
public StringBackedEnumDummy $get;
10+
}

src/Symfony/Component/Serializer/Tests/Normalizer/BackedEnumNormalizerTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ public function testDenormalizeObjectThrowsException()
115115
*/
116116
public function testDenormalizeBadBackingValueThrowsException()
117117
{
118-
$this->expectException(InvalidArgumentException::class);
118+
$this->expectException(NotNormalizableValueException::class);
119119
$this->expectExceptionMessage('The data must belong to a backed enumeration of type '.StringBackedEnumDummy::class);
120120

121121
$this->normalizer->denormalize('POST', StringBackedEnumDummy::class);

src/Symfony/Component/Serializer/Tests/SerializerTest.php

Lines changed: 47 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@
6060
use Symfony\Component\Serializer\Tests\Fixtures\DummyMessageNumberOne;
6161
use Symfony\Component\Serializer\Tests\Fixtures\DummyMessageNumberTwo;
6262
use Symfony\Component\Serializer\Tests\Fixtures\DummyObjectWithEnumConstructor;
63+
use Symfony\Component\Serializer\Tests\Fixtures\DummyObjectWithEnumProperty;
6364
use Symfony\Component\Serializer\Tests\Fixtures\FalseBuiltInDummy;
6465
use Symfony\Component\Serializer\Tests\Fixtures\NormalizableTraversableDummy;
6566
use Symfony\Component\Serializer\Tests\Fixtures\Php74Full;
@@ -1230,7 +1231,51 @@ public function testCollectDenormalizationErrorsWithEnumConstructor()
12301231
/**
12311232
* @requires PHP 8.1
12321233
*/
1233-
public function testNoCollectDenormalizationErrorsWithWrongEnum()
1234+
public function testCollectDenormalizationErrorsWithWrongPropertyWithoutConstruct()
1235+
{
1236+
$classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader());
1237+
$reflectionExtractor = new ReflectionExtractor();
1238+
$propertyInfoExtractor = new PropertyInfoExtractor([], [$reflectionExtractor], [], [], []);
1239+
1240+
$serializer = new Serializer(
1241+
[
1242+
new BackedEnumNormalizer(),
1243+
new ObjectNormalizer($classMetadataFactory, null, null, $propertyInfoExtractor),
1244+
],
1245+
['json' => new JsonEncoder()]
1246+
);
1247+
1248+
try {
1249+
$serializer->deserialize('{"get": "POST"}', DummyObjectWithEnumProperty::class, 'json', [
1250+
DenormalizerInterface::COLLECT_DENORMALIZATION_ERRORS => true,
1251+
]);
1252+
} catch (\Throwable $e) {
1253+
$this->assertInstanceOf(PartialDenormalizationException::class, $e);
1254+
}
1255+
1256+
$exceptionsAsArray = array_map(function (NotNormalizableValueException $e): array {
1257+
return [
1258+
'currentType' => $e->getCurrentType(),
1259+
'useMessageForUser' => $e->canUseMessageForUser(),
1260+
'message' => $e->getMessage(),
1261+
];
1262+
}, $e->getErrors());
1263+
1264+
$expected = [
1265+
[
1266+
'currentType' => 'string',
1267+
'useMessageForUser' => true,
1268+
'message' => 'The data must belong to a backed enumeration of type Symfony\Component\Serializer\Tests\Fixtures\StringBackedEnumDummy',
1269+
],
1270+
];
1271+
1272+
$this->assertSame($expected, $exceptionsAsArray);
1273+
}
1274+
1275+
/**
1276+
* @requires PHP 8.1
1277+
*/
1278+
public function testNoCollectDenormalizationErrorsWithWrongEnumOnConstructor()
12341279
{
12351280
$serializer = new Serializer(
12361281
[
@@ -1241,7 +1286,7 @@ public function testNoCollectDenormalizationErrorsWithWrongEnum()
12411286
);
12421287

12431288
try {
1244-
$serializer->deserialize('{"get": "invalid"}', DummyObjectWithEnumConstructor::class, 'json', [
1289+
$serializer->deserialize('{"get": "POST"}', DummyObjectWithEnumConstructor::class, 'json', [
12451290
DenormalizerInterface::COLLECT_DENORMALIZATION_ERRORS => true,
12461291
]);
12471292
} catch (\Throwable $th) {

0 commit comments

Comments
 (0)
0