diff --git a/src/Serializer/AbstractItemNormalizer.php b/src/Serializer/AbstractItemNormalizer.php index e8695e1e79..226d6853fa 100644 --- a/src/Serializer/AbstractItemNormalizer.php +++ b/src/Serializer/AbstractItemNormalizer.php @@ -652,7 +652,7 @@ protected function denormalizeObjectCollection(string $attribute, ApiProperty $p $collectionKeyType = $type->getCollectionKeyType(); while ($collectionKeyType instanceof WrappingTypeInterface) { - $collectionKeyType = $type->getWrappedType(); + $collectionKeyType = $collectionKeyType->getWrappedType(); } if (!$collectionKeyType->accepts($index)) { diff --git a/src/Serializer/Tests/AbstractItemNormalizerTest.php b/src/Serializer/Tests/AbstractItemNormalizerTest.php index 3a44cbd322..e1c796e579 100644 --- a/src/Serializer/Tests/AbstractItemNormalizerTest.php +++ b/src/Serializer/Tests/AbstractItemNormalizerTest.php @@ -1780,6 +1780,30 @@ public function testDenormalizeBadKeyType(): void $normalizer->denormalize($data, Dummy::class); } + public function testDenormalizeBadWrappedKeyType(): void + { + $this->expectException(NotNormalizableValueException::class); + $this->expectExceptionMessage('The type of the key "a" must be'); + + $propertyNameCollectionFactory = $this->createStub(PropertyNameCollectionFactoryInterface::class); + $propertyNameCollectionFactory->method('create')->willReturn(new PropertyNameCollection(['relatedDummies'])); + + $type = Type::collection(Type::object(ArrayCollection::class), Type::object(RelatedDummy::class), Type::nullable(Type::int())); + $propertyMetadataFactory = $this->createStub(PropertyMetadataFactoryInterface::class); + $propertyMetadataFactory->method('create')->willReturn((new ApiProperty())->withNativeType($type)->withReadable(false)->withWritable(true)->withReadableLink(false)->withWritableLink(true)); + + $resourceClassResolver = $this->createStub(ResourceClassResolverInterface::class); + $resourceClassResolver->method('getResourceClass')->willReturnArgument(1); + $resourceClassResolver->method('isResourceClass')->willReturn(true); + + $serializer = self::createStubForIntersectionOfInterfaces([SerializerInterface::class, DenormalizerInterface::class]); + + $normalizer = new class($propertyNameCollectionFactory, $propertyMetadataFactory, $this->createStub(IriConverterInterface::class), $resourceClassResolver, $this->createStub(PropertyAccessorInterface::class), null, null, [], null, null) extends AbstractItemNormalizer {}; + $normalizer->setSerializer($serializer); + + $normalizer->denormalize(['relatedDummies' => ['a' => ['bar' => 'baz']]], Dummy::class); + } + public function testNullable(): void { $data = [