|
30 | 30 | use Symfony\Component\Serializer\Exception\NotNormalizableValueException; |
31 | 31 | use Symfony\Component\Serializer\Exception\PartialDenormalizationException; |
32 | 32 | use Symfony\Component\Serializer\Normalizer\ArrayDenormalizer; |
| 33 | +use Symfony\Component\Serializer\Normalizer\BackedEnumNormalizer; |
33 | 34 | use Symfony\Component\Serializer\Normalizer\DenormalizerInterface; |
34 | 35 | use Symfony\Component\Serializer\Normalizer\ObjectNormalizer; |
35 | 36 | use Symfony\Component\Serializer\Serializer; |
@@ -284,6 +285,37 @@ public function testValidationNotPassed() |
284 | 285 | } |
285 | 286 | } |
286 | 287 |
|
| 288 | + public function testValidationFailedOnInvalidBackedEnum() |
| 289 | + { |
| 290 | + $content = '{"method": "INVALID"}'; |
| 291 | + $serializer = new Serializer([new BackedEnumNormalizer(), new ObjectNormalizer()], ['json' => new JsonEncoder()]); |
| 292 | + |
| 293 | + $validator = $this->createMock(ValidatorInterface::class); |
| 294 | + $validator->expects($this->never()) |
| 295 | + ->method('validate'); |
| 296 | + |
| 297 | + $resolver = new RequestPayloadValueResolver($serializer, $validator); |
| 298 | + |
| 299 | + $argument = new ArgumentMetadata('invalid', RequestPayloadWithBackedEnum::class, false, false, null, false, [ |
| 300 | + MapRequestPayload::class => new MapRequestPayload(), |
| 301 | + ]); |
| 302 | + $request = Request::create('/', 'POST', server: ['CONTENT_TYPE' => 'application/json'], content: $content); |
| 303 | + |
| 304 | + $kernel = $this->createStub(HttpKernelInterface::class); |
| 305 | + $arguments = $resolver->resolve($request, $argument); |
| 306 | + $event = new ControllerArgumentsEvent($kernel, function () {}, $arguments, $request, HttpKernelInterface::MAIN_REQUEST); |
| 307 | + |
| 308 | + try { |
| 309 | + $resolver->onKernelControllerArguments($event); |
| 310 | + $this->fail(\sprintf('Expected "%s" to be thrown.', HttpException::class)); |
| 311 | + } catch (HttpException $e) { |
| 312 | + $validationFailedException = $e->getPrevious(); |
| 313 | + $this->assertSame(422, $e->getStatusCode()); |
| 314 | + $this->assertInstanceOf(ValidationFailedException::class, $validationFailedException); |
| 315 | + $this->assertSame('The data must belong to a backed enumeration of type Symfony\\Component\\HttpKernel\\Tests\\Controller\\ArgumentResolver\\RequestMethod', $validationFailedException->getViolations()[0]->getMessage()); |
| 316 | + } |
| 317 | + } |
| 318 | + |
287 | 319 | public function testValidationNotPerformedWhenPartialDenormalizationReturnsViolation() |
288 | 320 | { |
289 | 321 | $content = '{"password": "abc"}'; |
@@ -1014,6 +1046,19 @@ public function getPassword(): string |
1014 | 1046 | } |
1015 | 1047 | } |
1016 | 1048 |
|
| 1049 | +class RequestPayloadWithBackedEnum |
| 1050 | +{ |
| 1051 | + public function __construct(public readonly RequestMethod $method) |
| 1052 | + { |
| 1053 | + } |
| 1054 | +} |
| 1055 | + |
| 1056 | +enum RequestMethod: string |
| 1057 | +{ |
| 1058 | + case GET = 'GET'; |
| 1059 | + case POST = 'POST'; |
| 1060 | +} |
| 1061 | + |
1017 | 1062 | class ObjectWithBoolArgument |
1018 | 1063 | { |
1019 | 1064 | public function __construct(public readonly ?bool $value = null) |
|
0 commit comments