|
20 | 20 | use Symfony\Component\HttpKernel\ControllerMetadata\ArgumentMetadata;
|
21 | 21 | use Symfony\Component\HttpKernel\Event\ControllerArgumentsEvent;
|
22 | 22 | use Symfony\Component\HttpKernel\Exception\HttpException;
|
| 23 | +use Symfony\Component\HttpKernel\Exception\NearMissValueResolverException; |
23 | 24 | use Symfony\Component\HttpKernel\HttpKernelInterface;
|
24 | 25 | use Symfony\Component\Serializer\Encoder\JsonEncoder;
|
25 | 26 | use Symfony\Component\Serializer\Encoder\XmlEncoder;
|
26 | 27 | use Symfony\Component\Serializer\Exception\NotNormalizableValueException;
|
27 | 28 | use Symfony\Component\Serializer\Exception\PartialDenormalizationException;
|
| 29 | +use Symfony\Component\Serializer\Normalizer\ArrayDenormalizer; |
28 | 30 | use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
|
29 | 31 | use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
|
30 | 32 | use Symfony\Component\Serializer\Serializer;
|
@@ -421,6 +423,74 @@ public function testRequestInputValidationPassed()
|
421 | 423 | $this->assertEquals([$payload], $event->getArguments());
|
422 | 424 | }
|
423 | 425 |
|
| 426 | + public function testRequestArrayDenormalization() |
| 427 | + { |
| 428 | + $input = [ |
| 429 | + ['price' => '50'], |
| 430 | + ['price' => '23'], |
| 431 | + ]; |
| 432 | + $payload = [ |
| 433 | + new RequestPayload(50), |
| 434 | + new RequestPayload(23), |
| 435 | + ]; |
| 436 | + |
| 437 | + $serializer = new Serializer([new ArrayDenormalizer(), new ObjectNormalizer()], ['json' => new JsonEncoder()]); |
| 438 | + |
| 439 | + $validator = $this->createMock(ValidatorInterface::class); |
| 440 | + $validator->expects($this->once()) |
| 441 | + ->method('validate') |
| 442 | + ->willReturn(new ConstraintViolationList()); |
| 443 | + |
| 444 | + $resolver = new RequestPayloadValueResolver($serializer, $validator); |
| 445 | + |
| 446 | + $argument = new ArgumentMetadata('prices', 'array', false, false, null, false, [ |
| 447 | + MapRequestPayload::class => new MapRequestPayload(type: RequestPayload::class), |
| 448 | + ]); |
| 449 | + $request = Request::create('/', 'POST', $input); |
| 450 | + |
| 451 | + $kernel = $this->createMock(HttpKernelInterface::class); |
| 452 | + $arguments = $resolver->resolve($request, $argument); |
| 453 | + $event = new ControllerArgumentsEvent($kernel, function () {}, $arguments, $request, HttpKernelInterface::MAIN_REQUEST); |
| 454 | + |
| 455 | + $resolver->onKernelControllerArguments($event); |
| 456 | + |
| 457 | + $this->assertEquals([$payload], $event->getArguments()); |
| 458 | + } |
| 459 | + |
| 460 | + public function testItThrowsOnMissingAttributeType() |
| 461 | + { |
| 462 | + $serializer = new Serializer(); |
| 463 | + $validator = $this->createMock(ValidatorInterface::class); |
| 464 | + $resolver = new RequestPayloadValueResolver($serializer, $validator); |
| 465 | + |
| 466 | + $argument = new ArgumentMetadata('prices', 'array', false, false, null, false, [ |
| 467 | + MapRequestPayload::class => new MapRequestPayload(), |
| 468 | + ]); |
| 469 | + $request = Request::create('/', 'POST'); |
| 470 | + $request->attributes->set('_controller', 'App\Controller\SomeController::someMethod'); |
| 471 | + |
| 472 | + $this->expectException(NearMissValueResolverException::class); |
| 473 | + $this->expectExceptionMessage('Controller "App\Controller\SomeController::someMethod" requires the "$prices" argument that could not be resolved. Please set the $type argument of the #[MapRequestPayload] attribute to the type of the objects in the expected array.'); |
| 474 | + $resolver->resolve($request, $argument); |
| 475 | + } |
| 476 | + |
| 477 | + public function testItThrowsOnInvalidAttributeTypeUsage() |
| 478 | + { |
| 479 | + $serializer = new Serializer(); |
| 480 | + $validator = $this->createMock(ValidatorInterface::class); |
| 481 | + $resolver = new RequestPayloadValueResolver($serializer, $validator); |
| 482 | + |
| 483 | + $argument = new ArgumentMetadata('prices', null, false, false, null, false, [ |
| 484 | + MapRequestPayload::class => new MapRequestPayload(type: RequestPayload::class), |
| 485 | + ]); |
| 486 | + $request = Request::create('/', 'POST'); |
| 487 | + $request->attributes->set('_controller', 'App\Controller\SomeController::someMethod'); |
| 488 | + |
| 489 | + $this->expectException(NearMissValueResolverException::class); |
| 490 | + $this->expectExceptionMessage('Controller "App\Controller\SomeController::someMethod" requires the "$prices" argument that could not be resolved. Please set its type to "array" when using argument $type of #[MapRequestPayload].'); |
| 491 | + $resolver->resolve($request, $argument); |
| 492 | + } |
| 493 | + |
424 | 494 | public function testItThrowsOnVariadicArgument()
|
425 | 495 | {
|
426 | 496 | $serializer = new Serializer();
|
|
0 commit comments