|
34 | 34 | use ApiPlatform\Serializer\AbstractItemNormalizer; |
35 | 35 | use ApiPlatform\Serializer\Tests\Fixtures\ApiResource\DtoWithNullValue; |
36 | 36 | use ApiPlatform\Serializer\Tests\Fixtures\ApiResource\Dummy; |
| 37 | +use ApiPlatform\Serializer\Tests\Fixtures\ApiResource\DummyWithMultipleRequiredConstructorArgs; |
37 | 38 | use ApiPlatform\Serializer\Tests\Fixtures\ApiResource\DummyTableInheritance; |
38 | 39 | use ApiPlatform\Serializer\Tests\Fixtures\ApiResource\DummyTableInheritanceChild; |
39 | 40 | use ApiPlatform\Serializer\Tests\Fixtures\ApiResource\DummyTableInheritanceRelated; |
|
51 | 52 | use Symfony\Component\PropertyAccess\PropertyAccessorInterface; |
52 | 53 | use Symfony\Component\PropertyInfo\PropertyInfoExtractor; |
53 | 54 | use Symfony\Component\PropertyInfo\Type as LegacyType; |
| 55 | +use Symfony\Component\Serializer\Exception\MissingConstructorArgumentsException; |
54 | 56 | use Symfony\Component\Serializer\Exception\NotNormalizableValueException; |
55 | 57 | use Symfony\Component\Serializer\Exception\UnexpectedValueException; |
56 | 58 | use Symfony\Component\Serializer\Normalizer\DenormalizerInterface; |
@@ -1937,6 +1939,46 @@ public function testSupportsNormalizationWithApiPlatformOutputContext(): void |
1937 | 1939 | 'api_platform_output_class' => 'SomeOtherClass', |
1938 | 1940 | ])); |
1939 | 1941 | } |
| 1942 | + |
| 1943 | + public function testDenormalizeReportsAllMissingConstructorArguments(): void |
| 1944 | + { |
| 1945 | + $data = []; |
| 1946 | + |
| 1947 | + $propertyNameCollectionFactoryProphecy = $this->prophesize(PropertyNameCollectionFactoryInterface::class); |
| 1948 | + $propertyNameCollectionFactoryProphecy->create(DummyWithMultipleRequiredConstructorArgs::class, Argument::type('array'))->willReturn(new PropertyNameCollection(['title', 'rating', 'comment'])); |
| 1949 | + |
| 1950 | + $propertyMetadataFactoryProphecy = $this->prophesize(PropertyMetadataFactoryInterface::class); |
| 1951 | + |
| 1952 | + if (!method_exists(PropertyInfoExtractor::class, 'getType')) { |
| 1953 | + $propertyMetadataFactoryProphecy->create(DummyWithMultipleRequiredConstructorArgs::class, 'title', Argument::type('array'))->willReturn((new ApiProperty())->withBuiltinTypes([new LegacyType(LegacyType::BUILTIN_TYPE_STRING)])->withReadable(true)->withWritable(true)); |
| 1954 | + $propertyMetadataFactoryProphecy->create(DummyWithMultipleRequiredConstructorArgs::class, 'rating', Argument::type('array'))->willReturn((new ApiProperty())->withBuiltinTypes([new LegacyType(LegacyType::BUILTIN_TYPE_INT)])->withReadable(true)->withWritable(true)); |
| 1955 | + $propertyMetadataFactoryProphecy->create(DummyWithMultipleRequiredConstructorArgs::class, 'comment', Argument::type('array'))->willReturn((new ApiProperty())->withBuiltinTypes([new LegacyType(LegacyType::BUILTIN_TYPE_STRING)])->withReadable(true)->withWritable(true)); |
| 1956 | + } else { |
| 1957 | + $propertyMetadataFactoryProphecy->create(DummyWithMultipleRequiredConstructorArgs::class, 'title', Argument::type('array'))->willReturn((new ApiProperty())->withNativeType(Type::string())->withReadable(true)->withWritable(true)); |
| 1958 | + $propertyMetadataFactoryProphecy->create(DummyWithMultipleRequiredConstructorArgs::class, 'rating', Argument::type('array'))->willReturn((new ApiProperty())->withNativeType(Type::int())->withReadable(true)->withWritable(true)); |
| 1959 | + $propertyMetadataFactoryProphecy->create(DummyWithMultipleRequiredConstructorArgs::class, 'comment', Argument::type('array'))->willReturn((new ApiProperty())->withNativeType(Type::string())->withReadable(true)->withWritable(true)); |
| 1960 | + } |
| 1961 | + |
| 1962 | + $iriConverterProphecy = $this->prophesize(IriConverterInterface::class); |
| 1963 | + $propertyAccessorProphecy = $this->prophesize(PropertyAccessorInterface::class); |
| 1964 | + $resourceClassResolverProphecy = $this->prophesize(ResourceClassResolverInterface::class); |
| 1965 | + $resourceClassResolverProphecy->getResourceClass(null, DummyWithMultipleRequiredConstructorArgs::class)->willReturn(DummyWithMultipleRequiredConstructorArgs::class); |
| 1966 | + $resourceClassResolverProphecy->isResourceClass(DummyWithMultipleRequiredConstructorArgs::class)->willReturn(true); |
| 1967 | + |
| 1968 | + $serializerProphecy = $this->prophesize(SerializerInterface::class); |
| 1969 | + $serializerProphecy->willImplement(NormalizerInterface::class); |
| 1970 | + |
| 1971 | + $normalizer = new class($propertyNameCollectionFactoryProphecy->reveal(), $propertyMetadataFactoryProphecy->reveal(), $iriConverterProphecy->reveal(), $resourceClassResolverProphecy->reveal(), $propertyAccessorProphecy->reveal(), null, null, [], null, null) extends AbstractItemNormalizer {}; |
| 1972 | + $normalizer->setSerializer($serializerProphecy->reveal()); |
| 1973 | + |
| 1974 | + try { |
| 1975 | + $normalizer->denormalize($data, DummyWithMultipleRequiredConstructorArgs::class); |
| 1976 | + $this->fail('Expected MissingConstructorArgumentsException was not thrown'); |
| 1977 | + } catch (MissingConstructorArgumentsException $e) { |
| 1978 | + $this->assertCount(3, $e->getMissingConstructorArguments(), 'All three missing constructor arguments (title, rating, comment) should be reported, not just the first one.'); |
| 1979 | + $this->assertSame(['title', 'rating', 'comment'], $e->getMissingConstructorArguments()); |
| 1980 | + } |
| 1981 | + } |
1940 | 1982 | } |
1941 | 1983 |
|
1942 | 1984 | class ObjectWithBasicProperties |
|
0 commit comments