Skip to content

Commit

Permalink
Merge branch '5.4' into 6.3
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
nicolas-grekas committed Oct 17, 2023
2 parents 94236cb + c54cfbb commit 8c5fb71
Show file tree
Hide file tree
Showing 5 changed files with 138 additions and 4 deletions.
2 changes: 0 additions & 2 deletions Normalizer/AbstractNormalizer.php
Original file line number Diff line number Diff line change
Expand Up @@ -405,8 +405,6 @@ protected function instantiateObject(array &$data, string $class, array &$contex
true
);
$context['not_normalizable_value_exceptions'][] = $exception;

return $reflectionClass->newInstanceWithoutConstructor();
}
}

Expand Down
7 changes: 5 additions & 2 deletions Tests/Fixtures/Php80WithPromotedTypedConstructor.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@

final class Php80WithPromotedTypedConstructor
{
public function __construct(public bool $bool)
{
public function __construct(
public bool $bool,
public string $string,
public int $int,
) {
}
}
35 changes: 35 additions & 0 deletions Tests/Fixtures/WithTypedConstructor.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?php

/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Symfony\Component\Serializer\Tests\Fixtures;

final class WithTypedConstructor
{
/**
* @var string
*/
public $string;
/**
* @var bool
*/
public $bool;
/**
* @var int
*/
public $int;

public function __construct(string $string, bool $bool, int $int)
{
$this->string = $string;
$this->bool = $bool;
$this->int = $int;
}
}
18 changes: 18 additions & 0 deletions Tests/Normalizer/Features/ConstructorArgumentsTestTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -71,4 +71,22 @@ public function testConstructorWithMissingData()
self::assertSame(['bar', 'baz'], $e->getMissingConstructorArguments());
}
}

public function testExceptionsAreCollectedForConstructorWithMissingData()
{
$data = [
'foo' => 10,
];

$exceptions = [];

$normalizer = $this->getDenormalizerForConstructArguments();
$normalizer->denormalize($data, ConstructorArgumentsObject::class, null, [
'not_normalizable_value_exceptions' => &$exceptions,
]);

self::assertCount(2, $exceptions);
self::assertSame('Failed to create object because the class misses the "bar" property.', $exceptions[0]->getMessage());
self::assertSame('Failed to create object because the class misses the "baz" property.', $exceptions[1]->getMessage());
}
}
80 changes: 80 additions & 0 deletions Tests/SerializerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@
use Symfony\Component\Serializer\Tests\Fixtures\TrueBuiltInDummy;
use Symfony\Component\Serializer\Tests\Fixtures\UpcomingDenormalizerInterface as DenormalizerInterface;
use Symfony\Component\Serializer\Tests\Fixtures\UpcomingNormalizerInterface as NormalizerInterface;
use Symfony\Component\Serializer\Tests\Fixtures\WithTypedConstructor;
use Symfony\Component\Serializer\Tests\Normalizer\TestDenormalizer;
use Symfony\Component\Serializer\Tests\Normalizer\TestNormalizer;

Expand Down Expand Up @@ -1209,6 +1210,85 @@ public function testCollectDenormalizationErrorsWithConstructor(?ClassMetadataFa
'useMessageForUser' => false,
'message' => 'The type of the "bool" attribute for class "Symfony\\Component\\Serializer\\Tests\\Fixtures\\Php80WithPromotedTypedConstructor" must be one of "bool" ("string" given).',
],
[
'currentType' => 'array',
'expectedTypes' => [
'unknown',
],
'path' => null,
'useMessageForUser' => true,
'message' => 'Failed to create object because the class misses the "string" property.',
],
[
'currentType' => 'array',
'expectedTypes' => [
'unknown',
],
'path' => null,
'useMessageForUser' => true,
'message' => 'Failed to create object because the class misses the "int" property.',
],
];

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

public function testCollectDenormalizationErrorsWithInvalidConstructorTypes()
{
$json = '{"string": "some string", "bool": "bool", "int": true}';

$extractor = new PropertyInfoExtractor([], [new ReflectionExtractor()]);

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

try {
$serializer->deserialize($json, WithTypedConstructor::class, 'json', [
DenormalizerInterface::COLLECT_DENORMALIZATION_ERRORS => true,
]);

$this->fail();
} catch (\Throwable $th) {
$this->assertInstanceOf(PartialDenormalizationException::class, $th);
}

$this->assertInstanceOf(WithTypedConstructor::class, $object = $th->getData());

$this->assertSame('some string', $object->string);
$this->assertTrue($object->bool);
$this->assertSame(1, $object->int);

$exceptionsAsArray = array_map(function (NotNormalizableValueException $e): array {
return [
'currentType' => $e->getCurrentType(),
'expectedTypes' => $e->getExpectedTypes(),
'path' => $e->getPath(),
'useMessageForUser' => $e->canUseMessageForUser(),
'message' => $e->getMessage(),
];
}, $th->getErrors());

$expected = [
[
'currentType' => 'string',
'expectedTypes' => [
0 => 'bool',
],
'path' => 'bool',
'useMessageForUser' => false,
'message' => 'The type of the "bool" attribute for class "Symfony\Component\Serializer\Tests\Fixtures\WithTypedConstructor" must be one of "bool" ("string" given).',
],
[
'currentType' => 'bool',
'expectedTypes' => [
0 => 'int',
],
'path' => 'int',
'useMessageForUser' => false,
'message' => 'The type of the "int" attribute for class "Symfony\Component\Serializer\Tests\Fixtures\WithTypedConstructor" must be one of "int" ("bool" given).',
],
];

$this->assertSame($expected, $exceptionsAsArray);
Expand Down

0 comments on commit 8c5fb71

Please sign in to comment.