8000 [HttpKernel] Denormalize request data using the csv format when using… · rch7/symfony@e0957a0 · GitHub
[go: up one dir, main page]

Skip to content

Commit e0957a0

Browse files
ovidiuenachefabpot
authored andcommitted
[HttpKernel] Denormalize request data using the csv format when using "#[MapQueryString]" or "#[MapRequestPayload]" (except for content data)
1 parent 727c7ea commit e0957a0

File tree

2 files changed

+67
-4
lines changed

2 files changed

+67
-4
lines changed

src/Symfony/Component/HttpKernel/Controller/ArgumentResolver/RequestPayloadValueResolver.php

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,11 +40,9 @@
4040
class RequestPayloadValueResolver implements ValueResolverInterface, EventSubscriberInterface
4141
{
4242
/**
43-
* @see \Symfony\Component\Serializer\Normalizer\AbstractObjectNormalizer::DISABLE_TYPE_ENFORCEMENT
4443
* @see DenormalizerInterface::COLLECT_DENORMALIZATION_ERRORS
4544
*/
4645
private const CONTEXT_DENORMALIZE = [
47-
'disable_type_enforcement' => true,
4846
'collect_denormalization_errors' => true,
4947
];
5048

@@ -161,7 +159,7 @@ private function mapQueryString(Request $request, string $type, MapQueryString $
161159
return null;
162160
}
163161

164-
return $this->serializer->denormalize($data, $type, null, $attribute->serializationContext + self::CONTEXT_DENORMALIZE);
162+
return $this->serializer->denormalize($data, $type, 'csv', $attribute->serializationContext + self::CONTEXT_DENORMALIZE);
165163
}
166164

167165
private function mapRequestPayload(Request $request, string $type, MapRequestPayload $attribute): ?object
@@ -175,7 +173,7 @@ private function mapRequestPayload(Request $request, string $type, MapRequestPay
175173
}
176174

177175
if ($data = $request->request->all()) {
178-
return $this->serializer->denormalize($data, $type, null, $attribute->serializationContext + self::CONTEXT_DENORMALIZE);
176+
return $this->serializer->denormalize($data, $type, 'csv', $attribute->serializationContext + self::CONTEXT_DENORMALIZE);
179177
}
180178

181179
if ('' === $data = $request->getContent()) {

src/Symfony/Component/HttpKernel/Tests/Controller/ArgumentResolver/RequestPayloadValueResolverTest.php

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
use Symfony\Component\HttpKernel\Exception\HttpException;
2323
use Symfony\Component\HttpKernel\HttpKernelInterface;
2424
use Symfony\Component\PropertyAccess\Exception\InvalidTypeException;
25+
use Symfony\Component\PropertyInfo\Extractor\ReflectionExtractor;
2526
use Symfony\Component\Serializer\Encoder\JsonEncoder;
2627
use Symfony\Component\Serializer\Encoder\XmlEncoder;
2728
use Symfony\Component\Serializer\Exception\PartialDenormalizationException;
@@ -363,6 +364,38 @@ public function testQueryStringValidationPassed()
363364
$this->assertEquals([$payload], $event->getArguments());
364365
}
365366

367+
public function testQueryStringParameterTypeMismatch()
368+
{
369+
$query = ['price' => 'not a float'];
370+
371+
$normalizer = new ObjectNormalizer(null, null, null, new ReflectionExtractor());
372+
$serializer = new Serializer([$normalizer], ['json' => new JsonEncoder()]);
373+
374+
$validator = $this->createMock(ValidatorInterface::class);
375+
$validator->expects($this->never())->method('validate');
376+
377+
$resolver = new RequestPayloadValueResolver($serializer, $validator);
378+
379+
$argument = new ArgumentMetadata('invalid', RequestPayload::class, false, false, null, false, [
380+
MapQueryString::class => new MapQueryString(),
381+
]);
382+
383+
$request = Request::create('/', 'GET', $query);
384+
385+
$kernel = $this->createMock(HttpKernelInterface::class);
386+
$arguments = $resolver->resolve($request, $argument);
387+
$event = new ControllerArgumentsEvent($kernel, function () {}, $arguments, $request, HttpKernelInterface::MAIN_REQUEST);
388+
389+
try {
390+
$resolver->onKernelControllerArguments($event);
391+
$this->fail(sprintf('Expected "%s" to be thrown.', HttpException::class));
392+
} catch (HttpException $e) {
393+
$validationFailedException = $e->getPrevious();
394+
$this->assertInstanceOf(ValidationFailedException::class, $validationFailedException);
395+
$this->assertSame('This value should be of type float.', $validationFailedException->getViolations()[0]->getMessage());
396+
}
397+
}
398+
366399
public function testRequestInputValidationPassed()
367400
{
368401
$input = ['price' => '50'];
@@ -391,6 +424,38 @@ public function testRequestInputValidationPassed()
391424
$this->assertEquals([$payload], $event->getArguments());
392425
}
393426

427+
public function testRequestInputTypeMismatch()
428+
{
429+
$input = ['price' => 'not a float'];
430+
431+
$normalizer = new ObjectNormalizer(null, null, null, new ReflectionExtractor());
432+
$serializer = new Serializer([$normalizer], ['json' => new JsonEncoder()]);
433+
434+
$validator = $this->createMock(ValidatorInterface::class);
435+
$validator->expects($this->never())->method('validate');
436+
437+
$resolver = new RequestPayloadValueResolver($serializer, $validator);
438+
439+
$argument = new ArgumentMetadata('invalid', RequestPayload::class, false, false, null, false, [
440+
MapRequestPayload::class => new MapRequestPayload 67F4 (),
441+
]);
442+
443+
$request = Request::create('/', 'POST', $input);
444+
445+
$kernel = $this->createMock(HttpKernelInterface::class);
446+
$arguments = $resolver->resolve($request, $argument);
447+
$event = new ControllerArgumentsEvent($kernel, function () {}, $arguments, $request, HttpKernelInterface::MAIN_REQUEST);
448+
449+
try {
450+
$resolver->onKernelControllerArguments($event);
451+
$this->fail(sprintf('Expected "%s" to be thrown.', HttpException::class));
452+
} catch (HttpException $e) {
453+
$validationFailedException = $e->getPrevious();
454+
$this->assertInstanceOf(ValidationFailedException::class, $validationFailedException);
455+
$this->assertSame('This value should be of type float.', $validationFailedException->getViolations()[0]->getMessage());
456+
}
457+
}
458+
394459
public function testItThrowsOnVariadicArgument()
395460
{
396461
$serializer = new Serializer();

0 commit comments

Comments
 (0)
0