diff --git a/src/Serializer/ItemNormalizer.php b/src/Serializer/ItemNormalizer.php index 36bb1799f1d..558867f10d7 100644 --- a/src/Serializer/ItemNormalizer.php +++ b/src/Serializer/ItemNormalizer.php @@ -31,6 +31,10 @@ class ItemNormalizer extends AbstractItemNormalizer */ public function denormalize($data, $class, $format = null, array $context = []) { + if (!isset($context['resource_class'])) { + $context['resource_class'] = $class; + } + // Avoid issues with proxies if we populated the object if (isset($data['id']) && !isset($context[self::OBJECT_TO_POPULATE])) { if (isset($context['api_allow_update']) && true !== $context['api_allow_update']) { diff --git a/tests/Serializer/ItemNormalizerTest.php b/tests/Serializer/ItemNormalizerTest.php index 76f830dbc88..8da66be565d 100644 --- a/tests/Serializer/ItemNormalizerTest.php +++ b/tests/Serializer/ItemNormalizerTest.php @@ -159,6 +159,63 @@ public function testDenormalizeWithIri() $this->assertInstanceOf(Dummy::class, $normalizer->denormalize(['id' => '/dummies/12', 'name' => 'hello'], Dummy::class, null, $context)); } + public function testDenormalizeWithIdWithoutResourceClass() + { + $context = []; + + $propertyNameCollection = new PropertyNameCollection(['id']); + $propertyNameCollectionFactoryProphecy = $this + ->prophesize(PropertyNameCollectionFactoryInterface::class); + $propertyNameCollectionFactoryProphecy + ->create(Dummy::class, Argument::type('array')) + ->willReturn($propertyNameCollection) + ->shouldBeCalled(); + + $propertyMetadataFactory = new PropertyMetadata(null, null, true, true); + $propertyMetadataFactoryProphecy = $this + ->prophesize(PropertyMetadataFactoryInterface::class); + + $propertyMetadataFactoryProphecy + ->create(Dummy::class, 'id', Argument::any()) + ->willReturn($propertyMetadataFactory->withIdentifier(true)); + + $iriConverterProphecy = $this->prophesize(IriConverterInterface::class); + + $iriConverterProphecy + ->getItemFromIri('12', Argument::type('array')) + ->willThrow(new InvalidArgumentException()); + $iriConverterProphecy + ->getIriFromResourceClass(Dummy::class) + ->willReturn('/dummies'); + $iriConverterProphecy + ->getItemFromIri('/dummies/12', Argument::type('array')) + ->willReturn(null); + + $resourceClassResolverProphecy = $this + ->prophesize(ResourceClassResolverInterface::class); + + $serializerProphecy = $this->prophesize(SerializerInterface::class); + $serializerProphecy->willImplement(DenormalizerInterface::class); + + $normalizer = new ItemNormalizer( + $propertyNameCollectionFactoryProphecy->reveal(), + $propertyMetadataFactoryProphecy->reveal(), + $iriConverterProphecy->reveal(), + $resourceClassResolverProphecy->reveal() + ); + $normalizer->setSerializer($serializerProphecy->reveal()); + + $this->assertInstanceOf( + Dummy::class, + $normalizer->denormalize( + ['id' => 12], + Dummy::class, + null, + $context + ) + ); + } + public function testDenormalizeWithIdAndUpdateNotAllowed() { $this->expectException(InvalidArgumentException::class);