Skip to content

Commit dbbac90

Browse files
committed
Fix reset on maxDepth
1 parent 2fe67f5 commit dbbac90

File tree

2 files changed

+76
-5
lines changed

2 files changed

+76
-5
lines changed

src/Operation/Factory/SubresourceOperationFactory.php

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,8 @@ private function computeSubresourceOperations(string $resourceClass, array &$tre
8888
// Handle maxDepth
8989
if ($rootResourceClass === $resourceClass) {
9090
$maxDepth = $subresource->getMaxDepth();
91+
// reset depth when we return to rootResourceClass
92+
$depth = 0;
9193
}
9294

9395
if (null !== $maxDepth && $depth >= $maxDepth) {
@@ -97,11 +99,6 @@ private function computeSubresourceOperations(string $resourceClass, array &$tre
9799
continue;
98100
}
99101

100-
if ($rootResourceClass === $resourceClass) {
101-
// reset depth when we return to rootResourceClass
102-
$depth = 0;
103-
}
104-
105102
$rootResourceMetadata = $this->resourceMetadataFactory->create($rootResourceClass);
106103
$operationName = 'get';
107104
$operation = [

tests/Operation/Factory/SubresourceOperationFactoryTest.php

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
use ApiPlatform\Core\Operation\Factory\SubresourceOperationFactory;
2424
use ApiPlatform\Core\Operation\PathSegmentNameGeneratorInterface;
2525
use ApiPlatform\Core\Tests\Fixtures\DummyEntity;
26+
use ApiPlatform\Core\Tests\Fixtures\DummyEntityFilterAnnotated;
2627
use ApiPlatform\Core\Tests\Fixtures\DummyValidatedEntity;
2728
use ApiPlatform\Core\Tests\Fixtures\RelatedDummyEntity;
2829
use PHPUnit\Framework\TestCase;
@@ -391,6 +392,79 @@ public function testCreateWithMaxDepthMultipleSubresources()
391392
], $subresourceOperationFactory->create(DummyEntity::class));
392393
}
393394

395+
/**
396+
* Test for issue: https://github.com/api-platform/core/issues/2103.
397+
*/
398+
public function testCreateWithMaxDepthMultipleSubresourcesSameMaxDepth()
399+
{
400+
401+
/**
402+
* DummyEntity -subresource (maxDepth=1)-> RelatedDummyEntity -anotherSubresource-> DummyEntity
403+
* DummyEntity -secondSubresource (maxDepth=1)-> dummyValidatedEntity -moreSubresource-> RelatedDummyEntity.
404+
*/
405+
$resourceMetadataFactoryProphecy = $this->prophesize(ResourceMetadataFactoryInterface::class);
406+
$resourceMetadataFactoryProphecy->create(DummyEntity::class)->shouldBeCalled()->willReturn(new ResourceMetadata('dummyEntity'));
407+
$resourceMetadataFactoryProphecy->create(RelatedDummyEntity::class)->shouldBeCalled()->willReturn(new ResourceMetadata('relatedDummyEntity'));
408+
$resourceMetadataFactoryProphecy->create(DummyValidatedEntity::class)->shouldBeCalled()->willReturn(new ResourceMetadata('dummyValidatedEntity'));
409+
410+
411+
$propertyNameCollectionFactoryProphecy = $this->prophesize(PropertyNameCollectionFactoryInterface::class);
412+
$propertyNameCollectionFactoryProphecy->create(DummyEntity::class)->shouldBeCalled()->willReturn(new PropertyNameCollection(['subresource', 'secondSubresource']));
413+
$propertyNameCollectionFactoryProphecy->create(RelatedDummyEntity::class)->shouldBeCalled()->willReturn(new PropertyNameCollection(['bar', 'anotherSubresource']));
414+
$propertyNameCollectionFactoryProphecy->create(DummyValidatedEntity::class)->shouldBeCalled()->willReturn(new PropertyNameCollection(['moreSubresource']));
415+
416+
$subresourceMetadataCollectionWithMaxDepth = (new PropertyMetadata())->withSubresource(new SubresourceMetadata(RelatedDummyEntity::class, false, 1));
417+
$secondSubresourceMetadata = (new PropertyMetadata())->withSubresource(new SubresourceMetadata(DummyValidatedEntity::class, false, 1));
418+
$anotherSubresourceMetadata = (new PropertyMetadata())->withSubresource(new SubresourceMetadata(DummyEntity::class, false));
419+
$moreSubresourceMetadata = (new PropertyMetadata())->withSubresource(new SubresourceMetadata(RelatedDummyEntity::class, false));
420+
421+
$propertyMetadataFactoryProphecy = $this->prophesize(PropertyMetadataFactoryInterface::class);
422+
$propertyMetadataFactoryProphecy->create(DummyEntity::class, 'subresource')->shouldBeCalled()->willReturn($subresourceMetadataCollectionWithMaxDepth);
423+
$propertyMetadataFactoryProphecy->create(DummyEntity::class, 'secondSubresource')->shouldBeCalled()->willReturn($secondSubresourceMetadata);
424+
$propertyMetadataFactoryProphecy->create(RelatedDummyEntity::class, 'bar')->shouldBeCalled()->willReturn(new PropertyMetadata());
425+
$propertyMetadataFactoryProphecy->create(RelatedDummyEntity::class, 'anotherSubresource')->shouldBeCalled()->willReturn($anotherSubresourceMetadata);
426+
$propertyMetadataFactoryProphecy->create(DummyValidatedEntity::class, 'moreSubresource')->shouldBeCalled()->willReturn($moreSubresourceMetadata);
427+
428+
$pathSegmentNameGeneratorProphecy = $this->prophesize(PathSegmentNameGeneratorInterface::class);
429+
$pathSegmentNameGeneratorProphecy->getSegmentName('dummyEntity', true)->shouldBeCalled()->willReturn('dummy_entities');
430+
$pathSegmentNameGeneratorProphecy->getSegmentName('subresource', false)->shouldBeCalled()->willReturn('subresources');
431+
$pathSegmentNameGeneratorProphecy->getSegmentName('secondSubresource', false)->shouldBeCalled()->willReturn('second_subresources');
432+
433+
$subresourceOperationFactory = new SubresourceOperationFactory(
434+
$resourceMetadataFactoryProphecy->reveal(),
435+
$propertyNameCollectionFactoryProphecy->reveal(),
436+
$propertyMetadataFactoryProphecy->reveal(),
437+
$pathSegmentNameGeneratorProphecy->reveal()
438+
);
439+
440+
$this->assertEquals([
441+
'api_dummy_entities_subresource_get_subresource' => [
442+
'property' => 'subresource',
443+
'collection' => false,
444+
'resource_class' => RelatedDummyEntity::class,
445+
'shortNames' => ['relatedDummyEntity', 'dummyEntity'],
446+
'identifiers' => [
447+
['id', DummyEntity::class, true],
448+
],
449+
'route_name' => 'api_dummy_entities_subresource_get_subresource',
450+
'path' => '/dummy_entities/{id}/subresources.{_format}',
451+
'operation_name' => 'subresource_get_subresource',
452+
] + SubresourceOperationFactory::ROUTE_OPTIONS,
453+
'api_dummy_entities_second_subresource_get_subresource' => [
454+
'property' => 'secondSubresource',
455+
'collection' => false,
456+
'resource_class' => DummyValidatedEntity::class,
457+
'shortNames' => ['dummyValidatedEntity', 'dummyEntity'],
458+
'identifiers' => [
459+
['id', DummyEntity::class, true],
460+
],
461+
'route_name' => 'api_dummy_entities_second_subresource_get_subresource',
462+
'path' => '/dummy_entities/{id}/second_subresources.{_format}',
463+
'operation_name' => 'second_subresource_get_subresource',
464+
] + SubresourceOperationFactory::ROUTE_OPTIONS
465+
], $subresourceOperationFactory->create(DummyEntity::class));
466+
}
467+
394468
public function testCreateWithEnd()
395469
{
396470
$resourceMetadataFactoryProphecy = $this->prophesize(ResourceMetadataFactoryInterface::class);

0 commit comments

Comments
 (0)