Skip to content

Commit 8c5fb71

Browse files
Merge branch '5.4' into 6.3
* 5.4: [Form] Fix merging params & files when "multiple" is enabled [HttpFoundation] Do not swallow trailing `=` in cookie value Handle Sendinblue error responses without a message key [Serializer] Fix collecting only first missing constructor argument [Messenger] Fix DoctrineOpenTransactionLoggerMiddleware [Translation] Add missing return type [Validator] add missing catalan translations
2 parents 94236cb + c54cfbb commit 8c5fb71

File tree

5 files changed

+138
-4
lines changed

5 files changed

+138
-4
lines changed

Normalizer/AbstractNormalizer.php

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -405,8 +405,6 @@ protected function instantiateObject(array &$data, string $class, array &$contex
405405
true
406406
);
407407
$context['not_normalizable_value_exceptions'][] = $exception;
408-
409-
return $reflectionClass->newInstanceWithoutConstructor();
410408
}
411409
}
412410

Tests/Fixtures/Php80WithPromotedTypedConstructor.php

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,10 @@
1313

1414
final class Php80WithPromotedTypedConstructor
1515
{
16-
public function __construct(public bool $bool)
17-
{
16+
public function __construct(
17+
public bool $bool,
18+
public string $string,
19+
public int $int,
20+
) {
1821
}
1922
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Serializer\Tests\Fixtures;
13+
14+
final class WithTypedConstructor
15+
{
16+
/**
17+
* @var string
18+
*/
19+
public $string;
20+
/**
21+
* @var bool
22+
*/
23+
public $bool;
24+
/**
25+
* @var int
26+
*/
27+
public $int;
28+
29+
public function __construct(string $string, bool $bool, int $int)
30+
{
31+
$this->string = $string;
32+
$this->bool = $bool;
33+
$this->int = $int;
34+
}
35+
}

Tests/Normalizer/Features/ConstructorArgumentsTestTrait.php

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,4 +71,22 @@ public function testConstructorWithMissingData()
7171
self::assertSame(['bar', 'baz'], $e->getMissingConstructorArguments());
7272
}
7373
}
74+
75+
public function testExceptionsAreCollectedForConstructorWithMissingData()
76+
{
77+
$data = [
78+
'foo' => 10,
79+
];
80+
81+
$exceptions = [];
82+
83+
$normalizer = $this->getDenormalizerForConstructArguments();
84+
$normalizer->denormalize($data, ConstructorArgumentsObject::class, null, [
85+
'not_normalizable_value_exceptions' => &$exceptions,
86+
]);
87+
88+
self::assertCount(2, $exceptions);
89+
self::assertSame('Failed to create object because the class misses the "bar" property.', $exceptions[0]->getMessage());
90+
self::assertSame('Failed to create object because the class misses the "baz" property.', $exceptions[1]->getMessage());
91+
}
7492
}

Tests/SerializerTest.php

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@
6969
use Symfony\Component\Serializer\Tests\Fixtures\TrueBuiltInDummy;
7070
use Symfony\Component\Serializer\Tests\Fixtures\UpcomingDenormalizerInterface as DenormalizerInterface;
7171
use Symfony\Component\Serializer\Tests\Fixtures\UpcomingNormalizerInterface as NormalizerInterface;
72+
use Symfony\Component\Serializer\Tests\Fixtures\WithTypedConstructor;
7273
use Symfony\Component\Serializer\Tests\Normalizer\TestDenormalizer;
7374
use Symfony\Component\Serializer\Tests\Normalizer\TestNormalizer;
7475

@@ -1209,6 +1210,85 @@ public function testCollectDenormalizationErrorsWithConstructor(?ClassMetadataFa
12091210
'useMessageForUser' => false,
12101211
'message' => 'The type of the "bool" attribute for class "Symfony\\Component\\Serializer\\Tests\\Fixtures\\Php80WithPromotedTypedConstructor" must be one of "bool" ("string" given).',
12111212
],
1213+
[
1214+
'currentType' => 'array',
1215+
'expectedTypes' => [
1216+
'unknown',
1217+
],
1218+
'path' => null,
1219+
'useMessageForUser' => true,
1220+
'message' => 'Failed to create object because the class misses the "string" property.',
1221+
],
1222+
[
1223+
'currentType' => 'array',
1224+
'expectedTypes' => [
1225+
'unknown',
1226+
],
1227+
'path' => null,
1228+
'useMessageForUser' => true,
1229+
'message' => 'Failed to create object because the class misses the "int" property.',
1230+
],
1231+
];
1232+
1233+
$this->assertSame($expected, $exceptionsAsArray);
1234+
}
1235+
1236+
public function testCollectDenormalizationErrorsWithInvalidConstructorTypes()
1237+
{
1238+
$json = '{"string": "some string", "bool": "bool", "int": true}';
1239+
1240+
$extractor = new PropertyInfoExtractor([], [new ReflectionExtractor()]);
1241+
1242+
$serializer = new Serializer(
1243+
[new ObjectNormalizer(null, null, null, $extractor)],
1244+
['json' => new JsonEncoder()]
1245+
);
1246+
1247+
try {
1248+
$serializer->deserialize($json, WithTypedConstructor::class, 'json', [
1249+
DenormalizerInterface::COLLECT_DENORMALIZATION_ERRORS => true,
1250+
]);
1251+
1252+
$this->fail();
1253+
} catch (\Throwable $th) {
1254+
$this->assertInstanceOf(PartialDenormalizationException::class, $th);
1255+
}
1256+
1257+
$this->assertInstanceOf(WithTypedConstructor::class, $object = $th->getData());
1258+
1259+
$this->assertSame('some string', $object->string);
1260+
$this->assertTrue($object->bool);
1261+
$this->assertSame(1, $object->int);
1262+
1263+
$exceptionsAsArray = array_map(function (NotNormalizableValueException $e): array {
1264+
return [
1265+
'currentType' => $e->getCurrentType(),
1266+
'expectedTypes' => $e->getExpectedTypes(),
1267+
'path' => $e->getPath(),
1268+
'useMessageForUser' => $e->canUseMessageForUser(),
1269+
'message' => $e->getMessage(),
1270+
];
1271+
}, $th->getErrors());
1272+
1273+
$expected = [
1274+
[
1275+
'currentType' => 'string',
1276+
'expectedTypes' => [
1277+
0 => 'bool',
1278+
],
1279+
'path' => 'bool',
1280+
'useMessageForUser' => false,
1281+
'message' => 'The type of the "bool" attribute for class "Symfony\Component\Serializer\Tests\Fixtures\WithTypedConstructor" must be one of "bool" ("string" given).',
1282+
],
1283+
[
1284+
'currentType' => 'bool',
1285+
'expectedTypes' => [
1286+
0 => 'int',
1287+
],
1288+
'path' => 'int',
1289+
'useMessageForUser' => false,
1290+
'message' => 'The type of the "int" attribute for class "Symfony\Component\Serializer\Tests\Fixtures\WithTypedConstructor" must be one of "int" ("bool" given).',
1291+
],
12121292
];
12131293

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

0 commit comments

Comments
 (0)