From d8e624ba242593365773ec8070d92f548f77d575 Mon Sep 17 00:00:00 2001 From: Alan Poulain Date: Mon, 7 Oct 2019 15:24:41 +0200 Subject: [PATCH] Possibility to add execute options for MongoDB (#3144) --- CHANGELOG.md | 4 + .../MongoDbOdm/CollectionDataProvider.php | 11 +- .../Extension/PaginationExtension.php | 11 +- .../Doctrine/MongoDbOdm/ItemDataProvider.php | 11 +- .../MongoDbOdm/SubresourceDataProvider.php | 19 +- .../Resources/config/doctrine_mongodb_odm.xml | 5 +- .../MongoDbOdm/CollectionDataProviderTest.php | 72 ++++++-- .../Extension/PaginationExtensionTest.php | 162 ++++++++++++------ .../MongoDbOdm/ItemDataProviderTest.php | 72 +++++++- .../SubresourceDataProviderTest.php | 153 +++++++++++++++-- tests/Fixtures/TestBundle/Document/Dummy.php | 5 + 11 files changed, 427 insertions(+), 98 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2a1fa17ab58..b3bb0b0e374 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## 2.6.0 + +* MongoDB: Possibility to add execute options (aggregate command fields) for a resource, like `allowDiskUse` (#3144) + ## 2.5.0 * Fix BC-break when using short-syntax notation for `access_control` diff --git a/src/Bridge/Doctrine/MongoDbOdm/CollectionDataProvider.php b/src/Bridge/Doctrine/MongoDbOdm/CollectionDataProvider.php index da4dac68ba5..b8820439d8a 100644 --- a/src/Bridge/Doctrine/MongoDbOdm/CollectionDataProvider.php +++ b/src/Bridge/Doctrine/MongoDbOdm/CollectionDataProvider.php @@ -18,6 +18,7 @@ use ApiPlatform\Core\DataProvider\CollectionDataProviderInterface; use ApiPlatform\Core\DataProvider\RestrictedDataProviderInterface; use ApiPlatform\Core\Exception\RuntimeException; +use ApiPlatform\Core\Metadata\Resource\Factory\ResourceMetadataFactoryInterface; use Doctrine\Common\Persistence\ManagerRegistry; use Doctrine\ODM\MongoDB\DocumentManager; use Doctrine\ODM\MongoDB\Repository\DocumentRepository; @@ -32,14 +33,16 @@ final class CollectionDataProvider implements CollectionDataProviderInterface, RestrictedDataProviderInterface { private $managerRegistry; + private $resourceMetadataFactory; private $collectionExtensions; /** * @param AggregationCollectionExtensionInterface[] $collectionExtensions */ - public function __construct(ManagerRegistry $managerRegistry, iterable $collectionExtensions = []) + public function __construct(ManagerRegistry $managerRegistry, ResourceMetadataFactoryInterface $resourceMetadataFactory, iterable $collectionExtensions = []) { $this->managerRegistry = $managerRegistry; + $this->resourceMetadataFactory = $resourceMetadataFactory; $this->collectionExtensions = $collectionExtensions; } @@ -72,6 +75,10 @@ public function getCollection(string $resourceClass, string $operationName = nul } } - return $aggregationBuilder->hydrate($resourceClass)->execute(); + $resourceMetadata = $this->resourceMetadataFactory->create($resourceClass); + $attribute = $resourceMetadata->getCollectionOperationAttribute($operationName, 'doctrine_mongodb', [], true); + $executeOptions = $attribute['execute_options'] ?? []; + + return $aggregationBuilder->hydrate($resourceClass)->execute($executeOptions); } } diff --git a/src/Bridge/Doctrine/MongoDbOdm/Extension/PaginationExtension.php b/src/Bridge/Doctrine/MongoDbOdm/Extension/PaginationExtension.php index 75215bbeb61..80399ffbc20 100644 --- a/src/Bridge/Doctrine/MongoDbOdm/Extension/PaginationExtension.php +++ b/src/Bridge/Doctrine/MongoDbOdm/Extension/PaginationExtension.php @@ -16,6 +16,7 @@ use ApiPlatform\Core\Bridge\Doctrine\MongoDbOdm\Paginator; use ApiPlatform\Core\DataProvider\Pagination; use ApiPlatform\Core\Exception\RuntimeException; +use ApiPlatform\Core\Metadata\Resource\Factory\ResourceMetadataFactoryInterface; use Doctrine\Common\Persistence\ManagerRegistry; use Doctrine\ODM\MongoDB\Aggregation\Builder; use Doctrine\ODM\MongoDB\DocumentManager; @@ -33,11 +34,13 @@ final class PaginationExtension implements AggregationResultCollectionExtensionInterface { private $managerRegistry; + private $resourceMetadataFactory; private $pagination; - public function __construct(ManagerRegistry $managerRegistry, Pagination $pagination) + public function __construct(ManagerRegistry $managerRegistry, ResourceMetadataFactoryInterface $resourceMetadataFactory, Pagination $pagination) { $this->managerRegistry = $managerRegistry; + $this->resourceMetadataFactory = $resourceMetadataFactory; $this->pagination = $pagination; } @@ -113,7 +116,11 @@ public function getResult(Builder $aggregationBuilder, string $resourceClass, st throw new RuntimeException(sprintf('The manager for "%s" must be an instance of "%s".', $resourceClass, DocumentManager::class)); } - return new Paginator($aggregationBuilder->execute(), $manager->getUnitOfWork(), $resourceClass, $aggregationBuilder->getPipeline()); + $resourceMetadata = $this->resourceMetadataFactory->create($resourceClass); + $attribute = $resourceMetadata->getCollectionOperationAttribute($operationName, 'doctrine_mongodb', [], true); + $executeOptions = $attribute['execute_options'] ?? []; + + return new Paginator($aggregationBuilder->execute($executeOptions), $manager->getUnitOfWork(), $resourceClass, $aggregationBuilder->getPipeline()); } private function addCountToContext(Builder $aggregationBuilder, array $context): array diff --git a/src/Bridge/Doctrine/MongoDbOdm/ItemDataProvider.php b/src/Bridge/Doctrine/MongoDbOdm/ItemDataProvider.php index 9dcc53f35e1..12db2dda163 100644 --- a/src/Bridge/Doctrine/MongoDbOdm/ItemDataProvider.php +++ b/src/Bridge/Doctrine/MongoDbOdm/ItemDataProvider.php @@ -22,6 +22,7 @@ use ApiPlatform\Core\Identifier\IdentifierConverterInterface; use ApiPlatform\Core\Metadata\Property\Factory\PropertyMetadataFactoryInterface; use ApiPlatform\Core\Metadata\Property\Factory\PropertyNameCollectionFactoryInterface; +use ApiPlatform\Core\Metadata\Resource\Factory\ResourceMetadataFactoryInterface; use Doctrine\Common\Persistence\ManagerRegistry; use Doctrine\ODM\MongoDB\DocumentManager; use Doctrine\ODM\MongoDB\Repository\DocumentRepository; @@ -38,14 +39,16 @@ final class ItemDataProvider implements DenormalizedIdentifiersAwareItemDataProv use IdentifierManagerTrait; private $managerRegistry; + private $resourceMetadataFactory; private $itemExtensions; /** * @param AggregationItemExtensionInterface[] $itemExtensions */ - public function __construct(ManagerRegistry $managerRegistry, PropertyNameCollectionFactoryInterface $propertyNameCollectionFactory, PropertyMetadataFactoryInterface $propertyMetadataFactory, iterable $itemExtensions = []) + public function __construct(ManagerRegistry $managerRegistry, ResourceMetadataFactoryInterface $resourceMetadataFactory, PropertyNameCollectionFactoryInterface $propertyNameCollectionFactory, PropertyMetadataFactoryInterface $propertyMetadataFactory, iterable $itemExtensions = []) { $this->managerRegistry = $managerRegistry; + $this->resourceMetadataFactory = $resourceMetadataFactory; $this->propertyNameCollectionFactory = $propertyNameCollectionFactory; $this->propertyMetadataFactory = $propertyMetadataFactory; $this->itemExtensions = $itemExtensions; @@ -95,6 +98,10 @@ public function getItem(string $resourceClass, $id, string $operationName = null } } - return $aggregationBuilder->hydrate($resourceClass)->execute()->current() ?: null; + $resourceMetadata = $this->resourceMetadataFactory->create($resourceClass); + $attribute = $resourceMetadata->getItemOperationAttribute($operationName, 'doctrine_mongodb', [], true); + $executeOptions = $attribute['execute_options'] ?? []; + + return $aggregationBuilder->hydrate($resourceClass)->execute($executeOptions)->current() ?: null; } } diff --git a/src/Bridge/Doctrine/MongoDbOdm/SubresourceDataProvider.php b/src/Bridge/Doctrine/MongoDbOdm/SubresourceDataProvider.php index 2c490deb456..beceaf0a22d 100644 --- a/src/Bridge/Doctrine/MongoDbOdm/SubresourceDataProvider.php +++ b/src/Bridge/Doctrine/MongoDbOdm/SubresourceDataProvider.php @@ -24,6 +24,7 @@ use ApiPlatform\Core\Identifier\IdentifierConverterInterface; use ApiPlatform\Core\Metadata\Property\Factory\PropertyMetadataFactoryInterface; use ApiPlatform\Core\Metadata\Property\Factory\PropertyNameCollectionFactoryInterface; +use ApiPlatform\Core\Metadata\Resource\Factory\ResourceMetadataFactoryInterface; use Doctrine\Common\Persistence\ManagerRegistry; use Doctrine\ODM\MongoDB\Aggregation\Builder; use Doctrine\ODM\MongoDB\DocumentManager; @@ -43,6 +44,7 @@ final class SubresourceDataProvider implements SubresourceDataProviderInterface use IdentifierManagerTrait; private $managerRegistry; + private $resourceMetadataFactory; private $collectionExtensions; private $itemExtensions; @@ -50,9 +52,10 @@ final class SubresourceDataProvider implements SubresourceDataProviderInterface * @param AggregationCollectionExtensionInterface[] $collectionExtensions * @param AggregationItemExtensionInterface[] $itemExtensions */ - public function __construct(ManagerRegistry $managerRegistry, PropertyNameCollectionFactoryInterface $propertyNameCollectionFactory, PropertyMetadataFactoryInterface $propertyMetadataFactory, iterable $collectionExtensions = [], iterable $itemExtensions = []) + public function __construct(ManagerRegistry $managerRegistry, ResourceMetadataFactoryInterface $resourceMetadataFactory, PropertyNameCollectionFactoryInterface $propertyNameCollectionFactory, PropertyMetadataFactoryInterface $propertyMetadataFactory, iterable $collectionExtensions = [], iterable $itemExtensions = []) { $this->managerRegistry = $managerRegistry; + $this->resourceMetadataFactory = $resourceMetadataFactory; $this->propertyNameCollectionFactory = $propertyNameCollectionFactory; $this->propertyMetadataFactory = $propertyMetadataFactory; $this->collectionExtensions = $collectionExtensions; @@ -80,7 +83,11 @@ public function getSubresource(string $resourceClass, array $identifiers, array throw new ResourceClassNotSupportedException('The given resource class is not a subresource.'); } - $aggregationBuilder = $this->buildAggregation($identifiers, $context, $repository->createAggregationBuilder(), \count($context['identifiers'])); + $resourceMetadata = $this->resourceMetadataFactory->create($resourceClass); + $attribute = $resourceMetadata->getSubresourceOperationAttribute($operationName, 'doctrine_mongodb', [], true); + $executeOptions = $attribute['execute_options'] ?? []; + + $aggregationBuilder = $this->buildAggregation($identifiers, $context, $executeOptions, $repository->createAggregationBuilder(), \count($context['identifiers'])); if (true === $context['collection']) { foreach ($this->collectionExtensions as $extension) { @@ -98,7 +105,7 @@ public function getSubresource(string $resourceClass, array $identifiers, array } } - $iterator = $aggregationBuilder->hydrate($resourceClass)->execute(); + $iterator = $aggregationBuilder->hydrate($resourceClass)->execute($executeOptions); return $context['collection'] ? $iterator->toArray() : ($iterator->current() ?: null); } @@ -106,7 +113,7 @@ public function getSubresource(string $resourceClass, array $identifiers, array /** * @throws RuntimeException */ - private function buildAggregation(array $identifiers, array $context, Builder $previousAggregationBuilder, int $remainingIdentifiers, Builder $topAggregationBuilder = null): Builder + private function buildAggregation(array $identifiers, array $context, array $executeOptions, Builder $previousAggregationBuilder, int $remainingIdentifiers, Builder $topAggregationBuilder = null): Builder { if ($remainingIdentifiers <= 0) { return $previousAggregationBuilder; @@ -154,9 +161,9 @@ private function buildAggregation(array $identifiers, array $context, Builder $p } // Recurse aggregations - $aggregation = $this->buildAggregation($identifiers, $context, $aggregation, --$remainingIdentifiers, $topAggregationBuilder); + $aggregation = $this->buildAggregation($identifiers, $context, $executeOptions, $aggregation, --$remainingIdentifiers, $topAggregationBuilder); - $results = $aggregation->execute()->toArray(); + $results = $aggregation->execute($executeOptions)->toArray(); $in = array_reduce($results, function ($in, $result) use ($previousAssociationProperty) { return $in + array_map(function ($result) { return $result['_id']; diff --git a/src/Bridge/Symfony/Bundle/Resources/config/doctrine_mongodb_odm.xml b/src/Bridge/Symfony/Bundle/Resources/config/doctrine_mongodb_odm.xml index fa300e4a700..d129fd7019b 100644 --- a/src/Bridge/Symfony/Bundle/Resources/config/doctrine_mongodb_odm.xml +++ b/src/Bridge/Symfony/Bundle/Resources/config/doctrine_mongodb_odm.xml @@ -24,11 +24,13 @@ + + @@ -36,6 +38,7 @@ + @@ -46,7 +49,6 @@ parent="api_platform.doctrine_mongodb.odm.collection_data_provider" class="ApiPlatform\Core\Bridge\Doctrine\MongoDbOdm\CollectionDataProvider"> - + diff --git a/tests/Bridge/Doctrine/MongoDbOdm/CollectionDataProviderTest.php b/tests/Bridge/Doctrine/MongoDbOdm/CollectionDataProviderTest.php index 001e4d997a8..2b972521c1a 100644 --- a/tests/Bridge/Doctrine/MongoDbOdm/CollectionDataProviderTest.php +++ b/tests/Bridge/Doctrine/MongoDbOdm/CollectionDataProviderTest.php @@ -17,6 +17,8 @@ use ApiPlatform\Core\Bridge\Doctrine\MongoDbOdm\Extension\AggregationCollectionExtensionInterface; use ApiPlatform\Core\Bridge\Doctrine\MongoDbOdm\Extension\AggregationResultCollectionExtensionInterface; use ApiPlatform\Core\Exception\RuntimeException; +use ApiPlatform\Core\Metadata\Resource\Factory\ResourceMetadataFactoryInterface; +use ApiPlatform\Core\Metadata\Resource\ResourceMetadata; use ApiPlatform\Core\Tests\Fixtures\TestBundle\Document\Dummy; use Doctrine\Common\Persistence\ManagerRegistry; use Doctrine\Common\Persistence\ObjectRepository; @@ -33,13 +35,27 @@ */ class CollectionDataProviderTest extends TestCase { + private $managerRegistryProphecy; + private $resourceMetadataFactoryProphecy; + + /** + * {@inheritdoc} + */ + protected function setUp(): void + { + parent::setUp(); + + $this->managerRegistryProphecy = $this->prophesize(ManagerRegistry::class); + $this->resourceMetadataFactoryProphecy = $this->prophesize(ResourceMetadataFactoryInterface::class); + } + public function testGetCollection() { $iterator = $this->prophesize(Iterator::class)->reveal(); $aggregationBuilderProphecy = $this->prophesize(Builder::class); $aggregationBuilderProphecy->hydrate(Dummy::class)->willReturn($aggregationBuilderProphecy)->shouldBeCalled(); - $aggregationBuilderProphecy->execute()->willReturn($iterator)->shouldBeCalled(); + $aggregationBuilderProphecy->execute([])->willReturn($iterator)->shouldBeCalled(); $aggregationBuilder = $aggregationBuilderProphecy->reveal(); $repositoryProphecy = $this->prophesize(DocumentRepository::class); @@ -48,13 +64,46 @@ public function testGetCollection() $managerProphecy = $this->prophesize(DocumentManager::class); $managerProphecy->getRepository(Dummy::class)->willReturn($repositoryProphecy->reveal())->shouldBeCalled(); - $managerRegistryProphecy = $this->prophesize(ManagerRegistry::class); - $managerRegistryProphecy->getManagerForClass(Dummy::class)->willReturn($managerProphecy->reveal())->shouldBeCalled(); + $this->managerRegistryProphecy->getManagerForClass(Dummy::class)->willReturn($managerProphecy->reveal())->shouldBeCalled(); + + $this->resourceMetadataFactoryProphecy->create(Dummy::class)->willReturn(new ResourceMetadata()); + + $extensionProphecy = $this->prophesize(AggregationCollectionExtensionInterface::class); + $extensionProphecy->applyToCollection($aggregationBuilder, Dummy::class, 'foo', [])->shouldBeCalled(); + + $dataProvider = new CollectionDataProvider($this->managerRegistryProphecy->reveal(), $this->resourceMetadataFactoryProphecy->reveal(), [$extensionProphecy->reveal()]); + $this->assertEquals($iterator, $dataProvider->getCollection(Dummy::class, 'foo')); + } + + public function testGetCollectionWithExecuteOptions() + { + $iterator = $this->prophesize(Iterator::class)->reveal(); + + $aggregationBuilderProphecy = $this->prophesize(Builder::class); + $aggregationBuilderProphecy->hydrate(Dummy::class)->willReturn($aggregationBuilderProphecy)->shouldBeCalled(); + $aggregationBuilderProphecy->execute(['allowDiskUse' => true])->willReturn($iterator)->shouldBeCalled(); + $aggregationBuilder = $aggregationBuilderProphecy->reveal(); + + $repositoryProphecy = $this->prophesize(DocumentRepository::class); + $repositoryProphecy->createAggregationBuilder()->willReturn($aggregationBuilder)->shouldBeCalled(); + + $managerProphecy = $this->prophesize(DocumentManager::class); + $managerProphecy->getRepository(Dummy::class)->willReturn($repositoryProphecy->reveal())->shouldBeCalled(); + + $this->managerRegistryProphecy->getManagerForClass(Dummy::class)->willReturn($managerProphecy->reveal())->shouldBeCalled(); + + $this->resourceMetadataFactoryProphecy->create(Dummy::class)->willReturn(new ResourceMetadata( + 'Dummy', + null, + null, + null, + ['foo' => ['doctrine_mongodb' => ['execute_options' => ['allowDiskUse' => true]]]] + )); $extensionProphecy = $this->prophesize(AggregationCollectionExtensionInterface::class); $extensionProphecy->applyToCollection($aggregationBuilder, Dummy::class, 'foo', [])->shouldBeCalled(); - $dataProvider = new CollectionDataProvider($managerRegistryProphecy->reveal(), [$extensionProphecy->reveal()]); + $dataProvider = new CollectionDataProvider($this->managerRegistryProphecy->reveal(), $this->resourceMetadataFactoryProphecy->reveal(), [$extensionProphecy->reveal()]); $this->assertEquals($iterator, $dataProvider->getCollection(Dummy::class, 'foo')); } @@ -69,15 +118,14 @@ public function testAggregationResultExtension() $managerProphecy = $this->prophesize(DocumentManager::class); $managerProphecy->getRepository(Dummy::class)->willReturn($repositoryProphecy->reveal())->shouldBeCalled(); - $managerRegistryProphecy = $this->prophesize(ManagerRegistry::class); - $managerRegistryProphecy->getManagerForClass(Dummy::class)->willReturn($managerProphecy->reveal())->shouldBeCalled(); + $this->managerRegistryProphecy->getManagerForClass(Dummy::class)->willReturn($managerProphecy->reveal())->shouldBeCalled(); $extensionProphecy = $this->prophesize(AggregationResultCollectionExtensionInterface::class); $extensionProphecy->applyToCollection($aggregationBuilder, Dummy::class, 'foo', [])->shouldBeCalled(); $extensionProphecy->supportsResult(Dummy::class, 'foo', [])->willReturn(true)->shouldBeCalled(); $extensionProphecy->getResult($aggregationBuilder, Dummy::class, 'foo', [])->willReturn([])->shouldBeCalled(); - $dataProvider = new CollectionDataProvider($managerRegistryProphecy->reveal(), [$extensionProphecy->reveal()]); + $dataProvider = new CollectionDataProvider($this->managerRegistryProphecy->reveal(), $this->resourceMetadataFactoryProphecy->reveal(), [$extensionProphecy->reveal()]); $this->assertEquals([], $dataProvider->getCollection(Dummy::class, 'foo')); } @@ -91,21 +139,19 @@ public function testCannotCreateAggregationBuilder() $managerProphecy = $this->prophesize(DocumentManager::class); $managerProphecy->getRepository(Dummy::class)->willReturn($repositoryProphecy->reveal())->shouldBeCalled(); - $managerRegistryProphecy = $this->prophesize(ManagerRegistry::class); - $managerRegistryProphecy->getManagerForClass(Dummy::class)->willReturn($managerProphecy->reveal())->shouldBeCalled(); + $this->managerRegistryProphecy->getManagerForClass(Dummy::class)->willReturn($managerProphecy->reveal())->shouldBeCalled(); - $dataProvider = new CollectionDataProvider($managerRegistryProphecy->reveal()); + $dataProvider = new CollectionDataProvider($this->managerRegistryProphecy->reveal(), $this->resourceMetadataFactoryProphecy->reveal()); $this->assertEquals([], $dataProvider->getCollection(Dummy::class, 'foo')); } public function testUnsupportedClass() { - $managerRegistryProphecy = $this->prophesize(ManagerRegistry::class); - $managerRegistryProphecy->getManagerForClass(Dummy::class)->willReturn(null)->shouldBeCalled(); + $this->managerRegistryProphecy->getManagerForClass(Dummy::class)->willReturn(null)->shouldBeCalled(); $extensionProphecy = $this->prophesize(AggregationResultCollectionExtensionInterface::class); - $dataProvider = new CollectionDataProvider($managerRegistryProphecy->reveal(), [$extensionProphecy->reveal()]); + $dataProvider = new CollectionDataProvider($this->managerRegistryProphecy->reveal(), $this->resourceMetadataFactoryProphecy->reveal(), [$extensionProphecy->reveal()]); $this->assertFalse($dataProvider->supports(Dummy::class, 'foo')); } } diff --git a/tests/Bridge/Doctrine/MongoDbOdm/Extension/PaginationExtensionTest.php b/tests/Bridge/Doctrine/MongoDbOdm/Extension/PaginationExtensionTest.php index f6b4f383628..9532392f42a 100644 --- a/tests/Bridge/Doctrine/MongoDbOdm/Extension/PaginationExtensionTest.php +++ b/tests/Bridge/Doctrine/MongoDbOdm/Extension/PaginationExtensionTest.php @@ -42,24 +42,28 @@ class PaginationExtensionTest extends TestCase { private $managerRegistryProphecy; + private $resourceMetadataFactoryProphecy; + /** + * {@inheritdoc} + */ protected function setUp(): void { parent::setUp(); $this->managerRegistryProphecy = $this->prophesize(ManagerRegistry::class); + $this->resourceMetadataFactoryProphecy = $this->prophesize(ResourceMetadataFactoryInterface::class); } public function testApplyToCollection() { - $resourceMetadataFactoryProphecy = $this->prophesize(ResourceMetadataFactoryInterface::class); $attributes = [ 'pagination_enabled' => true, 'pagination_client_enabled' => true, 'pagination_items_per_page' => 40, ]; - $resourceMetadataFactoryProphecy->create('Foo')->willReturn(new ResourceMetadata(null, null, null, [], [], $attributes)); - $resourceMetadataFactory = $resourceMetadataFactoryProphecy->reveal(); + $this->resourceMetadataFactoryProphecy->create('Foo')->willReturn(new ResourceMetadata(null, null, null, [], [], $attributes)); + $resourceMetadataFactory = $this->resourceMetadataFactoryProphecy->reveal(); $pagination = new Pagination($resourceMetadataFactory, [ 'page_parameter_name' => '_page', @@ -71,6 +75,7 @@ public function testApplyToCollection() $extension = new PaginationExtension( $this->managerRegistryProphecy->reveal(), + $resourceMetadataFactory, $pagination ); $extension->applyToCollection($aggregationBuilderProphecy->reveal(), 'Foo', 'op', $context); @@ -78,14 +83,13 @@ public function testApplyToCollection() public function testApplyToCollectionWithItemPerPageZero() { - $resourceMetadataFactoryProphecy = $this->prophesize(ResourceMetadataFactoryInterface::class); $attributes = [ 'pagination_enabled' => true, 'pagination_client_enabled' => true, 'pagination_items_per_page' => 0, ]; - $resourceMetadataFactoryProphecy->create('Foo')->willReturn(new ResourceMetadata(null, null, null, [], [], $attributes)); - $resourceMetadataFactory = $resourceMetadataFactoryProphecy->reveal(); + $this->resourceMetadataFactoryProphecy->create('Foo')->willReturn(new ResourceMetadata(null, null, null, [], [], $attributes)); + $resourceMetadataFactory = $this->resourceMetadataFactoryProphecy->reveal(); $pagination = new Pagination($resourceMetadataFactory, [ 'items_per_page' => 0, @@ -98,6 +102,7 @@ public function testApplyToCollectionWithItemPerPageZero() $extension = new PaginationExtension( $this->managerRegistryProphecy->reveal(), + $resourceMetadataFactory, $pagination ); $extension->applyToCollection($aggregationBuilderProphecy->reveal(), 'Foo', 'op', $context); @@ -108,14 +113,13 @@ public function testApplyToCollectionWithItemPerPageZeroAndPage2() $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage('Page should not be greater than 1 if limit is equal to 0'); - $resourceMetadataFactoryProphecy = $this->prophesize(ResourceMetadataFactoryInterface::class); $attributes = [ 'pagination_enabled' => true, 'pagination_client_enabled' => true, 'pagination_items_per_page' => 0, ]; - $resourceMetadataFactoryProphecy->create('Foo')->willReturn(new ResourceMetadata(null, null, null, [], [], $attributes)); - $resourceMetadataFactory = $resourceMetadataFactoryProphecy->reveal(); + $this->resourceMetadataFactoryProphecy->create('Foo')->willReturn(new ResourceMetadata(null, null, null, [], [], $attributes)); + $resourceMetadataFactory = $this->resourceMetadataFactoryProphecy->reveal(); $pagination = new Pagination($resourceMetadataFactory, [ 'items_per_page' => 0, @@ -129,6 +133,7 @@ public function testApplyToCollectionWithItemPerPageZeroAndPage2() $extension = new PaginationExtension( $this->prophesize(ManagerRegistry::class)->reveal(), + $resourceMetadataFactory, $pagination ); $extension->applyToCollection($aggregationBuilderProphecy->reveal(), 'Foo', 'op', $context); @@ -139,14 +144,13 @@ public function testApplyToCollectionWithItemPerPageLessThan0() $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage('Limit should not be less than 0'); - $resourceMetadataFactoryProphecy = $this->prophesize(ResourceMetadataFactoryInterface::class); $attributes = [ 'pagination_enabled' => true, 'pagination_client_enabled' => true, 'pagination_items_per_page' => -20, ]; - $resourceMetadataFactoryProphecy->create('Foo')->willReturn(new ResourceMetadata(null, null, null, [], [], $attributes)); - $resourceMetadataFactory = $resourceMetadataFactoryProphecy->reveal(); + $this->resourceMetadataFactoryProphecy->create('Foo')->willReturn(new ResourceMetadata(null, null, null, [], [], $attributes)); + $resourceMetadataFactory = $this->resourceMetadataFactoryProphecy->reveal(); $pagination = new Pagination($resourceMetadataFactory, [ 'items_per_page' => -20, @@ -160,6 +164,7 @@ public function testApplyToCollectionWithItemPerPageLessThan0() $extension = new PaginationExtension( $this->managerRegistryProphecy->reveal(), + $resourceMetadataFactory, $pagination ); $extension->applyToCollection($aggregationBuilderProphecy->reveal(), 'Foo', 'op', $context); @@ -167,14 +172,13 @@ public function testApplyToCollectionWithItemPerPageLessThan0() public function testApplyToCollectionWithItemPerPageTooHigh() { - $resourceMetadataFactoryProphecy = $this->prophesize(ResourceMetadataFactoryInterface::class); $attributes = [ 'pagination_enabled' => true, 'pagination_client_enabled' => true, 'pagination_client_items_per_page' => true, ]; - $resourceMetadataFactoryProphecy->create('Foo')->willReturn(new ResourceMetadata(null, null, null, [], [], $attributes)); - $resourceMetadataFactory = $resourceMetadataFactoryProphecy->reveal(); + $this->resourceMetadataFactoryProphecy->create('Foo')->willReturn(new ResourceMetadata(null, null, null, [], [], $attributes)); + $resourceMetadataFactory = $this->resourceMetadataFactoryProphecy->reveal(); $pagination = new Pagination($resourceMetadataFactory, [ 'page_parameter_name' => '_page', @@ -187,6 +191,7 @@ public function testApplyToCollectionWithItemPerPageTooHigh() $extension = new PaginationExtension( $this->managerRegistryProphecy->reveal(), + $resourceMetadataFactory, $pagination ); $extension->applyToCollection($aggregationBuilderProphecy->reveal(), 'Foo', 'op', $context); @@ -194,14 +199,13 @@ public function testApplyToCollectionWithItemPerPageTooHigh() public function testApplyToCollectionWithGraphql() { - $resourceMetadataFactoryProphecy = $this->prophesize(ResourceMetadataFactoryInterface::class); $attributes = [ 'pagination_enabled' => true, 'pagination_client_enabled' => true, 'pagination_client_items_per_page' => 20, ]; - $resourceMetadataFactoryProphecy->create('Foo')->willReturn(new ResourceMetadata(null, null, null, [], [], $attributes)); - $resourceMetadataFactory = $resourceMetadataFactoryProphecy->reveal(); + $this->resourceMetadataFactoryProphecy->create('Foo')->willReturn(new ResourceMetadata(null, null, null, [], [], $attributes)); + $resourceMetadataFactory = $this->resourceMetadataFactoryProphecy->reveal(); $pagination = new Pagination($resourceMetadataFactory); @@ -211,6 +215,7 @@ public function testApplyToCollectionWithGraphql() $extension = new PaginationExtension( $this->managerRegistryProphecy->reveal(), + $resourceMetadataFactory, $pagination ); $extension->applyToCollection($aggregationBuilderProphecy->reveal(), 'Foo', 'op', $context); @@ -218,14 +223,13 @@ public function testApplyToCollectionWithGraphql() public function testApplyToCollectionWithGraphqlAndCountContext() { - $resourceMetadataFactoryProphecy = $this->prophesize(ResourceMetadataFactoryInterface::class); $attributes = [ 'pagination_enabled' => true, 'pagination_client_enabled' => true, 'pagination_client_items_per_page' => 20, ]; - $resourceMetadataFactoryProphecy->create('Foo')->willReturn(new ResourceMetadata(null, null, null, [], [], $attributes)); - $resourceMetadataFactory = $resourceMetadataFactoryProphecy->reveal(); + $this->resourceMetadataFactoryProphecy->create('Foo')->willReturn(new ResourceMetadata(null, null, null, [], [], $attributes)); + $resourceMetadataFactory = $this->resourceMetadataFactoryProphecy->reveal(); $pagination = new Pagination($resourceMetadataFactory); @@ -244,6 +248,7 @@ public function testApplyToCollectionWithGraphqlAndCountContext() $extension = new PaginationExtension( $this->managerRegistryProphecy->reveal(), + $resourceMetadataFactory, $pagination ); $extension->applyToCollection($aggregationBuilderProphecy->reveal(), 'Foo', 'op', $context); @@ -251,9 +256,8 @@ public function testApplyToCollectionWithGraphqlAndCountContext() public function testApplyToCollectionNoFilters() { - $resourceMetadataFactoryProphecy = $this->prophesize(ResourceMetadataFactoryInterface::class); - $resourceMetadataFactoryProphecy->create('Foo')->willReturn(new ResourceMetadata(null, null, null, [], [])); - $resourceMetadataFactory = $resourceMetadataFactoryProphecy->reveal(); + $this->resourceMetadataFactoryProphecy->create('Foo')->willReturn(new ResourceMetadata(null, null, null, [], [])); + $resourceMetadataFactory = $this->resourceMetadataFactoryProphecy->reveal(); $pagination = new Pagination($resourceMetadataFactory); @@ -263,6 +267,7 @@ public function testApplyToCollectionNoFilters() $extension = new PaginationExtension( $this->managerRegistryProphecy->reveal(), + $resourceMetadataFactory, $pagination ); $extension->applyToCollection($aggregationBuilderProphecy->reveal(), 'Foo', 'op', $context); @@ -270,9 +275,8 @@ public function testApplyToCollectionNoFilters() public function testApplyToCollectionPaginationDisabled() { - $resourceMetadataFactoryProphecy = $this->prophesize(ResourceMetadataFactoryInterface::class); - $resourceMetadataFactoryProphecy->create('Foo')->willReturn(new ResourceMetadata(null, null, null, [], [])); - $resourceMetadataFactory = $resourceMetadataFactoryProphecy->reveal(); + $this->resourceMetadataFactoryProphecy->create('Foo')->willReturn(new ResourceMetadata(null, null, null, [], [])); + $resourceMetadataFactory = $this->resourceMetadataFactoryProphecy->reveal(); $pagination = new Pagination($resourceMetadataFactory, [ 'enabled' => false, @@ -285,6 +289,7 @@ public function testApplyToCollectionPaginationDisabled() $extension = new PaginationExtension( $this->managerRegistryProphecy->reveal(), + $resourceMetadataFactory, $pagination ); $extension->applyToCollection($aggregationBuilderProphecy->reveal(), 'Foo', 'op', $context); @@ -292,9 +297,8 @@ public function testApplyToCollectionPaginationDisabled() public function testApplyToCollectionGraphQlPaginationDisabled() { - $resourceMetadataFactoryProphecy = $this->prophesize(ResourceMetadataFactoryInterface::class); - $resourceMetadataFactoryProphecy->create('Foo')->willReturn(new ResourceMetadata(null, null, null, [], [])); - $resourceMetadataFactory = $resourceMetadataFactoryProphecy->reveal(); + $this->resourceMetadataFactoryProphecy->create('Foo')->willReturn(new ResourceMetadata(null, null, null, [], [])); + $resourceMetadataFactory = $this->resourceMetadataFactoryProphecy->reveal(); $pagination = new Pagination($resourceMetadataFactory, [], [ 'enabled' => false, @@ -307,6 +311,7 @@ public function testApplyToCollectionGraphQlPaginationDisabled() $extension = new PaginationExtension( $this->managerRegistryProphecy->reveal(), + $resourceMetadataFactory, $pagination ); $extension->applyToCollection($aggregationBuilderProphecy->reveal(), 'Foo', 'op', $context); @@ -314,14 +319,13 @@ public function testApplyToCollectionGraphQlPaginationDisabled() public function testApplyToCollectionWithMaximumItemsPerPage() { - $resourceMetadataFactoryProphecy = $this->prophesize(ResourceMetadataFactoryInterface::class); $attributes = [ 'pagination_enabled' => true, 'pagination_client_enabled' => true, 'pagination_maximum_items_per_page' => 80, ]; - $resourceMetadataFactoryProphecy->create('Foo')->willReturn(new ResourceMetadata(null, null, null, [], [], $attributes)); - $resourceMetadataFactory = $resourceMetadataFactoryProphecy->reveal(); + $this->resourceMetadataFactoryProphecy->create('Foo')->willReturn(new ResourceMetadata(null, null, null, [], [], $attributes)); + $resourceMetadataFactory = $this->resourceMetadataFactoryProphecy->reveal(); $pagination = new Pagination($resourceMetadataFactory, [ 'client_enabled' => true, @@ -335,6 +339,7 @@ public function testApplyToCollectionWithMaximumItemsPerPage() $extension = new PaginationExtension( $this->managerRegistryProphecy->reveal(), + $resourceMetadataFactory, $pagination ); $extension->applyToCollection($aggregationBuilderProphecy->reveal(), 'Foo', 'op', $context); @@ -342,14 +347,14 @@ public function testApplyToCollectionWithMaximumItemsPerPage() public function testSupportsResult() { - $resourceMetadataFactoryProphecy = $this->prophesize(ResourceMetadataFactoryInterface::class); - $resourceMetadataFactoryProphecy->create('Foo')->willReturn(new ResourceMetadata(null, null, null, [], [])); - $resourceMetadataFactory = $resourceMetadataFactoryProphecy->reveal(); + $this->resourceMetadataFactoryProphecy->create('Foo')->willReturn(new ResourceMetadata(null, null, null, [], [])); + $resourceMetadataFactory = $this->resourceMetadataFactoryProphecy->reveal(); $pagination = new Pagination($resourceMetadataFactory); $extension = new PaginationExtension( $this->managerRegistryProphecy->reveal(), + $resourceMetadataFactory, $pagination ); $this->assertTrue($extension->supportsResult('Foo', 'op')); @@ -357,9 +362,8 @@ public function testSupportsResult() public function testSupportsResultClientNotAllowedToPaginate() { - $resourceMetadataFactoryProphecy = $this->prophesize(ResourceMetadataFactoryInterface::class); - $resourceMetadataFactoryProphecy->create('Foo')->willReturn(new ResourceMetadata(null, null, null, [], [])); - $resourceMetadataFactory = $resourceMetadataFactoryProphecy->reveal(); + $this->resourceMetadataFactoryProphecy->create('Foo')->willReturn(new ResourceMetadata(null, null, null, [], [])); + $resourceMetadataFactory = $this->resourceMetadataFactoryProphecy->reveal(); $pagination = new Pagination($resourceMetadataFactory, [ 'enabled' => false, @@ -368,6 +372,7 @@ public function testSupportsResultClientNotAllowedToPaginate() $extension = new PaginationExtension( $this->managerRegistryProphecy->reveal(), + $resourceMetadataFactory, $pagination ); $this->assertFalse($extension->supportsResult('Foo', 'op', ['filters' => ['pagination' => true]])); @@ -375,9 +380,8 @@ public function testSupportsResultClientNotAllowedToPaginate() public function testSupportsResultPaginationDisabled() { - $resourceMetadataFactoryProphecy = $this->prophesize(ResourceMetadataFactoryInterface::class); - $resourceMetadataFactoryProphecy->create('Foo')->willReturn(new ResourceMetadata(null, null, null, [], [])); - $resourceMetadataFactory = $resourceMetadataFactoryProphecy->reveal(); + $this->resourceMetadataFactoryProphecy->create('Foo')->willReturn(new ResourceMetadata(null, null, null, [], [])); + $resourceMetadataFactory = $this->resourceMetadataFactoryProphecy->reveal(); $pagination = new Pagination($resourceMetadataFactory, [ 'enabled' => false, @@ -385,6 +389,7 @@ public function testSupportsResultPaginationDisabled() $extension = new PaginationExtension( $this->managerRegistryProphecy->reveal(), + $resourceMetadataFactory, $pagination ); $this->assertFalse($extension->supportsResult('Foo', 'op', ['filters' => ['enabled' => false]])); @@ -392,9 +397,8 @@ public function testSupportsResultPaginationDisabled() public function testSupportsResultGraphQlPaginationDisabled() { - $resourceMetadataFactoryProphecy = $this->prophesize(ResourceMetadataFactoryInterface::class); - $resourceMetadataFactoryProphecy->create('Foo')->willReturn(new ResourceMetadata(null, null, null, [], [])); - $resourceMetadataFactory = $resourceMetadataFactoryProphecy->reveal(); + $this->resourceMetadataFactoryProphecy->create('Foo')->willReturn(new ResourceMetadata(null, null, null, [], [])); + $resourceMetadataFactory = $this->resourceMetadataFactoryProphecy->reveal(); $pagination = new Pagination($resourceMetadataFactory, [], [ 'enabled' => false, @@ -402,6 +406,7 @@ public function testSupportsResultGraphQlPaginationDisabled() $extension = new PaginationExtension( $this->managerRegistryProphecy->reveal(), + $resourceMetadataFactory, $pagination ); $this->assertFalse($extension->supportsResult('Foo', 'op', ['filters' => ['enabled' => false], 'graphql_operation_name' => 'op'])); @@ -409,8 +414,7 @@ public function testSupportsResultGraphQlPaginationDisabled() public function testGetResult() { - $resourceMetadataFactoryProphecy = $this->prophesize(ResourceMetadataFactoryInterface::class); - $resourceMetadataFactory = $resourceMetadataFactoryProphecy->reveal(); + $resourceMetadataFactory = $this->resourceMetadataFactoryProphecy->reveal(); $pagination = new Pagination($resourceMetadataFactory); @@ -420,6 +424,8 @@ public function testGetResult() $this->managerRegistryProphecy->getManagerForClass(Dummy::class)->willReturn($documentManager); + $this->resourceMetadataFactoryProphecy->create(Dummy::class)->willReturn(new ResourceMetadata()); + $iteratorProphecy = $this->prophesize(Iterator::class); $iteratorProphecy->toArray()->willReturn([ [ @@ -432,7 +438,7 @@ public function testGetResult() ]); $aggregationBuilderProphecy = $this->prophesize(Builder::class); - $aggregationBuilderProphecy->execute()->willReturn($iteratorProphecy->reveal()); + $aggregationBuilderProphecy->execute([])->willReturn($iteratorProphecy->reveal()); $aggregationBuilderProphecy->getPipeline()->willReturn([ [ '$facet' => [ @@ -449,6 +455,7 @@ public function testGetResult() $paginationExtension = new PaginationExtension( $this->managerRegistryProphecy->reveal(), + $resourceMetadataFactory, $pagination ); @@ -458,6 +465,65 @@ public function testGetResult() $this->assertInstanceOf(PaginatorInterface::class, $result); } + public function testGetResultWithExecuteOptions() + { + $resourceMetadataFactory = $this->resourceMetadataFactoryProphecy->reveal(); + + $pagination = new Pagination($resourceMetadataFactory); + + $fixturesPath = \dirname((string) (new \ReflectionClass(Dummy::class))->getFileName()); + $config = DoctrineMongoDbOdmSetup::createAnnotationMetadataConfiguration([$fixturesPath], true); + $documentManager = DocumentManager::create(null, $config); + + $this->managerRegistryProphecy->getManagerForClass(Dummy::class)->willReturn($documentManager); + + $this->resourceMetadataFactoryProphecy->create(Dummy::class)->willReturn(new ResourceMetadata( + 'Dummy', + null, + null, + null, + ['foo' => ['doctrine_mongodb' => ['execute_options' => ['allowDiskUse' => true]]]] + )); + + $iteratorProphecy = $this->prophesize(Iterator::class); + $iteratorProphecy->toArray()->willReturn([ + [ + 'count' => [ + [ + 'count' => 9, + ], + ], + ], + ]); + + $aggregationBuilderProphecy = $this->prophesize(Builder::class); + $aggregationBuilderProphecy->execute(['allowDiskUse' => true])->willReturn($iteratorProphecy->reveal()); + $aggregationBuilderProphecy->getPipeline()->willReturn([ + [ + '$facet' => [ + 'results' => [ + ['$skip' => 3], + ['$limit' => 6], + ], + 'count' => [ + ['$count' => 'count'], + ], + ], + ], + ]); + + $paginationExtension = new PaginationExtension( + $this->managerRegistryProphecy->reveal(), + $resourceMetadataFactory, + $pagination + ); + + $result = $paginationExtension->getResult($aggregationBuilderProphecy->reveal(), Dummy::class, 'foo'); + + $this->assertInstanceOf(PartialPaginatorInterface::class, $result); + $this->assertInstanceOf(PaginatorInterface::class, $result); + } + private function mockAggregationBuilder($expectedOffset, $expectedLimit) { $skipProphecy = $this->prophesize(Skip::class); diff --git a/tests/Bridge/Doctrine/MongoDbOdm/ItemDataProviderTest.php b/tests/Bridge/Doctrine/MongoDbOdm/ItemDataProviderTest.php index 2f5cee9f086..bba7ade6290 100644 --- a/tests/Bridge/Doctrine/MongoDbOdm/ItemDataProviderTest.php +++ b/tests/Bridge/Doctrine/MongoDbOdm/ItemDataProviderTest.php @@ -23,6 +23,8 @@ use ApiPlatform\Core\Metadata\Property\Factory\PropertyNameCollectionFactoryInterface; use ApiPlatform\Core\Metadata\Property\PropertyMetadata; use ApiPlatform\Core\Metadata\Property\PropertyNameCollection; +use ApiPlatform\Core\Metadata\Resource\Factory\ResourceMetadataFactoryInterface; +use ApiPlatform\Core\Metadata\Resource\ResourceMetadata; use ApiPlatform\Core\Tests\Fixtures\TestBundle\Document\Dummy; use Doctrine\Common\Persistence\ManagerRegistry; use Doctrine\Common\Persistence\ObjectManager; @@ -42,6 +44,18 @@ */ class ItemDataProviderTest extends TestCase { + private $resourceMetadataFactoryProphecy; + + /** + * {@inheritdoc} + */ + protected function setUp(): void + { + parent::setUp(); + + $this->resourceMetadataFactoryProphecy = $this->prophesize(ResourceMetadataFactoryInterface::class); + } + public function testGetItemSingleIdentifier() { $context = ['foo' => 'bar', 'fetch_data' => true, IdentifierConverterInterface::HAS_IDENTIFIER_CONVERTER => true]; @@ -57,7 +71,40 @@ public function testGetItemSingleIdentifier() $aggregationBuilderProphecy = $this->prophesize(Builder::class); $aggregationBuilderProphecy->match()->willReturn($matchProphecy->reveal())->shouldBeCalled(); $aggregationBuilderProphecy->hydrate(Dummy::class)->willReturn($aggregationBuilderProphecy)->shouldBeCalled(); - $aggregationBuilderProphecy->execute()->willReturn($iterator->reveal())->shouldBeCalled(); + $aggregationBuilderProphecy->execute([])->willReturn($iterator->reveal())->shouldBeCalled(); + $aggregationBuilder = $aggregationBuilderProphecy->reveal(); + + [$propertyNameCollectionFactory, $propertyMetadataFactory] = $this->getMetadataFactories(Dummy::class, [ + 'id', + ]); + $managerRegistry = $this->getManagerRegistry(Dummy::class, $aggregationBuilder); + + $this->resourceMetadataFactoryProphecy->create(Dummy::class)->willReturn(new ResourceMetadata()); + + $extensionProphecy = $this->prophesize(AggregationItemExtensionInterface::class); + $extensionProphecy->applyToItem($aggregationBuilder, Dummy::class, ['id' => 1], 'foo', $context)->shouldBeCalled(); + + $dataProvider = new ItemDataProvider($managerRegistry, $this->resourceMetadataFactoryProphecy->reveal(), $propertyNameCollectionFactory, $propertyMetadataFactory, [$extensionProphecy->reveal()]); + + $this->assertEquals($result, $dataProvider->getItem(Dummy::class, ['id' => 1], 'foo', $context)); + } + + public function testGetItemWithExecuteOptions() + { + $context = ['foo' => 'bar', 'fetch_data' => true, IdentifierConverterInterface::HAS_IDENTIFIER_CONVERTER => true]; + + $matchProphecy = $this->prophesize(Match::class); + $matchProphecy->field('id')->willReturn($matchProphecy)->shouldBeCalled(); + $matchProphecy->equals(1)->shouldBeCalled(); + + $iterator = $this->prophesize(Iterator::class); + $result = new \stdClass(); + $iterator->current()->willReturn($result)->shouldBeCalled(); + + $aggregationBuilderProphecy = $this->prophesize(Builder::class); + $aggregationBuilderProphecy->match()->willReturn($matchProphecy->reveal())->shouldBeCalled(); + $aggregationBuilderProphecy->hydrate(Dummy::class)->willReturn($aggregationBuilderProphecy)->shouldBeCalled(); + $aggregationBuilderProphecy->execute(['allowDiskUse' => true])->willReturn($iterator->reveal())->shouldBeCalled(); $aggregationBuilder = $aggregationBuilderProphecy->reveal(); [$propertyNameCollectionFactory, $propertyMetadataFactory] = $this->getMetadataFactories(Dummy::class, [ @@ -65,10 +112,17 @@ public function testGetItemSingleIdentifier() ]); $managerRegistry = $this->getManagerRegistry(Dummy::class, $aggregationBuilder); + $this->resourceMetadataFactoryProphecy->create(Dummy::class)->willReturn(new ResourceMetadata( + 'Dummy', + null, + null, + ['foo' => ['doctrine_mongodb' => ['execute_options' => ['allowDiskUse' => true]]]] + )); + $extensionProphecy = $this->prophesize(AggregationItemExtensionInterface::class); $extensionProphecy->applyToItem($aggregationBuilder, Dummy::class, ['id' => 1], 'foo', $context)->shouldBeCalled(); - $dataProvider = new ItemDataProvider($managerRegistry, $propertyNameCollectionFactory, $propertyMetadataFactory, [$extensionProphecy->reveal()]); + $dataProvider = new ItemDataProvider($managerRegistry, $this->resourceMetadataFactoryProphecy->reveal(), $propertyNameCollectionFactory, $propertyMetadataFactory, [$extensionProphecy->reveal()]); $this->assertEquals($result, $dataProvider->getItem(Dummy::class, ['id' => 1], 'foo', $context)); } @@ -88,7 +142,7 @@ public function testGetItemDoubleIdentifier() $aggregationBuilderProphecy = $this->prophesize(Builder::class); $aggregationBuilderProphecy->match()->willReturn($matchProphecy->reveal())->shouldBeCalled(); $aggregationBuilderProphecy->hydrate(Dummy::class)->willReturn($aggregationBuilderProphecy)->shouldBeCalled(); - $aggregationBuilderProphecy->execute()->willReturn($iterator->reveal())->shouldBeCalled(); + $aggregationBuilderProphecy->execute([])->willReturn($iterator->reveal())->shouldBeCalled(); $aggregationBuilder = $aggregationBuilderProphecy->reveal(); [$propertyNameCollectionFactory, $propertyMetadataFactory] = $this->getMetadataFactories(Dummy::class, [ @@ -97,11 +151,13 @@ public function testGetItemDoubleIdentifier() ]); $managerRegistry = $this->getManagerRegistry(Dummy::class, $aggregationBuilder); + $this->resourceMetadataFactoryProphecy->create(Dummy::class)->willReturn(new ResourceMetadata()); + $context = [IdentifierConverterInterface::HAS_IDENTIFIER_CONVERTER => true]; $extensionProphecy = $this->prophesize(AggregationItemExtensionInterface::class); $extensionProphecy->applyToItem($aggregationBuilder, Dummy::class, ['ida' => 1, 'idb' => 2], 'foo', $context)->shouldBeCalled(); - $dataProvider = new ItemDataProvider($managerRegistry, $propertyNameCollectionFactory, $propertyMetadataFactory, [$extensionProphecy->reveal()]); + $dataProvider = new ItemDataProvider($managerRegistry, $this->resourceMetadataFactoryProphecy->reveal(), $propertyNameCollectionFactory, $propertyMetadataFactory, [$extensionProphecy->reveal()]); $this->assertEquals($result, $dataProvider->getItem(Dummy::class, ['ida' => 1, 'idb' => 2], 'foo', $context)); } @@ -126,7 +182,7 @@ public function testGetItemWrongCompositeIdentifier() ], ]); - $dataProvider = new ItemDataProvider($managerRegistry, $propertyNameCollectionFactory, $propertyMetadataFactory); + $dataProvider = new ItemDataProvider($managerRegistry, $this->resourceMetadataFactoryProphecy->reveal(), $propertyNameCollectionFactory, $propertyMetadataFactory); $dataProvider->getItem(Dummy::class, 'ida=1;', 'foo'); } @@ -151,7 +207,7 @@ public function testAggregationResultExtension() $extensionProphecy->supportsResult(Dummy::class, 'foo', $context)->willReturn(true)->shouldBeCalled(); $extensionProphecy->getResult($aggregationBuilder, Dummy::class, 'foo', $context)->willReturn([])->shouldBeCalled(); - $dataProvider = new ItemDataProvider($managerRegistry, $propertyNameCollectionFactory, $propertyMetadataFactory, [$extensionProphecy->reveal()]); + $dataProvider = new ItemDataProvider($managerRegistry, $this->resourceMetadataFactoryProphecy->reveal(), $propertyNameCollectionFactory, $propertyMetadataFactory, [$extensionProphecy->reveal()]); $this->assertEquals([], $dataProvider->getItem(Dummy::class, ['id' => 1], 'foo', $context)); } @@ -167,7 +223,7 @@ public function testUnsupportedClass() 'id', ]); - $dataProvider = new ItemDataProvider($managerRegistryProphecy->reveal(), $propertyNameCollectionFactory, $propertyMetadataFactory, [$extensionProphecy->reveal()]); + $dataProvider = new ItemDataProvider($managerRegistryProphecy->reveal(), $this->resourceMetadataFactoryProphecy->reveal(), $propertyNameCollectionFactory, $propertyMetadataFactory, [$extensionProphecy->reveal()]); $this->assertFalse($dataProvider->supports(Dummy::class, 'foo')); } @@ -190,7 +246,7 @@ public function testCannotCreateAggregationBuilder() 'id', ]); - (new ItemDataProvider($managerRegistryProphecy->reveal(), $propertyNameCollectionFactory, $propertyMetadataFactory, [$extensionProphecy->reveal()]))->getItem(Dummy::class, 'foo', null, [IdentifierConverterInterface::HAS_IDENTIFIER_CONVERTER => true]); + (new ItemDataProvider($managerRegistryProphecy->reveal(), $this->resourceMetadataFactoryProphecy->reveal(), $propertyNameCollectionFactory, $propertyMetadataFactory, [$extensionProphecy->reveal()]))->getItem(Dummy::class, 'foo', null, [IdentifierConverterInterface::HAS_IDENTIFIER_CONVERTER => true]); } /** diff --git a/tests/Bridge/Doctrine/MongoDbOdm/SubresourceDataProviderTest.php b/tests/Bridge/Doctrine/MongoDbOdm/SubresourceDataProviderTest.php index 301843efa60..5745364d34f 100644 --- a/tests/Bridge/Doctrine/MongoDbOdm/SubresourceDataProviderTest.php +++ b/tests/Bridge/Doctrine/MongoDbOdm/SubresourceDataProviderTest.php @@ -22,6 +22,8 @@ use ApiPlatform\Core\Metadata\Property\Factory\PropertyNameCollectionFactoryInterface; use ApiPlatform\Core\Metadata\Property\PropertyMetadata; use ApiPlatform\Core\Metadata\Property\PropertyNameCollection; +use ApiPlatform\Core\Metadata\Resource\Factory\ResourceMetadataFactoryInterface; +use ApiPlatform\Core\Metadata\Resource\ResourceMetadata; use ApiPlatform\Core\Tests\Fixtures\TestBundle\Document\Dummy; use ApiPlatform\Core\Tests\Fixtures\TestBundle\Document\RelatedDummy; use ApiPlatform\Core\Tests\Fixtures\TestBundle\Document\RelatedOwningDummy; @@ -45,6 +47,18 @@ */ class SubresourceDataProviderTest extends TestCase { + private $resourceMetadataFactoryProphecy; + + /** + * {@inheritdoc} + */ + protected function setUp(): void + { + parent::setUp(); + + $this->resourceMetadataFactoryProphecy = $this->prophesize(ResourceMetadataFactoryInterface::class); + } + private function getMetadataProphecies(array $resourceClassesIdentifiers) { $propertyNameCollectionFactoryProphecy = $this->prophesize(PropertyNameCollectionFactoryInterface::class); @@ -94,7 +108,7 @@ public function testNotASubresource() $aggregationBuilder = $this->prophesize(Builder::class)->reveal(); $managerRegistry = $this->getManagerRegistryProphecy($aggregationBuilder, $identifiers, Dummy::class); - $dataProvider = new SubresourceDataProvider($managerRegistry, $propertyNameCollectionFactory, $propertyMetadataFactory, []); + $dataProvider = new SubresourceDataProvider($managerRegistry, $this->resourceMetadataFactoryProphecy->reveal(), $propertyNameCollectionFactory, $propertyMetadataFactory, []); $dataProvider->getSubresource(Dummy::class, ['id' => 1], []); } @@ -126,7 +140,7 @@ public function testGetSubresource() $dummyIterator = $this->prophesize(Iterator::class); $dummyIterator->toArray()->shouldBeCalled()->willReturn([['_id' => 1, 'relatedDummies' => [['_id' => 2]]]]); - $dummyAggregationBuilder->execute()->shouldBeCalled()->willReturn($dummyIterator->reveal()); + $dummyAggregationBuilder->execute([])->shouldBeCalled()->willReturn($dummyIterator->reveal()); $managerProphecy->createAggregationBuilder(Dummy::class)->shouldBeCalled()->willReturn($dummyAggregationBuilder->reveal()); @@ -137,16 +151,18 @@ public function testGetSubresource() $iterator = $this->prophesize(Iterator::class); $iterator->toArray()->shouldBeCalled()->willReturn([]); - $aggregationBuilder->execute()->shouldBeCalled()->willReturn($iterator->reveal()); + $aggregationBuilder->execute([])->shouldBeCalled()->willReturn($iterator->reveal()); $aggregationBuilder->hydrate(RelatedDummy::class)->shouldBeCalled()->willReturn($aggregationBuilder); $managerRegistryProphecy = $this->prophesize(ManagerRegistry::class); $managerRegistryProphecy->getManagerForClass(RelatedDummy::class)->shouldBeCalled()->willReturn($managerProphecy->reveal()); $managerRegistryProphecy->getManagerForClass(Dummy::class)->shouldBeCalled()->willReturn($managerProphecy->reveal()); + $this->resourceMetadataFactoryProphecy->create(RelatedDummy::class)->willReturn(new ResourceMetadata()); + [$propertyNameCollectionFactory, $propertyMetadataFactory] = $this->getMetadataProphecies([Dummy::class => ['id']]); - $dataProvider = new SubresourceDataProvider($managerRegistryProphecy->reveal(), $propertyNameCollectionFactory, $propertyMetadataFactory); + $dataProvider = new SubresourceDataProvider($managerRegistryProphecy->reveal(), $this->resourceMetadataFactoryProphecy->reveal(), $propertyNameCollectionFactory, $propertyMetadataFactory); $context = ['property' => 'relatedDummies', 'identifiers' => [['id', Dummy::class]], 'collection' => true, IdentifierConverterInterface::HAS_IDENTIFIER_CONVERTER => true]; @@ -171,7 +187,7 @@ public function testGetSubSubresourceItem() $dummyIterator = $this->prophesize(Iterator::class); $dummyIterator->toArray()->shouldBeCalled()->willReturn([['_id' => 1, 'relatedDummies' => [['_id' => 2]]]]); - $dummyAggregationBuilder->execute()->shouldBeCalled()->willReturn($dummyIterator->reveal()); + $dummyAggregationBuilder->execute([])->shouldBeCalled()->willReturn($dummyIterator->reveal()); $classMetadataProphecy = $this->prophesize(ClassMetadata::class); $classMetadataProphecy->hasAssociation('relatedDummies')->willReturn(true)->shouldBeCalled(); @@ -198,7 +214,7 @@ public function testGetSubSubresourceItem() $rIterator = $this->prophesize(Iterator::class); $rIterator->toArray()->shouldBeCalled()->willReturn([['_id' => 1, 'thirdLevel' => [['_id' => 3]]]]); - $rAggregationBuilder->execute()->shouldBeCalled()->willReturn($rIterator->reveal()); + $rAggregationBuilder->execute([])->shouldBeCalled()->willReturn($rIterator->reveal()); $rClassMetadataProphecy = $this->prophesize(ClassMetadata::class); $rClassMetadataProphecy->hasAssociation('thirdLevel')->shouldBeCalled()->willReturn(true); @@ -220,7 +236,7 @@ public function testGetSubSubresourceItem() $iterator = $this->prophesize(Iterator::class); $iterator->current()->shouldBeCalled()->willReturn($result); - $aggregationBuilder->execute()->shouldBeCalled()->willReturn($iterator->reveal()); + $aggregationBuilder->execute([])->shouldBeCalled()->willReturn($iterator->reveal()); $aggregationBuilder->hydrate(ThirdLevel::class)->shouldBeCalled()->willReturn($aggregationBuilder); $repositoryProphecy = $this->prophesize(DocumentRepository::class); @@ -231,15 +247,114 @@ public function testGetSubSubresourceItem() $managerRegistryProphecy->getManagerForClass(ThirdLevel::class)->shouldBeCalled()->willReturn($managerProphecy->reveal()); + $this->resourceMetadataFactoryProphecy->create(ThirdLevel::class)->willReturn(new ResourceMetadata()); + [$propertyNameCollectionFactory, $propertyMetadataFactory] = $this->getMetadataProphecies([Dummy::class => $identifiers, RelatedDummy::class => $identifiers]); - $dataProvider = new SubresourceDataProvider($managerRegistryProphecy->reveal(), $propertyNameCollectionFactory, $propertyMetadataFactory); + $dataProvider = new SubresourceDataProvider($managerRegistryProphecy->reveal(), $this->resourceMetadataFactoryProphecy->reveal(), $propertyNameCollectionFactory, $propertyMetadataFactory); $context = ['property' => 'thirdLevel', 'identifiers' => [['id', Dummy::class], ['relatedDummies', RelatedDummy::class]], 'collection' => false, IdentifierConverterInterface::HAS_IDENTIFIER_CONVERTER => true]; $this->assertEquals($result, $dataProvider->getSubresource(ThirdLevel::class, ['id' => ['id' => 1], 'relatedDummies' => ['id' => 1]], $context)); } + public function testGetSubSubresourceItemWithExecuteOptions() + { + $managerRegistryProphecy = $this->prophesize(ManagerRegistry::class); + $identifiers = ['id']; + + // First manager (Dummy) + $dummyAggregationBuilder = $this->prophesize(Builder::class); + $dummyLookup = $this->prophesize(Lookup::class); + $dummyLookup->alias('relatedDummies')->shouldBeCalled(); + $dummyAggregationBuilder->lookup('relatedDummies')->shouldBeCalled()->willReturn($dummyLookup->reveal()); + + $dummyMatch = $this->prophesize(Match::class); + $dummyMatch->equals(1)->shouldBeCalled(); + $dummyMatch->field('id')->shouldBeCalled()->willReturn($dummyMatch); + $dummyAggregationBuilder->match()->shouldBeCalled()->willReturn($dummyMatch->reveal()); + + $dummyIterator = $this->prophesize(Iterator::class); + $dummyIterator->toArray()->shouldBeCalled()->willReturn([['_id' => 1, 'relatedDummies' => [['_id' => 2]]]]); + $dummyAggregationBuilder->execute(['allowDiskUse' => true])->shouldBeCalled()->willReturn($dummyIterator->reveal()); + + $classMetadataProphecy = $this->prophesize(ClassMetadata::class); + $classMetadataProphecy->hasAssociation('relatedDummies')->willReturn(true)->shouldBeCalled(); + + $dummyManagerProphecy = $this->prophesize(DocumentManager::class); + $dummyManagerProphecy->createAggregationBuilder(Dummy::class)->shouldBeCalled()->willReturn($dummyAggregationBuilder->reveal()); + $dummyManagerProphecy->getClassMetadata(Dummy::class)->shouldBeCalled()->willReturn($classMetadataProphecy->reveal()); + + $managerRegistryProphecy->getManagerForClass(Dummy::class)->shouldBeCalled()->willReturn($dummyManagerProphecy->reveal()); + + // Second manager (RelatedDummy) + $rAggregationBuilder = $this->prophesize(Builder::class); + $rLookup = $this->prophesize(Lookup::class); + $rLookup->alias('thirdLevel')->shouldBeCalled(); + $rAggregationBuilder->lookup('thirdLevel')->shouldBeCalled()->willReturn($rLookup->reveal()); + + $rMatch = $this->prophesize(Match::class); + $rMatch->equals(1)->shouldBeCalled(); + $rMatch->field('id')->shouldBeCalled()->willReturn($rMatch); + $previousRMatch = $this->prophesize(Match::class); + $previousRMatch->in([2])->shouldBeCalled(); + $previousRMatch->field('_id')->shouldBeCalled()->willReturn($previousRMatch); + $rAggregationBuilder->match()->shouldBeCalled()->willReturn($rMatch->reveal(), $previousRMatch->reveal()); + + $rIterator = $this->prophesize(Iterator::class); + $rIterator->toArray()->shouldBeCalled()->willReturn([['_id' => 1, 'thirdLevel' => [['_id' => 3]]]]); + $rAggregationBuilder->execute(['allowDiskUse' => true])->shouldBeCalled()->willReturn($rIterator->reveal()); + + $rClassMetadataProphecy = $this->prophesize(ClassMetadata::class); + $rClassMetadataProphecy->hasAssociation('thirdLevel')->shouldBeCalled()->willReturn(true); + + $rDummyManagerProphecy = $this->prophesize(DocumentManager::class); + $rDummyManagerProphecy->createAggregationBuilder(RelatedDummy::class)->shouldBeCalled()->willReturn($rAggregationBuilder->reveal()); + $rDummyManagerProphecy->getClassMetadata(RelatedDummy::class)->shouldBeCalled()->willReturn($rClassMetadataProphecy->reveal()); + + $managerRegistryProphecy->getManagerForClass(RelatedDummy::class)->shouldBeCalled()->willReturn($rDummyManagerProphecy->reveal()); + + $result = new \stdClass(); + // Origin manager (ThirdLevel) + $aggregationBuilder = $this->prophesize(Builder::class); + + $match = $this->prophesize(Match::class); + $match->in([3])->shouldBeCalled(); + $match->field('_id')->shouldBeCalled()->willReturn($match); + $aggregationBuilder->match()->shouldBeCalled()->willReturn($match); + + $iterator = $this->prophesize(Iterator::class); + $iterator->current()->shouldBeCalled()->willReturn($result); + $aggregationBuilder->execute(['allowDiskUse' => true])->shouldBeCalled()->willReturn($iterator->reveal()); + $aggregationBuilder->hydrate(ThirdLevel::class)->shouldBeCalled()->willReturn($aggregationBuilder); + + $repositoryProphecy = $this->prophesize(DocumentRepository::class); + $repositoryProphecy->createAggregationBuilder()->shouldBeCalled()->willReturn($aggregationBuilder->reveal()); + + $managerProphecy = $this->prophesize(DocumentManager::class); + $managerProphecy->getRepository(ThirdLevel::class)->shouldBeCalled()->willReturn($repositoryProphecy->reveal()); + + $managerRegistryProphecy->getManagerForClass(ThirdLevel::class)->shouldBeCalled()->willReturn($managerProphecy->reveal()); + + $this->resourceMetadataFactoryProphecy->create(ThirdLevel::class)->willReturn(new ResourceMetadata( + 'ThirdLevel', + null, + null, + null, + null, + null, + ['third_level_operation_name' => ['doctrine_mongodb' => ['execute_options' => ['allowDiskUse' => true]]]] + )); + + [$propertyNameCollectionFactory, $propertyMetadataFactory] = $this->getMetadataProphecies([Dummy::class => $identifiers, RelatedDummy::class => $identifiers]); + + $dataProvider = new SubresourceDataProvider($managerRegistryProphecy->reveal(), $this->resourceMetadataFactoryProphecy->reveal(), $propertyNameCollectionFactory, $propertyMetadataFactory); + + $context = ['property' => 'thirdLevel', 'identifiers' => [['id', Dummy::class], ['relatedDummies', RelatedDummy::class]], 'collection' => false, IdentifierConverterInterface::HAS_IDENTIFIER_CONVERTER => true]; + + $this->assertEquals($result, $dataProvider->getSubresource(ThirdLevel::class, ['id' => ['id' => 1], 'relatedDummies' => ['id' => 1]], $context, 'third_level_operation_name')); + } + public function testGetSubresourceOneToOneOwningRelation() { // RelatedOwningDummy OneToOne Dummy @@ -274,16 +389,18 @@ public function testGetSubresourceOneToOneOwningRelation() $iterator->toArray()->shouldBeCalled()->willReturn([['_id' => 1, 'ownedDummy' => [['_id' => 3]]]]); $result = new \stdClass(); $iterator->current()->shouldBeCalled()->willReturn($result); - $aggregationBuilder->execute()->shouldBeCalled()->willReturn($iterator->reveal()); + $aggregationBuilder->execute([])->shouldBeCalled()->willReturn($iterator->reveal()); $aggregationBuilder->hydrate(RelatedOwningDummy::class)->shouldBeCalled()->willReturn($aggregationBuilder); $managerRegistryProphecy = $this->prophesize(ManagerRegistry::class); $managerRegistryProphecy->getManagerForClass(RelatedOwningDummy::class)->shouldBeCalled()->willReturn($managerProphecy->reveal()); $managerRegistryProphecy->getManagerForClass(Dummy::class)->shouldBeCalled()->willReturn($managerProphecy->reveal()); + $this->resourceMetadataFactoryProphecy->create(RelatedOwningDummy::class)->willReturn(new ResourceMetadata()); + [$propertyNameCollectionFactory, $propertyMetadataFactory] = $this->getMetadataProphecies([Dummy::class => $identifiers]); - $dataProvider = new SubresourceDataProvider($managerRegistryProphecy->reveal(), $propertyNameCollectionFactory, $propertyMetadataFactory); + $dataProvider = new SubresourceDataProvider($managerRegistryProphecy->reveal(), $this->resourceMetadataFactoryProphecy->reveal(), $propertyNameCollectionFactory, $propertyMetadataFactory); $context = ['property' => 'ownedDummy', 'identifiers' => [['id', Dummy::class]], 'collection' => false, IdentifierConverterInterface::HAS_IDENTIFIER_CONVERTER => true]; @@ -321,12 +438,14 @@ public function testAggregationResultExtension() $iterator = $this->prophesize(Iterator::class); $iterator->toArray()->shouldBeCalled()->willReturn([['_id' => 1, 'relatedDummies' => [['_id' => 3]]]]); - $aggregationBuilder->execute()->shouldBeCalled()->willReturn($iterator->reveal()); + $aggregationBuilder->execute([])->shouldBeCalled()->willReturn($iterator->reveal()); $managerRegistryProphecy = $this->prophesize(ManagerRegistry::class); $managerRegistryProphecy->getManagerForClass(RelatedDummy::class)->shouldBeCalled()->willReturn($managerProphecy->reveal()); $managerRegistryProphecy->getManagerForClass(Dummy::class)->shouldBeCalled()->willReturn($managerProphecy->reveal()); + $this->resourceMetadataFactoryProphecy->create(RelatedDummy::class)->willReturn(new ResourceMetadata()); + [$propertyNameCollectionFactory, $propertyMetadataFactory] = $this->getMetadataProphecies([Dummy::class => $identifiers]); $extensionProphecy = $this->prophesize(AggregationResultCollectionExtensionInterface::class); @@ -334,7 +453,7 @@ public function testAggregationResultExtension() $extensionProphecy->supportsResult(RelatedDummy::class, null, Argument::type('array'))->willReturn(true)->shouldBeCalled(); $extensionProphecy->getResult($aggregationBuilder, RelatedDummy::class, null, Argument::type('array'))->willReturn([])->shouldBeCalled(); - $dataProvider = new SubresourceDataProvider($managerRegistryProphecy->reveal(), $propertyNameCollectionFactory, $propertyMetadataFactory, [$extensionProphecy->reveal()]); + $dataProvider = new SubresourceDataProvider($managerRegistryProphecy->reveal(), $this->resourceMetadataFactoryProphecy->reveal(), $propertyNameCollectionFactory, $propertyMetadataFactory, [$extensionProphecy->reveal()]); $context = ['property' => 'relatedDummies', 'identifiers' => [['id', Dummy::class]], 'collection' => true, IdentifierConverterInterface::HAS_IDENTIFIER_CONVERTER => true]; @@ -357,7 +476,7 @@ public function testCannotCreateQueryBuilder() [$propertyNameCollectionFactory, $propertyMetadataFactory] = $this->getMetadataProphecies([Dummy::class => $identifiers]); - $dataProvider = new SubresourceDataProvider($managerRegistryProphecy->reveal(), $propertyNameCollectionFactory, $propertyMetadataFactory); + $dataProvider = new SubresourceDataProvider($managerRegistryProphecy->reveal(), $this->resourceMetadataFactoryProphecy->reveal(), $propertyNameCollectionFactory, $propertyMetadataFactory); $dataProvider->getSubresource(Dummy::class, ['id' => 1], []); } @@ -371,7 +490,7 @@ public function testThrowResourceClassNotSupportedException() [$propertyNameCollectionFactory, $propertyMetadataFactory] = $this->getMetadataProphecies([Dummy::class => $identifiers]); - $dataProvider = new SubresourceDataProvider($managerRegistryProphecy->reveal(), $propertyNameCollectionFactory, $propertyMetadataFactory); + $dataProvider = new SubresourceDataProvider($managerRegistryProphecy->reveal(), $this->resourceMetadataFactoryProphecy->reveal(), $propertyNameCollectionFactory, $propertyMetadataFactory); $dataProvider->getSubresource(Dummy::class, ['id' => 1], []); } @@ -401,7 +520,7 @@ public function testGetSubresourceCollectionItem() $rIterator = $this->prophesize(Iterator::class); $rIterator->current()->shouldBeCalled()->willReturn($result); - $rAggregationBuilder->execute()->shouldBeCalled()->willReturn($rIterator->reveal()); + $rAggregationBuilder->execute([])->shouldBeCalled()->willReturn($rIterator->reveal()); $rAggregationBuilder->hydrate(RelatedDummy::class)->shouldBeCalled()->willReturn($rAggregationBuilder); $aggregationBuilder = $this->prophesize(Builder::class); @@ -411,9 +530,11 @@ public function testGetSubresourceCollectionItem() $rDummyManagerProphecy->getRepository(RelatedDummy::class)->shouldBeCalled()->willReturn($repositoryProphecy->reveal()); + $this->resourceMetadataFactoryProphecy->create(RelatedDummy::class)->willReturn(new ResourceMetadata()); + [$propertyNameCollectionFactory, $propertyMetadataFactory] = $this->getMetadataProphecies([Dummy::class => $identifiers, RelatedDummy::class => $identifiers]); - $dataProvider = new SubresourceDataProvider($managerRegistryProphecy->reveal(), $propertyNameCollectionFactory, $propertyMetadataFactory); + $dataProvider = new SubresourceDataProvider($managerRegistryProphecy->reveal(), $this->resourceMetadataFactoryProphecy->reveal(), $propertyNameCollectionFactory, $propertyMetadataFactory); $context = ['property' => 'id', 'identifiers' => [['id', Dummy::class, true], ['relatedDummies', RelatedDummy::class, true]], 'collection' => false, IdentifierConverterInterface::HAS_IDENTIFIER_CONVERTER => true]; diff --git a/tests/Fixtures/TestBundle/Document/Dummy.php b/tests/Fixtures/TestBundle/Document/Dummy.php index 2ddc9f878e8..a25c1bff186 100644 --- a/tests/Fixtures/TestBundle/Document/Dummy.php +++ b/tests/Fixtures/TestBundle/Document/Dummy.php @@ -27,6 +27,11 @@ * @author Alexandre Delplace * * @ApiResource(attributes={ + * "doctrine_mongodb"={ + * "execute_options"={ + * "allowDiskUse"=true + * } + * }, * "filters"={ * "my_dummy.mongodb.boolean", * "my_dummy.mongodb.date",