Skip to content

Commit fed77b5

Browse files
authored
Merge pull request #2164 from MoltenCoreIO/fix-subresourcesMaxDepthReset
Fix reset on maxDepth
2 parents 2fe67f5 + 7830c2d commit fed77b5

File tree

3 files changed

+116
-6
lines changed

3 files changed

+116
-6
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/Fixtures/DummyEntityFilterAnnotated.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
<?php
22

3-
43
/*
54
* This file is part of the API Platform project.
65
*

tests/Operation/Factory/SubresourceOperationFactoryTest.php

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -391,6 +391,120 @@ public function testCreateWithMaxDepthMultipleSubresources()
391391
], $subresourceOperationFactory->create(DummyEntity::class));
392392
}
393393

394+
/**
395+
* Test for issue: https://github.com/api-platform/core/issues/2103.
396+
*/
397+
public function testCreateWithMaxDepthMultipleSubresourcesSameMaxDepth()
398+
{
399+
/**
400+
* DummyEntity -subresource (maxDepth=1)-> RelatedDummyEntity -anotherSubresource-> DummyEntity
401+
* DummyEntity -secondSubresource (maxDepth=1)-> dummyValidatedEntity -moreSubresource-> RelatedDummyEntity.
402+
*/
403+
$resourceMetadataFactoryProphecy = $this->prophesize(ResourceMetadataFactoryInterface::class);
404+
$resourceMetadataFactoryProphecy->create(DummyEntity::class)->shouldBeCalled()->willReturn(new ResourceMetadata('dummyEntity'));
405+
$resourceMetadataFactoryProphecy->create(RelatedDummyEntity::class)->shouldBeCalled()->willReturn(new ResourceMetadata('relatedDummyEntity'));
406+
$resourceMetadataFactoryProphecy->create(DummyValidatedEntity::class)->shouldBeCalled()->willReturn(new ResourceMetadata('dummyValidatedEntity'));
407+
408+
$propertyNameCollectionFactoryProphecy = $this->prophesize(PropertyNameCollectionFactoryInterface::class);
409+
$propertyNameCollectionFactoryProphecy->create(DummyEntity::class)->shouldBeCalled()->willReturn(new PropertyNameCollection(['subresource', 'secondSubresource']));
410+
$propertyNameCollectionFactoryProphecy->create(RelatedDummyEntity::class)->shouldBeCalled()->willReturn(new PropertyNameCollection(['bar', 'anotherSubresource']));
411+
$propertyNameCollectionFactoryProphecy->create(DummyValidatedEntity::class)->shouldBeCalled()->willReturn(new PropertyNameCollection(['moreSubresource']));
412+
413+
$subresourceMetadataCollectionWithMaxDepth = (new PropertyMetadata())->withSubresource(new SubresourceMetadata(RelatedDummyEntity::class, false, 1));
414+
$secondSubresourceMetadata = (new PropertyMetadata())->withSubresource(new SubresourceMetadata(DummyValidatedEntity::class, false, 1));
415+
$anotherSubresourceMetadata = (new PropertyMetadata())->withSubresource(new SubresourceMetadata(DummyEntity::class, false));
416+
$moreSubresourceMetadata = (new PropertyMetadata())->withSubresource(new SubresourceMetadata(RelatedDummyEntity::class, false));
417+
418+
$propertyMetadataFactoryProphecy = $this->prophesize(PropertyMetadataFactoryInterface::class);
419+
$propertyMetadataFactoryProphecy->create(DummyEntity::class, 'subresource')->shouldBeCalled()->willReturn($subresourceMetadataCollectionWithMaxDepth);
420+
$propertyMetadataFactoryProphecy->create(DummyEntity::class, 'secondSubresource')->shouldBeCalled()->willReturn($secondSubresourceMetadata);
421+
$propertyMetadataFactoryProphecy->create(RelatedDummyEntity::class, 'bar')->shouldBeCalled()->willReturn(new PropertyMetadata());
422+
$propertyMetadataFactoryProphecy->create(RelatedDummyEntity::class, 'anotherSubresource')->shouldBeCalled()->willReturn($anotherSubresourceMetadata);
423+
$propertyMetadataFactoryProphecy->create(DummyValidatedEntity::class, 'moreSubresource')->shouldBeCalled()->willReturn($moreSubresourceMetadata);
424+
425+
$pathSegmentNameGeneratorProphecy = $this->prophesize(PathSegmentNameGeneratorInterface::class);
426+
$pathSegmentNameGeneratorProphecy->getSegmentName('dummyEntity', true)->shouldBeCalled()->willReturn('dummy_entities');
427+
$pathSegmentNameGeneratorProphecy->getSegmentName('subresource', false)->shouldBeCalled()->willReturn('subresources');
428+
$pathSegmentNameGeneratorProphecy->getSegmentName('secondSubresource', false)->shouldBeCalled()->willReturn('second_subresources');
429+
430+
$subresourceOperationFactory = new SubresourceOperationFactory(
431+
$resourceMetadataFactoryProphecy->reveal(),
432+
$propertyNameCollectionFactoryProphecy->reveal(),
433+
$propertyMetadataFactoryProphecy->reveal(),
434+
$pathSegmentNameGeneratorProphecy->reveal()
435+
);
436+
437+
$this->assertEquals([
438+
'api_dummy_entities_subresource_get_subresource' => [
439+
'property' => 'subresource',
440+
'collection' => false,
441+
'resource_class' => RelatedDummyEntity::class,
442+
'shortNames' => ['relatedDummyEntity', 'dummyEntity'],
443+
'identifiers' => [
444+
['id', DummyEntity::class, true],
445+
],
446+
'route_name' => 'api_dummy_entities_subresource_get_subresource',
447+
'path' => '/dummy_entities/{id}/subresources.{_format}',
448+
'operation_name' => 'subresource_get_subresource',
449+
] + SubresourceOperationFactory::ROUTE_OPTIONS,
450+
'api_dummy_entities_second_subresource_get_subresource' => [
451+
'property' => 'secondSubresource',
452+
'collection' => false,
453+
'resource_class' => DummyValidatedEntity::class,
454+
'shortNames' => ['dummyValidatedEntity', 'dummyEntity'],
455+
'identifiers' => [
456+
['id', DummyEntity::class, true],
457+
],
458+
'route_name' => 'api_dummy_entities_second_subresource_get_subresource',
459+
'path' => '/dummy_entities/{id}/second_subresources.{_format}',
460+
'operation_name' => 'second_subresource_get_subresource',
461+
] + SubresourceOperationFactory::ROUTE_OPTIONS,
462+
], $subresourceOperationFactory->create(DummyEntity::class));
463+
}
464+
465+
public function testCreateSelfReferencingSubresources()
466+
{
467+
/**
468+
* DummyEntity -subresource-> DummyEntity -subresource-> DummyEntity ...
469+
*/
470+
$resourceMetadataFactoryProphecy = $this->prophesize(ResourceMetadataFactoryInterface::class);
471+
$resourceMetadataFactoryProphecy->create(DummyEntity::class)->shouldBeCalled()->willReturn(new ResourceMetadata('dummyEntity'));
472+
473+
$propertyNameCollectionFactoryProphecy = $this->prophesize(PropertyNameCollectionFactoryInterface::class);
474+
$propertyNameCollectionFactoryProphecy->create(DummyEntity::class)->shouldBeCalled()->willReturn(new PropertyNameCollection(['subresource']));
475+
476+
$subresource = (new PropertyMetadata())->withSubresource(new SubresourceMetadata(DummyEntity::class, false));
477+
478+
$propertyMetadataFactoryProphecy = $this->prophesize(PropertyMetadataFactoryInterface::class);
479+
$propertyMetadataFactoryProphecy->create(DummyEntity::class, 'subresource')->shouldBeCalled()->willReturn($subresource);
480+
481+
$pathSegmentNameGeneratorProphecy = $this->prophesize(PathSegmentNameGeneratorInterface::class);
482+
$pathSegmentNameGeneratorProphecy->getSegmentName('dummyEntity', true)->shouldBeCalled()->willReturn('dummy_entities');
483+
$pathSegmentNameGeneratorProphecy->getSegmentName('subresource', false)->shouldBeCalled()->willReturn('subresources');
484+
485+
$subresourceOperationFactory = new SubresourceOperationFactory(
486+
$resourceMetadataFactoryProphecy->reveal(),
487+
$propertyNameCollectionFactoryProphecy->reveal(),
488+
$propertyMetadataFactoryProphecy->reveal(),
489+
$pathSegmentNameGeneratorProphecy->reveal()
490+
);
491+
492+
$this->assertEquals([
493+
'api_dummy_entities_subresource_get_subresource' => [
494+
'property' => 'subresource',
495+
'collection' => false,
496+
'resource_class' => DummyEntity::class,
497+
'shortNames' => ['dummyEntity'],
498+
'identifiers' => [
499+
['id', DummyEntity::class, true],
500+
],
501+
'route_name' => 'api_dummy_entities_subresource_get_subresource',
502+
'path' => '/dummy_entities/{id}/subresources.{_format}',
503+
'operation_name' => 'subresource_get_subresource',
504+
] + SubresourceOperationFactory::ROUTE_OPTIONS,
505+
], $subresourceOperationFactory->create(DummyEntity::class));
506+
}
507+
394508
public function testCreateWithEnd()
395509
{
396510
$resourceMetadataFactoryProphecy = $this->prophesize(ResourceMetadataFactoryInterface::class);

0 commit comments

Comments
 (0)