From a9b5d09bbcc76af51959bfd383f20f022fcb5f3d Mon Sep 17 00:00:00 2001 From: "Nek (Maxime Veber)" Date: Sun, 7 Apr 2019 15:25:51 +0200 Subject: [PATCH] Rework how resource class resolver use inheritance This commits comes with many changes: 1. The resource class resolver now works well with inheritance and is able to resolve resources using the ApiPlatform resource list (more clever) 2. This change adds a new feature: inherited items from api resources now are working as an api, a new behat test proves it 3. some parts of api platform were not compatible because it does not uses the resource resolver but "get class" to get the resource, theses parts are also fixed Notice: the cache from the resource class resolver is removed here. It was introduced in 2015 and was probably a great improvement, but since 2016 resources are not re-genarated on each call to the factory but we call instead a cached factory. This cache was just adding complexity so I removed it. --- features/bootstrap/DoctrineContext.php | 21 +++++ features/main/table_inheritance.feature | 85 +++++++++++++++---- src/Api/IdentifiersExtractor.php | 6 +- src/Api/ResourceClassResolver.php | 36 ++++++-- src/Api/ResourceClassResolverInterface.php | 2 +- .../PublishMercureUpdatesListener.php | 5 +- tests/Api/IdentifiersExtractorTest.php | 1 + tests/Api/ResourceClassResolverTest.php | 28 +++++- .../PublishMercureUpdatesListenerTest.php | 3 + ...mmyTableInheritanceNotApiResourceChild.php | 47 ++++++++++ .../Entity/DummyTableInheritance.php | 7 +- ...mmyTableInheritanceNotApiResourceChild.php | 48 +++++++++++ .../JsonLd/Serializer/ItemNormalizerTest.php | 10 +-- 13 files changed, 260 insertions(+), 39 deletions(-) create mode 100644 tests/Fixtures/TestBundle/Document/DummyTableInheritanceNotApiResourceChild.php create mode 100644 tests/Fixtures/TestBundle/Entity/DummyTableInheritanceNotApiResourceChild.php diff --git a/features/bootstrap/DoctrineContext.php b/features/bootstrap/DoctrineContext.php index cd03b6024d3..f143276c982 100644 --- a/features/bootstrap/DoctrineContext.php +++ b/features/bootstrap/DoctrineContext.php @@ -74,6 +74,8 @@ use ApiPlatform\Core\Tests\Fixtures\TestBundle\Entity\DummyOffer; use ApiPlatform\Core\Tests\Fixtures\TestBundle\Entity\DummyProduct; use ApiPlatform\Core\Tests\Fixtures\TestBundle\Entity\DummyProperty; +use ApiPlatform\Core\Tests\Fixtures\TestBundle\Entity\DummyTableInheritanceNotApiResourceChild; +use ApiPlatform\Core\Tests\Fixtures\TestBundle\Entity\DummyTableInheritanceNotApiResourceChild as DummyTableInheritanceNotApiResourceChildDocument; use ApiPlatform\Core\Tests\Fixtures\TestBundle\Entity\EmbeddableDummy; use ApiPlatform\Core\Tests\Fixtures\TestBundle\Entity\EmbeddedDummy; use ApiPlatform\Core\Tests\Fixtures\TestBundle\Entity\FileConfigDummy; @@ -165,6 +167,17 @@ public function thereAreDummyObjects(int $nb) $this->manager->flush(); } + /** + * @When some dummy table inheritance data but not api resource child are created + */ + public function someDummyTableInheritanceDataButNotApiResourceChildAreCreated() + { + $dummy = $this->buildDummyTableInheritanceNotApiResourceChild(); + $dummy->setName('Foobarbaz inheritance'); + $this->manager->persist($dummy); + $this->manager->flush(); + } + /** * @Given there are :nb foo objects with fake names */ @@ -1272,6 +1285,14 @@ private function buildDummy() return $this->isOrm() ? new Dummy() : new DummyDocument(); } + /** + * @return DummyTableInheritanceNotApiResourceChild|DummyTableInheritanceNotApiResourceChildDocument + */ + private function buildDummyTableInheritanceNotApiResourceChild() + { + return $this->isOrm() ? new DummyTableInheritanceNotApiResourceChild() : new DummyTableInheritanceNotApiResourceChildDocument(); + } + /** * @return DummyAggregateOffer|DummyAggregateOfferDocument */ diff --git a/features/main/table_inheritance.feature b/features/main/table_inheritance.feature index fbcf9e58a51..72b64bed1d0 100644 --- a/features/main/table_inheritance.feature +++ b/features/main/table_inheritance.feature @@ -20,15 +20,18 @@ Feature: Table inheritance "properties": { "@type": { "type": "string", - "pattern": "^DummyTableInheritanceChild$" + "pattern": "^DummyTableInheritanceChild$", + "required": "true" }, "@context": { "type": "string", - "pattern": "^/contexts/DummyTableInheritanceChild$" + "pattern": "^/contexts/DummyTableInheritanceChild$", + "required": "true" }, "@id": { "type": "string", - "pattern": "^/dummy_table_inheritance_children/1$" + "pattern": "^/dummy_table_inheritance_children/1$", + "required": "true" }, "name": { "type": "string", @@ -61,7 +64,8 @@ Feature: Table inheritance "properties": { "@type": { "type": "string", - "pattern": "^DummyTableInheritanceChild$" + "pattern": "^DummyTableInheritanceChild$", + "required": "true" }, "name": { "type": "string", @@ -81,6 +85,40 @@ Feature: Table inheritance """ @createSchema + Scenario: Some children not api resources are created in the app + When some dummy table inheritance data but not api resource child are created + And I send a "GET" request to "/dummy_table_inheritances" + Then the response status code should be 200 + And the response should be in JSON + And the header "Content-Type" should be equal to "application/ld+json; charset=utf-8" + And the JSON should be valid according to this schema: + """ + { + "type": "object", + "properties": { + "hydra:member": { + "type": "array", + "items": { + "type": "object", + "properties": { + "@type": { + "type": "string", + "pattern": "^DummyTableInheritance(Child)?$", + "required": "true" + }, + "name": { + "type": "string", + "required": "true" + } + } + }, + "minItems": 1 + } + }, + "required": ["hydra:member"] + } + """ + Scenario: Create a table inherited resource When I add "Content-Type" header equal to "application/ld+json" And I send a "POST" request to "/dummy_table_inheritance_children" with body: @@ -97,15 +135,18 @@ Feature: Table inheritance "properties": { "@type": { "type": "string", - "pattern": "^DummyTableInheritanceChild$" + "pattern": "^DummyTableInheritanceChild$", + "required": "true" }, "@context": { "type": "string", - "pattern": "^/contexts/DummyTableInheritanceChild$" + "pattern": "^/contexts/DummyTableInheritanceChild$", + "required": "true" }, "@id": { "type": "string", - "pattern": "^/dummy_table_inheritance_children/1$" + "pattern": "^/dummy_table_inheritance_children/1$", + "required": "true" }, "name": { "type": "string", @@ -136,15 +177,18 @@ Feature: Table inheritance "properties": { "@type": { "type": "string", - "pattern": "^DummyTableInheritanceDifferentChild$" + "pattern": "^DummyTableInheritanceDifferentChild$", + "required": "true" }, "@context": { "type": "string", - "pattern": "^/contexts/DummyTableInheritanceDifferentChild$" + "pattern": "^/contexts/DummyTableInheritanceDifferentChild$", + "required": "true" }, "@id": { "type": "string", - "pattern": "^/dummy_table_inheritance_different_children/2$" + "pattern": "^/dummy_table_inheritance_different_children/2$", + "required": "true" }, "name": { "type": "string", @@ -181,15 +225,18 @@ Feature: Table inheritance "properties": { "@type": { "type": "string", - "pattern": "^DummyTableInheritanceRelated$" + "pattern": "^DummyTableInheritanceRelated$", + "required": "true" }, "@context": { "type": "string", - "pattern": "^/contexts/DummyTableInheritanceRelated$" + "pattern": "^/contexts/DummyTableInheritanceRelated$", + "required": "true" }, "@id": { "type": "string", - "pattern": "^/dummy_table_inheritance_relateds/1$" + "pattern": "^/dummy_table_inheritance_relateds/1$", + "required": "true" }, "children": { "items": { @@ -199,7 +246,8 @@ Feature: Table inheritance "properties": { "@type": { "type": "string", - "pattern": "^DummyTableInheritanceChild$" + "pattern": "^DummyTableInheritanceChild$", + "required": "true" }, "name": { "type": "string", @@ -215,7 +263,8 @@ Feature: Table inheritance "properties": { "@type": { "type": "string", - "pattern": "^DummyTableInheritanceDifferentChild$" + "pattern": "^DummyTableInheritanceDifferentChild$", + "required": "true" }, "name": { "type": "string", @@ -255,7 +304,8 @@ Feature: Table inheritance "properties": { "@type": { "type": "string", - "pattern": "^DummyTableInheritanceChild$" + "pattern": "^DummyTableInheritanceChild$", + "required": "true" }, "name": { "type": "string", @@ -271,7 +321,8 @@ Feature: Table inheritance "properties": { "@type": { "type": "string", - "pattern": "^DummyTableInheritanceDifferentChild$" + "pattern": "^DummyTableInheritanceDifferentChild$", + "required": "true" }, "name": { "type": "string", diff --git a/src/Api/IdentifiersExtractor.php b/src/Api/IdentifiersExtractor.php index 31f493f7520..981fdb9defd 100644 --- a/src/Api/IdentifiersExtractor.php +++ b/src/Api/IdentifiersExtractor.php @@ -67,8 +67,10 @@ public function getIdentifiersFromResourceClass(string $resourceClass): array public function getIdentifiersFromItem($item): array { $identifiers = []; - $type = $this->getObjectClass($item); - $resourceClass = $this->resourceClassResolver->isResourceClass($type) ? $this->resourceClassResolver->getResourceClass($item) : $type; + $resourceClass = $this->getObjectClass($item); + if (null !== $this->resourceClassResolver) { // BC Layer + $resourceClass = $this->resourceClassResolver->isResourceClass($resourceClass) ? $this->resourceClassResolver->getResourceClass($item) : $resourceClass; + } foreach ($this->propertyNameCollectionFactory->create($resourceClass) as $propertyName) { $propertyMetadata = $this->propertyMetadataFactory->create($resourceClass, $propertyName); diff --git a/src/Api/ResourceClassResolver.php b/src/Api/ResourceClassResolver.php index 98e88fb1e4e..c932e8c53fe 100644 --- a/src/Api/ResourceClassResolver.php +++ b/src/Api/ResourceClassResolver.php @@ -28,7 +28,6 @@ final class ResourceClassResolver implements ResourceClassResolverInterface use ClassInfoTrait; private $resourceNameCollectionFactory; - private $localIsResourceClassCache = []; public function __construct(ResourceNameCollectionFactoryInterface $resourceNameCollectionFactory) { @@ -56,20 +55,27 @@ public function getResourceClass($value, string $resourceClass = null, bool $str $resolvedResourceClass = $currentResourceClass; } } + if (null !== $resolvedResourceClass) { $resourceClass = $resolvedResourceClass; } + $typeIsStrictResourceClass = $this->isStrictResourceClass($type); + if ($strict && $typeIsStrictResourceClass) { + return $type; + } + + $typeIsResourceClass = $this->isResourceClass($type); if ( null === $type - || ((!$strict || $resourceClass === $type) && $isResourceClass = $this->isResourceClass($type)) - || null !== $resolvedResourceClass && interface_exists($resourceClass) + || (((!$strict || $resourceClass === $type)) && $typeIsResourceClass) + || null !== $resolvedResourceClass && (interface_exists($resourceClass) || !$typeIsStrictResourceClass) ) { return $resourceClass; } if ( - ($isResourceClass ?? $this->isResourceClass($type)) + $typeIsResourceClass || (is_subclass_of($type, $resourceClass) && $this->isResourceClass($resourceClass)) ) { return $type; @@ -83,16 +89,28 @@ public function getResourceClass($value, string $resourceClass = null, bool $str */ public function isResourceClass(string $type): bool { - if (isset($this->localIsResourceClassCache[$type])) { - return $this->localIsResourceClassCache[$type]; + foreach ($this->resourceNameCollectionFactory->create() as $resourceClass) { + if ($type === $resourceClass || is_subclass_of($type, $resourceClass)) { + return true; + } } + return false; + } + + /** + * Same of isResourceClass but more strict: it ignores inheritance. + * + * @param string $type FQCN of an object + */ + private function isStrictResourceClass(string $type): bool + { foreach ($this->resourceNameCollectionFactory->create() as $resourceClass) { - if ($type === $resourceClass || is_subclass_of($type, $resourceClass)) { - return $this->localIsResourceClassCache[$type] = true; + if ($type === $resourceClass) { + return true; } } - return $this->localIsResourceClassCache[$type] = false; + return false; } } diff --git a/src/Api/ResourceClassResolverInterface.php b/src/Api/ResourceClassResolverInterface.php index 1bf900bfec8..1555b4f0086 100644 --- a/src/Api/ResourceClassResolverInterface.php +++ b/src/Api/ResourceClassResolverInterface.php @@ -25,7 +25,7 @@ interface ResourceClassResolverInterface /** * Guesses the associated resource. * - * @param object $value Object you're playing with + * @param mixed $value Object you're playing with * @param string $resourceClass Resource class it is supposed to be (could be parent class for instance) * @param bool $strict value must be type of resource class given or it will return type * diff --git a/src/Bridge/Doctrine/EventListener/PublishMercureUpdatesListener.php b/src/Bridge/Doctrine/EventListener/PublishMercureUpdatesListener.php index 805e2585baa..87f3952d683 100644 --- a/src/Bridge/Doctrine/EventListener/PublishMercureUpdatesListener.php +++ b/src/Bridge/Doctrine/EventListener/PublishMercureUpdatesListener.php @@ -121,7 +121,10 @@ private function reset(): void private function storeEntityToPublish($entity, string $property): void { $resourceClass = $this->getObjectClass($entity); - if (!$this->resourceClassResolver->isResourceClass($resourceClass)) { + + if ($this->resourceClassResolver->isResourceClass($resourceClass)) { + $resourceClass = $this->resourceClassResolver->getResourceClass($entity); + } else { return; } diff --git a/tests/Api/IdentifiersExtractorTest.php b/tests/Api/IdentifiersExtractorTest.php index 878f881f196..de5462afcc5 100644 --- a/tests/Api/IdentifiersExtractorTest.php +++ b/tests/Api/IdentifiersExtractorTest.php @@ -179,6 +179,7 @@ private function getResourceClassResolver() $resourceClassResolver->isResourceClass(Argument::type('string'))->will(function ($args) { return !(Uuid::class === $args[0]); }); + $resourceClassResolver->getResourceClass(Argument::any())->will(function ($args) {return \get_class($args[0]); }); return $resourceClassResolver->reveal(); } diff --git a/tests/Api/ResourceClassResolverTest.php b/tests/Api/ResourceClassResolverTest.php index 025a43afa77..6a3350c348a 100644 --- a/tests/Api/ResourceClassResolverTest.php +++ b/tests/Api/ResourceClassResolverTest.php @@ -24,6 +24,7 @@ use ApiPlatform\Core\Tests\Fixtures\TestBundle\Entity\DummyCar; use ApiPlatform\Core\Tests\Fixtures\TestBundle\Entity\DummyTableInheritance; use ApiPlatform\Core\Tests\Fixtures\TestBundle\Entity\DummyTableInheritanceChild; +use ApiPlatform\Core\Tests\Fixtures\TestBundle\Entity\DummyTableInheritanceNotApiResourceChild; use PHPUnit\Framework\TestCase; /** @@ -175,13 +176,12 @@ public function testGetResourceClassWithChildResource() public function testGetResourceClassWithInterfaceResource() { - $this->expectException(InvalidArgumentException::class); - $this->expectExceptionMessage("The given object's resource is the interface \"ApiPlatform\Core\Tests\Fixtures\DummyResourceInterface\", finding a class is not possible."); $dummy = new DummyResourceImplementation(); $resourceNameCollectionFactoryProphecy = $this->prophesize(ResourceNameCollectionFactoryInterface::class); + $resourceNameCollectionFactoryProphecy->create()->willReturn(new ResourceNameCollection([DummyResourceInterface::class]))->shouldBeCalled(); $resourceClassResolver = new ResourceClassResolver($resourceNameCollectionFactoryProphecy->reveal()); - $resourceClassResolver->getResourceClass($dummy, DummyResourceInterface::class, true); + $this->assertEquals(DummyResourceInterface::class, $resourceClassResolver->getResourceClass($dummy, DummyResourceInterface::class, true)); } public function testGetResourceClassWithoutSecondParameterIsAccurate() @@ -212,4 +212,26 @@ public function testInterfaceCanBeResourceClass() $resourceClassResolver = new ResourceClassResolver($resourceNameCollectionFactoryProphecy->reveal()); $this->assertTrue($resourceClassResolver->isResourceClass(DummyResourceImplementation::class)); } + + public function testItResolveParentResourceClassOfChildrenOfResourceClasses() + { + $dummy = new DummyTableInheritanceNotApiResourceChild(); + $resourceNameCollectionFactoryProphecy = $this->prophesize(ResourceNameCollectionFactoryInterface::class); + $resourceNameCollectionFactoryProphecy->create()->willReturn(new ResourceNameCollection([DummyTableInheritance::class]))->shouldBeCalled(); + + $resourceClassResolver = new ResourceClassResolver($resourceNameCollectionFactoryProphecy->reveal()); +// $this->assertTrue($resourceClassResolver->isResourceClass(DummyTableInheritanceNotApiResourceChild::class)); +// $this->assertEquals(DummyTableInheritance::class, $resourceClassResolver->getResourceClass($dummy)); + $this->assertEquals(DummyTableInheritance::class, $resourceClassResolver->getResourceClass($dummy, DummyTableInheritance::class, true)); + } + + public function testItResolveChildWhenParentAndChildrenAreResourcesAndIsStrict() + { + $dummy = new DummyTableInheritanceChild(); + $resourceNameCollectionFactoryProphecy = $this->prophesize(ResourceNameCollectionFactoryInterface::class); + $resourceNameCollectionFactoryProphecy->create()->willReturn(new ResourceNameCollection([DummyTableInheritance::class, DummyTableInheritanceChild::class]))->shouldBeCalled(); + + $resourceClassResolver = new ResourceClassResolver($resourceNameCollectionFactoryProphecy->reveal()); + $this->assertEquals(DummyTableInheritanceChild::class, $resourceClassResolver->getResourceClass($dummy, DummyTableInheritance::class, true)); + } } diff --git a/tests/Bridge/Doctrine/EventListener/PublishMercureUpdatesListenerTest.php b/tests/Bridge/Doctrine/EventListener/PublishMercureUpdatesListenerTest.php index 632338a845e..82d84d8735f 100644 --- a/tests/Bridge/Doctrine/EventListener/PublishMercureUpdatesListenerTest.php +++ b/tests/Bridge/Doctrine/EventListener/PublishMercureUpdatesListenerTest.php @@ -28,6 +28,7 @@ use Doctrine\ORM\Event\OnFlushEventArgs; use Doctrine\ORM\UnitOfWork; use PHPUnit\Framework\TestCase; +use Prophecy\Argument; use Symfony\Component\Mercure\Update; use Symfony\Component\Serializer\SerializerInterface; @@ -56,6 +57,7 @@ public function testPublishUpdate() $resourceClassResolverProphecy->isResourceClass(NotAResource::class)->willReturn(false); $resourceClassResolverProphecy->isResourceClass(DummyCar::class)->willReturn(true); $resourceClassResolverProphecy->isResourceClass(DummyFriend::class)->willReturn(true); + $resourceClassResolverProphecy->getResourceClass(Argument::type('object'))->will(function ($args) { return \get_class($args[0]); }); $iriConverterProphecy = $this->prophesize(IriConverterInterface::class); $iriConverterProphecy->getIriFromItem($toInsert, UrlGeneratorInterface::ABS_URL)->willReturn('http://example.com/dummies/1')->shouldBeCalled(); @@ -136,6 +138,7 @@ public function testInvalidMercureAttribute() $resourceClassResolverProphecy = $this->prophesize(ResourceClassResolverInterface::class); $resourceClassResolverProphecy->isResourceClass(Dummy::class)->willReturn(true); + $resourceClassResolverProphecy->getResourceClass(Argument::type('object'))->will(function ($args) { return \get_class($args[0]); }); $iriConverterProphecy = $this->prophesize(IriConverterInterface::class); diff --git a/tests/Fixtures/TestBundle/Document/DummyTableInheritanceNotApiResourceChild.php b/tests/Fixtures/TestBundle/Document/DummyTableInheritanceNotApiResourceChild.php new file mode 100644 index 00000000000..046381598f7 --- /dev/null +++ b/tests/Fixtures/TestBundle/Document/DummyTableInheritanceNotApiResourceChild.php @@ -0,0 +1,47 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace ApiPlatform\Core\Tests\Fixtures\TestBundle\Document; + +use Doctrine\ODM\MongoDB\Mapping\Annotations as ODM; + +/** + * @ODM\Document + */ +class DummyTableInheritanceNotApiResourceChild extends DummyTableInheritance +{ + /** + * Considering this class is not an ApiResource, what should be render is only parent fields. + * + * @var bool The dummy swagg + * + * @ODM\Field(type="boolean") + */ + private $swaggerThanParent; + + public function __construct() + { + // Definitely always swagger than parents + $this->swaggerThanParent = true; + } + + public function isSwaggerThanParent(): bool + { + return $this->swaggerThanParent; + } + + public function setSwaggerThanParent(bool $swaggerThanParent) + { + $this->swaggerThanParent = $swaggerThanParent; + } +} diff --git a/tests/Fixtures/TestBundle/Entity/DummyTableInheritance.php b/tests/Fixtures/TestBundle/Entity/DummyTableInheritance.php index 4a208281425..23b629d541d 100644 --- a/tests/Fixtures/TestBundle/Entity/DummyTableInheritance.php +++ b/tests/Fixtures/TestBundle/Entity/DummyTableInheritance.php @@ -21,7 +21,12 @@ * @ORM\Entity * @ORM\InheritanceType("JOINED") * @ORM\DiscriminatorColumn(name="discr", type="string") - * @ORM\DiscriminatorMap({"dummyTableInheritance"="DummyTableInheritance", "dummyTableInheritanceChild"="DummyTableInheritanceChild", "dummyTableInheritanceDifferentChild"="DummyTableInheritanceDifferentChild"}) + * @ORM\DiscriminatorMap({ + * "dummyTableInheritance"="DummyTableInheritance", + * "dummyTableInheritanceChild"="DummyTableInheritanceChild", + * "dummyTableInheritanceDifferentChild"="DummyTableInheritanceDifferentChild", + * "dummyTableInheritanceNotApiResourceChild"="DummyTableInheritanceNotApiResourceChild" + * }) * @ApiResource */ class DummyTableInheritance diff --git a/tests/Fixtures/TestBundle/Entity/DummyTableInheritanceNotApiResourceChild.php b/tests/Fixtures/TestBundle/Entity/DummyTableInheritanceNotApiResourceChild.php new file mode 100644 index 00000000000..0ae63213898 --- /dev/null +++ b/tests/Fixtures/TestBundle/Entity/DummyTableInheritanceNotApiResourceChild.php @@ -0,0 +1,48 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace ApiPlatform\Core\Tests\Fixtures\TestBundle\Entity; + +use ApiPlatform\Core\Annotation\ApiResource; +use Doctrine\ORM\Mapping as ORM; + +/** + * @ORM\Entity + */ +class DummyTableInheritanceNotApiResourceChild extends DummyTableInheritance +{ + /** + * Considering this class is not an ApiResource, what should be render is only parent fields. + * + * @var bool The dummy swagg + * + * @ORM\Column(type="boolean") + */ + private $swaggerThanParent; + + public function __construct() + { + // Definitely always swagger than parents + $this->swaggerThanParent = true; + } + + public function isSwaggerThanParent(): bool + { + return $this->swaggerThanParent; + } + + public function setSwaggerThanParent(bool $swaggerThanParent) + { + $this->swaggerThanParent = $swaggerThanParent; + } +} diff --git a/tests/JsonLd/Serializer/ItemNormalizerTest.php b/tests/JsonLd/Serializer/ItemNormalizerTest.php index fb5b1bf984f..7ebf2de6644 100644 --- a/tests/JsonLd/Serializer/ItemNormalizerTest.php +++ b/tests/JsonLd/Serializer/ItemNormalizerTest.php @@ -13,8 +13,8 @@ namespace ApiPlatform\Core\Tests\JsonLd\Serializer; -use ApiPlatform\Core\Api\IriConverterInterface; use ApiPlatform\Core\Api\ResourceClassResolverInterface; +use ApiPlatform\Core\Api\ResourceIriConverterInterface; use ApiPlatform\Core\JsonLd\ContextBuilderInterface; use ApiPlatform\Core\JsonLd\Serializer\ItemNormalizer; use ApiPlatform\Core\Metadata\Property\Factory\PropertyMetadataFactoryInterface; @@ -42,7 +42,7 @@ public function testDontSupportDenormalization() $resourceMetadataFactoryProphecy = $this->prophesize(ResourceMetadataFactoryInterface::class); $propertyNameCollectionFactoryProphecy = $this->prophesize(PropertyNameCollectionFactoryInterface::class); $propertyMetadataFactoryProphecy = $this->prophesize(PropertyMetadataFactoryInterface::class); - $iriConverterProphecy = $this->prophesize(IriConverterInterface::class); + $iriConverterProphecy = $this->prophesize(ResourceIriConverterInterface::class); $resourceClassResolverProphecy = $this->prophesize(ResourceClassResolverInterface::class); $contextBuilderProphecy = $this->prophesize(ContextBuilderInterface::class); $resourceClassResolverProphecy->getResourceClass(['dummy'], 'Dummy')->willReturn(Dummy::class); @@ -66,7 +66,7 @@ public function testSupportNormalization() $resourceMetadataFactoryProphecy = $this->prophesize(ResourceMetadataFactoryInterface::class); $propertyNameCollectionFactoryProphecy = $this->prophesize(PropertyNameCollectionFactoryInterface::class); $propertyMetadataFactoryProphecy = $this->prophesize(PropertyMetadataFactoryInterface::class); - $iriConverterProphecy = $this->prophesize(IriConverterInterface::class); + $iriConverterProphecy = $this->prophesize(ResourceIriConverterInterface::class); $contextBuilderProphecy = $this->prophesize(ContextBuilderInterface::class); $resourceClassResolverProphecy = $this->prophesize(ResourceClassResolverInterface::class); @@ -103,8 +103,8 @@ public function testNormalize() $propertyMetadataFactoryProphecy = $this->prophesize(PropertyMetadataFactoryInterface::class); $propertyMetadataFactoryProphecy->create(Dummy::class, 'name', [])->willReturn($propertyMetadata)->shouldBeCalled(); - $iriConverterProphecy = $this->prophesize(IriConverterInterface::class); - $iriConverterProphecy->getIriFromItem($dummy)->willReturn('/dummies/1988')->shouldBeCalled(); + $iriConverterProphecy = $this->prophesize(ResourceIriConverterInterface::class); + $iriConverterProphecy->getIriFromItemWithResource($dummy, Argument::type('string'))->willReturn('/dummies/1988')->shouldBeCalled(); $resourceClassResolverProphecy = $this->prophesize(ResourceClassResolverInterface::class); $resourceClassResolverProphecy->getResourceClass($dummy, null, true)->willReturn(Dummy::class)->shouldBeCalled();