From 76bd7e4a0f7e8c1a7bd70dc9882793431dfda62a Mon Sep 17 00:00:00 2001 From: Teoh Han Hui Date: Fri, 22 Jun 2018 17:14:21 +0200 Subject: [PATCH] Fix tests and some minor refactoring --- features/hydra/collection.feature | 2 +- .../Orm/Extension/PaginationExtension.php | 61 ++-- src/DataProvider/Pagination.php | 36 ++- .../Orm/Extension/PaginationExtensionTest.php | 275 ++++++++++-------- .../ApiPlatformExtensionTest.php | 47 +-- .../DependencyInjection/ConfigurationTest.php | 4 + 6 files changed, 235 insertions(+), 190 deletions(-) diff --git a/features/hydra/collection.feature b/features/hydra/collection.feature index 3ddd6787e71..b63eb2875e8 100644 --- a/features/hydra/collection.feature +++ b/features/hydra/collection.feature @@ -434,4 +434,4 @@ Feature: Collections support When I send a "GET" request to "/dummies?itemsPerPage=0&page=2" Then the response status code should be 400 - And the JSON node "hydra:description" should be equal to "Page should not be greater than 1 if itemsPerPage is equal to 0" + And the JSON node "hydra:description" should be equal to "Page should not be greater than 1 if limit is equal to 0" diff --git a/src/Bridge/Doctrine/Orm/Extension/PaginationExtension.php b/src/Bridge/Doctrine/Orm/Extension/PaginationExtension.php index fb5c52e2172..84e2a8b657d 100644 --- a/src/Bridge/Doctrine/Orm/Extension/PaginationExtension.php +++ b/src/Bridge/Doctrine/Orm/Extension/PaginationExtension.php @@ -21,11 +21,9 @@ use ApiPlatform\Core\Exception\InvalidArgumentException; use ApiPlatform\Core\Metadata\Resource\Factory\ResourceMetadataFactoryInterface; use Doctrine\Common\Persistence\ManagerRegistry; -use Doctrine\Common\Util\Inflector; use Doctrine\ORM\QueryBuilder; use Doctrine\ORM\Tools\Pagination\Paginator as DoctrineOrmPaginator; use Symfony\Component\HttpFoundation\RequestStack; -use Symfony\Component\Validator\Mapping\Factory\MetadataFactoryInterface; /** * Applies pagination on the Doctrine query for resource collection when enabled. @@ -52,41 +50,44 @@ public function __construct(ManagerRegistry $managerRegistry, /* ResourceMetadat $requestStack = $resourceMetadataFactory; $resourceMetadataFactory = $pagination; - if (3 < \count($args = func_get_args())) { - @trigger_error(sprintf('Passing "$enabled", "$clientEnabled", "$clientItemsPerPage", "$itemsPerPage", "$pageParameterName", "$enabledParameterName", "$itemsPerPageParameterName", "$maximumItemPerPage", "$partial", "$clientPartial" and "$partialParameterName" arguments is deprecated since API Platform 2.3 and will not be possible anymore in API Platform 3. Pass an instance of "%s" as third argument instead.', Paginator::class), E_USER_DEPRECATED); - } - - $options = []; - $legacyArgs = [ - ['name' => 'enabled', 'type' => 'bool', 'default' => true], - ['name' => 'client_enabled', 'type' => 'bool', 'default' => false], - ['name' => 'client_items_per_page', 'type' => 'bool', 'default' => false], - ['name' => 'items_per_page', 'type' => 'bool', 'default' => false], - ['name' => 'page_parameter_name', 'type' => 'string', 'default' => 'page'], - ['name' => 'enabled_parameter_name', 'type' => 'string', 'default' => 'pagination'], - ['name' => 'items_per_page_parameter_name', 'type' => 'string', 'default' => 'itemsPerPage'], - ['name' => 'maximum_items_per_page', 'type' => 'int', 'default' => null], - ['name' => 'partial', 'type' => 'bool', 'default' => false], - ['name' => 'client_partial', 'type' => 'bool', 'default' => false], - ['name' => 'partial_parameter_name', 'type' => 'string', 'default' => 'partial'], + $legacyPaginationArgs = [ + 3 => ['arg_name' => 'enabled', 'option_name' => 'enabled', 'type' => 'bool', 'default' => true], + 4 => ['arg_name' => 'clientEnabled', 'option_name' => 'client_enabled', 'type' => 'bool', 'default' => false], + 5 => ['arg_name' => 'clientItemsPerPage', 'option_name' => 'client_items_per_page', 'type' => 'bool', 'default' => false], + 6 => ['arg_name' => 'itemsPerPage', 'option_name' => 'items_per_page', 'type' => 'int', 'default' => 30], + 7 => ['arg_name' => 'pageParameterName', 'option_name' => 'page_parameter_name', 'type' => 'string', 'default' => 'page'], + 8 => ['arg_name' => 'enabledParameterName', 'option_name' => 'enabled_parameter_name', 'type' => 'string', 'default' => 'pagination'], + 9 => ['arg_name' => 'itemsPerPageParameterName', 'option_name' => 'items_per_page_parameter_name', 'type' => 'string', 'default' => 'itemsPerPage'], + 10 => ['arg_name' => 'maximumItemPerPage', 'option_name' => 'maximum_items_per_page', 'type' => 'int', 'default' => null], + 11 => ['arg_name' => 'partial', 'option_name' => 'partial', 'type' => 'bool', 'default' => false], + 12 => ['arg_name' => 'clientPartial', 'option_name' => 'client_partial', 'type' => 'bool', 'default' => false], + 13 => ['arg_name' => 'partialParameterName', 'option_name' => 'partial_parameter_name', 'type' => 'string', 'default' => 'partial'], ]; - foreach ($legacyArgs as $i => $arg) { - $option = null; - if (array_key_exists($i + 3, $args)) { - if (!\call_user_func('is_'.$arg['type'], $args[$i + 3]) && !(null === $arg['default'] && null === $args[$i + 3])) { - throw new InvalidArgumentException(sprintf('The "$%s" argument is expected to be a %s%s.', Inflector::camelize($arg['name']), $arg['type'], null === $arg['default'] ? ' or null' : '')); + $paginationOptions = array_column($legacyPaginationArgs, 'default', 'option_name'); + + if (0 < \count($legacyArgs = \array_slice(\func_get_args(), 3, null, true))) { + @trigger_error(sprintf('Passing "$%s" arguments is deprecated since API Platform 2.3 and will not be possible anymore in API Platform 3. Pass an instance of "%s" as third argument instead.', implode('", "$', array_column($legacyPaginationArgs, 'arg_name')), Paginator::class), E_USER_DEPRECATED); + + foreach ($legacyArgs as $pos => $arg) { + [ + 'arg_name' => $argName, + 'option_name' => $optionName, + 'type' => $type, + 'default' => $default, + ] = $legacyPaginationArgs[$pos]; + + if (!(\call_user_func("is_{$type}", $arg) || null === $default && null === $arg)) { + throw new InvalidArgumentException(sprintf('The "$%s" argument is expected to be a %s%s.', $argName, $type, null === $default ? ' or null' : '')); } - $option = $args[$i + 3]; + $paginationOptions[$optionName] = $arg; } - - $options[$arg['name']] = $option ?? $arg['default']; } - $pagination = new Pagination($requestStack, $resourceMetadataFactory, $options); + $pagination = new Pagination($requestStack, $resourceMetadataFactory, $paginationOptions); } elseif (!$resourceMetadataFactory instanceof ResourceMetadataFactoryInterface) { - throw new InvalidArgumentException(sprintf('The "$resourceMetadataFactory" argument is expected to be an implementation of the "%s" interface.', MetadataFactoryInterface::class)); + throw new InvalidArgumentException(sprintf('The "$resourceMetadataFactory" argument is expected to be an implementation of the "%s" interface.', ResourceMetadataFactoryInterface::class)); } elseif (!$pagination instanceof Pagination) { throw new InvalidArgumentException(sprintf('The "$pagination" argument is expected to be an instance of the "%s" class.', Pagination::class)); } @@ -167,7 +168,7 @@ private function useFetchJoinCollection(QueryBuilder $queryBuilder, string $reso $resourceMetadata = $this->resourceMetadataFactory->create($resourceClass); - return $resourceMetadata->getCollectionOperationAttribute($operationName, 'pagination_fetch_join_collection', true, true); + return $resourceMetadata->getCollectionOperationAttribute($operationName, 'pagination_fetch_join_collection', true, true); } /** diff --git a/src/DataProvider/Pagination.php b/src/DataProvider/Pagination.php index cba6c2a2b05..a73830c87ee 100644 --- a/src/DataProvider/Pagination.php +++ b/src/DataProvider/Pagination.php @@ -85,24 +85,31 @@ public function getLimit(string $resourceClass = null, string $operationName = n $clientLimit = $this->options['client_items_per_page']; $request = $this->requestStack->getCurrentRequest(); - if (null !== $resourceClass && $resourceMetadata = $this->resourceMetadataFactory->create($resourceClass)) { + if (null !== $resourceClass) { + $resourceMetadata = $this->resourceMetadataFactory->create($resourceClass); $limit = $resourceMetadata->getCollectionOperationAttribute($operationName, 'pagination_items_per_page', $limit, true); if ($request) { $clientLimit = $resourceMetadata->getCollectionOperationAttribute($operationName, 'pagination_client_items_per_page', $clientLimit, true); - } - } - if (null !== $resourceClass && $request && $request->attributes->get('_graphql')) { - $collectionArgs = $request->attributes->get('_graphql_collections_args', []); - $limit = $collectionArgs[$resourceClass]['first'] ?? $limit; + if ($request->attributes->get('_graphql')) { + $collectionArgs = $request->attributes->get('_graphql_collections_args', []); + $limit = $collectionArgs[$resourceClass]['first'] ?? $limit; + } + } } if ($clientLimit && $request) { $limit = (int) $this->getParameterFromRequest($request, $this->options['items_per_page_parameter_name'], $limit); + $maxItemsPerPage = $this->options['maximum_items_per_page']; + + if (null !== $resourceClass) { + $resourceMetadata = $this->resourceMetadataFactory->create($resourceClass); + $maxItemsPerPage = $resourceMetadata->getCollectionOperationAttribute($operationName, 'maximum_items_per_page', $maxItemsPerPage, true); + } - if (null !== $this->options['maximum_items_per_page'] && $limit > $this->options['maximum_items_per_page']) { - $limit = $this->options['maximum_items_per_page']; + if (null !== $maxItemsPerPage && $limit > $maxItemsPerPage) { + $limit = $maxItemsPerPage; } } @@ -134,15 +141,18 @@ private function getEnabled(string $resourceClass = null, string $operationName $clientEnabled = $this->options[$partial ? 'client_partial' : 'client_enabled']; $request = $this->requestStack->getCurrentRequest(); - if (null !== $resourceClass && $resourceMetadata = $this->resourceMetadataFactory->create($resourceClass)) { + if (null === $request) { + return false; + } + + if (null !== $resourceClass) { + $resourceMetadata = $this->resourceMetadataFactory->create($resourceClass); $enabled = $resourceMetadata->getCollectionOperationAttribute($operationName, $partial ? 'pagination_partial' : 'pagination_enabled', $enabled, true); - if ($request) { - $clientEnabled = $resourceMetadata->getCollectionOperationAttribute($operationName, $partial ? 'pagination_client_partial' : 'pagination_client_enabled', $clientEnabled, true); - } + $clientEnabled = $resourceMetadata->getCollectionOperationAttribute($operationName, $partial ? 'pagination_client_partial' : 'pagination_client_enabled', $clientEnabled, true); } - if ($clientEnabled && $request) { + if ($clientEnabled) { return filter_var($this->getParameterFromRequest($request, $this->options[$partial ? 'partial_parameter_name' : 'enabled_parameter_name'], $enabled), FILTER_VALIDATE_BOOLEAN); } diff --git a/tests/Bridge/Doctrine/Orm/Extension/PaginationExtensionTest.php b/tests/Bridge/Doctrine/Orm/Extension/PaginationExtensionTest.php index 580fc50862c..eabdc3ee82f 100644 --- a/tests/Bridge/Doctrine/Orm/Extension/PaginationExtensionTest.php +++ b/tests/Bridge/Doctrine/Orm/Extension/PaginationExtensionTest.php @@ -15,6 +15,7 @@ use ApiPlatform\Core\Bridge\Doctrine\Orm\Extension\PaginationExtension; use ApiPlatform\Core\Bridge\Doctrine\Orm\Util\QueryNameGenerator; +use ApiPlatform\Core\DataProvider\Pagination; use ApiPlatform\Core\DataProvider\PaginatorInterface; use ApiPlatform\Core\DataProvider\PartialPaginatorInterface; use ApiPlatform\Core\Exception\InvalidArgumentException; @@ -38,18 +39,22 @@ class PaginationExtensionTest extends TestCase { public function testApplyToCollection() { - $requestStack = new RequestStack(); - $requestStack->push(new Request(['pagination' => true, 'itemsPerPage' => 20, '_page' => 2])); - $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))->shouldBeCalled(); + $resourceMetadataFactoryProphecy->create('Foo')->willReturn(new ResourceMetadata(null, null, null, [], [], $attributes)); $resourceMetadataFactory = $resourceMetadataFactoryProphecy->reveal(); + $requestStack = new RequestStack(); + $requestStack->push(new Request(['pagination' => true, 'itemsPerPage' => 20, '_page' => 2])); + + $pagination = new Pagination($requestStack, $resourceMetadataFactory, [ + 'page_parameter_name' => '_page', + ]); + $queryBuilderProphecy = $this->prophesize(QueryBuilder::class); $queryBuilderProphecy->setFirstResult(40)->willReturn($queryBuilderProphecy)->shouldBeCalled(); $queryBuilderProphecy->setMaxResults(40)->shouldBeCalled(); @@ -57,31 +62,31 @@ public function testApplyToCollection() $extension = new PaginationExtension( $this->prophesize(ManagerRegistry::class)->reveal(), - $requestStack, $resourceMetadataFactory, - true, - false, - false, - 30, - '_page' + $pagination ); $extension->applyToCollection($queryBuilder, new QueryNameGenerator(), 'Foo', 'op'); } public function testApplyToCollectionWithItemPerPageZero() { - $requestStack = new RequestStack(); - $requestStack->push(new Request(['pagination' => true, 'itemsPerPage' => 0, '_page' => 1])); - $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))->shouldBeCalled(); + $resourceMetadataFactoryProphecy->create('Foo')->willReturn(new ResourceMetadata(null, null, null, [], [], $attributes)); $resourceMetadataFactory = $resourceMetadataFactoryProphecy->reveal(); + $requestStack = new RequestStack(); + $requestStack->push(new Request(['pagination' => true, 'itemsPerPage' => 0, '_page' => 1])); + + $pagination = new Pagination($requestStack, $resourceMetadataFactory, [ + 'items_per_page' => 0, + 'page_parameter_name' => '_page', + ]); + $queryBuilderProphecy = $this->prophesize(QueryBuilder::class); $queryBuilderProphecy->setFirstResult(0)->willReturn($queryBuilderProphecy)->shouldBeCalled(); $queryBuilderProphecy->setMaxResults(0)->shouldBeCalled(); @@ -89,13 +94,8 @@ public function testApplyToCollectionWithItemPerPageZero() $extension = new PaginationExtension( $this->prophesize(ManagerRegistry::class)->reveal(), - $requestStack, $resourceMetadataFactory, - true, - false, - false, - 0, - '_page' + $pagination ); $extension->applyToCollection($queryBuilder, new QueryNameGenerator(), 'Foo', 'op'); } @@ -103,10 +103,7 @@ public function testApplyToCollectionWithItemPerPageZero() public function testApplyToCollectionWithItemPerPageZeroAndPage2() { $this->expectException(InvalidArgumentException::class); - $this->expectExceptionMessage('Page should not be greater than 1 if itemsPerPage is equal to 0'); - - $requestStack = new RequestStack(); - $requestStack->push(new Request(['pagination' => true, 'itemsPerPage' => 0, '_page' => 2])); + $this->expectExceptionMessage('Page should not be greater than 1 if limit is equal to 0'); $resourceMetadataFactoryProphecy = $this->prophesize(ResourceMetadataFactoryInterface::class); $attributes = [ @@ -114,9 +111,17 @@ public function testApplyToCollectionWithItemPerPageZeroAndPage2() 'pagination_client_enabled' => true, 'pagination_items_per_page' => 0, ]; - $resourceMetadataFactoryProphecy->create('Foo')->willReturn(new ResourceMetadata(null, null, null, [], [], $attributes))->shouldBeCalled(); + $resourceMetadataFactoryProphecy->create('Foo')->willReturn(new ResourceMetadata(null, null, null, [], [], $attributes)); $resourceMetadataFactory = $resourceMetadataFactoryProphecy->reveal(); + $requestStack = new RequestStack(); + $requestStack->push(new Request(['pagination' => true, 'itemsPerPage' => 0, '_page' => 2])); + + $pagination = new Pagination($requestStack, $resourceMetadataFactory, [ + 'items_per_page' => 0, + 'page_parameter_name' => '_page', + ]); + $queryBuilderProphecy = $this->prophesize(QueryBuilder::class); $queryBuilderProphecy->setFirstResult(0)->willReturn($queryBuilderProphecy)->shouldNotBeCalled(); $queryBuilderProphecy->setMaxResults(0)->shouldNotBeCalled(); @@ -124,24 +129,16 @@ public function testApplyToCollectionWithItemPerPageZeroAndPage2() $extension = new PaginationExtension( $this->prophesize(ManagerRegistry::class)->reveal(), - $requestStack, $resourceMetadataFactory, - true, - false, - false, - 0, - '_page' + $pagination ); $extension->applyToCollection($queryBuilder, new QueryNameGenerator(), 'Foo', 'op'); } - public function testApplyToCollectionWithItemPerPageLessThen0() + public function testApplyToCollectionWithItemPerPageLessThan0() { $this->expectException(InvalidArgumentException::class); - $this->expectExceptionMessage('Item per page parameter should not be less than 0'); - - $requestStack = new RequestStack(); - $requestStack->push(new Request(['pagination' => true, 'itemsPerPage' => -20, '_page' => 2])); + $this->expectExceptionMessage('Limit should not be less than 0'); $resourceMetadataFactoryProphecy = $this->prophesize(ResourceMetadataFactoryInterface::class); $attributes = [ @@ -149,9 +146,17 @@ public function testApplyToCollectionWithItemPerPageLessThen0() 'pagination_client_enabled' => true, 'pagination_items_per_page' => -20, ]; - $resourceMetadataFactoryProphecy->create('Foo')->willReturn(new ResourceMetadata(null, null, null, [], [], $attributes))->shouldBeCalled(); + $resourceMetadataFactoryProphecy->create('Foo')->willReturn(new ResourceMetadata(null, null, null, [], [], $attributes)); $resourceMetadataFactory = $resourceMetadataFactoryProphecy->reveal(); + $requestStack = new RequestStack(); + $requestStack->push(new Request(['pagination' => true, 'itemsPerPage' => -20, '_page' => 2])); + + $pagination = new Pagination($requestStack, $resourceMetadataFactory, [ + 'items_per_page' => -20, + 'page_parameter_name' => '_page', + ]); + $queryBuilderProphecy = $this->prophesize(QueryBuilder::class); $queryBuilderProphecy->setFirstResult(40)->willReturn($queryBuilderProphecy)->shouldNotBeCalled(); $queryBuilderProphecy->setMaxResults(40)->shouldNotBeCalled(); @@ -159,31 +164,31 @@ public function testApplyToCollectionWithItemPerPageLessThen0() $extension = new PaginationExtension( $this->prophesize(ManagerRegistry::class)->reveal(), - $requestStack, $resourceMetadataFactory, - true, - false, - false, - -20, - '_page' + $pagination ); $extension->applyToCollection($queryBuilder, new QueryNameGenerator(), 'Foo', 'op'); } public function testApplyToCollectionWithItemPerPageTooHigh() { - $requestStack = new RequestStack(); - $requestStack->push(new Request(['pagination' => true, 'itemsPerPage' => 301, '_page' => 2])); - $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))->shouldBeCalled(); + $resourceMetadataFactoryProphecy->create('Foo')->willReturn(new ResourceMetadata(null, null, null, [], [], $attributes)); $resourceMetadataFactory = $resourceMetadataFactoryProphecy->reveal(); + $requestStack = new RequestStack(); + $requestStack->push(new Request(['pagination' => true, 'itemsPerPage' => 301, '_page' => 2])); + + $pagination = new Pagination($requestStack, $resourceMetadataFactory, [ + 'page_parameter_name' => '_page', + 'maximum_items_per_page' => 300, + ]); + $queryBuilderProphecy = $this->prophesize(QueryBuilder::class); $queryBuilderProphecy->setFirstResult(300)->willReturn($queryBuilderProphecy)->shouldBeCalled(); $queryBuilderProphecy->setMaxResults(300)->shouldBeCalled(); @@ -191,37 +196,31 @@ public function testApplyToCollectionWithItemPerPageTooHigh() $extension = new PaginationExtension( $this->prophesize(ManagerRegistry::class)->reveal(), - $requestStack, $resourceMetadataFactory, - true, - false, - false, - 30, - '_page', - 'pagination', - 'itemsPerPage', - 300 + $pagination ); $extension->applyToCollection($queryBuilder, new QueryNameGenerator(), 'Foo', 'op'); } public function testApplyToCollectionWithGraphql() { - $requestStack = new RequestStack(); - $requestStack->push(new Request(['pagination' => true], [], [ - '_graphql' => true, - '_graphql_collections_args' => ['Foo' => ['first' => 5, 'after' => 'OQ==']], // base64_encode('9') - ])); - $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))->shouldBeCalled(); + $resourceMetadataFactoryProphecy->create('Foo')->willReturn(new ResourceMetadata(null, null, null, [], [], $attributes)); $resourceMetadataFactory = $resourceMetadataFactoryProphecy->reveal(); + $requestStack = new RequestStack(); + $requestStack->push(new Request(['pagination' => true], [], [ + '_graphql' => true, + '_graphql_collections_args' => ['Foo' => ['first' => 5, 'after' => 'OQ==']], // base64_encode('9') + ])); + + $pagination = new Pagination($requestStack, $resourceMetadataFactory); + $queryBuilderProphecy = $this->prophesize(QueryBuilder::class); $queryBuilderProphecy->setFirstResult(10)->willReturn($queryBuilderProphecy)->shouldBeCalled(); $queryBuilderProphecy->setMaxResults(5)->shouldBeCalled(); @@ -229,18 +228,19 @@ public function testApplyToCollectionWithGraphql() $extension = new PaginationExtension( $this->prophesize(ManagerRegistry::class)->reveal(), - $requestStack, $resourceMetadataFactory, - true, - false, - false, - 30 + $pagination ); $extension->applyToCollection($queryBuilder, new QueryNameGenerator(), 'Foo', 'op'); } public function testApplyToCollectionNoRequest() { + $resourceMetadataFactoryProphecy = $this->prophesize(ResourceMetadataFactoryInterface::class); + $resourceMetadataFactory = $resourceMetadataFactoryProphecy->reveal(); + + $pagination = new Pagination(new RequestStack(), $resourceMetadataFactory); + $queryBuilderProphecy = $this->prophesize(QueryBuilder::class); $queryBuilderProphecy->setFirstResult(Argument::any())->shouldNotBeCalled(); $queryBuilderProphecy->setMaxResults(Argument::any())->shouldNotBeCalled(); @@ -248,20 +248,22 @@ public function testApplyToCollectionNoRequest() $extension = new PaginationExtension( $this->prophesize(ManagerRegistry::class)->reveal(), - new RequestStack(), - $this->prophesize(ResourceMetadataFactoryInterface::class)->reveal() + $resourceMetadataFactory, + $pagination ); $extension->applyToCollection($queryBuilder, new QueryNameGenerator(), 'Foo', 'op'); } public function testApplyToCollectionEmptyRequest() { + $resourceMetadataFactoryProphecy = $this->prophesize(ResourceMetadataFactoryInterface::class); + $resourceMetadataFactoryProphecy->create('Foo')->willReturn(new ResourceMetadata(null, null, null, [], [])); + $resourceMetadataFactory = $resourceMetadataFactoryProphecy->reveal(); + $requestStack = new RequestStack(); $requestStack->push(new Request()); - $resourceMetadataFactoryProphecy = $this->prophesize(ResourceMetadataFactoryInterface::class); - $resourceMetadataFactoryProphecy->create('Foo')->willReturn(new ResourceMetadata(null, null, null, [], []))->shouldBeCalled(); - $resourceMetadataFactory = $resourceMetadataFactoryProphecy->reveal(); + $pagination = new Pagination($requestStack, $resourceMetadataFactory); $queryBuilderProphecy = $this->prophesize(QueryBuilder::class); $queryBuilderProphecy->setFirstResult(0)->willReturn($queryBuilderProphecy)->shouldBeCalled(); @@ -270,20 +272,24 @@ public function testApplyToCollectionEmptyRequest() $extension = new PaginationExtension( $this->prophesize(ManagerRegistry::class)->reveal(), - $requestStack, - $resourceMetadataFactory + $resourceMetadataFactory, + $pagination ); $extension->applyToCollection($queryBuilder, new QueryNameGenerator(), 'Foo', 'op'); } public function testApplyToCollectionPaginationDisabled() { + $resourceMetadataFactoryProphecy = $this->prophesize(ResourceMetadataFactoryInterface::class); + $resourceMetadataFactoryProphecy->create('Foo')->willReturn(new ResourceMetadata(null, null, null, [], [])); + $resourceMetadataFactory = $resourceMetadataFactoryProphecy->reveal(); + $requestStack = new RequestStack(); $requestStack->push(new Request()); - $resourceMetadataFactoryProphecy = $this->prophesize(ResourceMetadataFactoryInterface::class); - $resourceMetadataFactoryProphecy->create('Foo')->willReturn(new ResourceMetadata(null, null, null, [], []))->shouldBeCalled(); - $resourceMetadataFactory = $resourceMetadataFactoryProphecy->reveal(); + $pagination = new Pagination($requestStack, $resourceMetadataFactory, [ + 'enabled' => false, + ]); $queryBuilderProphecy = $this->prophesize(QueryBuilder::class); $queryBuilderProphecy->setFirstResult(Argument::any())->shouldNotBeCalled(); @@ -292,27 +298,32 @@ public function testApplyToCollectionPaginationDisabled() $extension = new PaginationExtension( $this->prophesize(ManagerRegistry::class)->reveal(), - $requestStack, $resourceMetadataFactory, - false + $pagination ); $extension->applyToCollection($queryBuilder, new QueryNameGenerator(), 'Foo', 'op'); } public function testApplyToCollectionWithMaximumItemsPerPage() { - $requestStack = new RequestStack(); - $requestStack->push(new Request(['pagination' => true, 'itemsPerPage' => 80, 'page' => 1])); - $resourceMetadataFactoryProphecy = $this->prophesize(ResourceMetadataFactoryInterface::class); $attributes = [ 'pagination_enabled' => true, 'pagination_client_enabled' => true, 'maximum_items_per_page' => 80, ]; - $resourceMetadataFactoryProphecy->create('Foo')->willReturn(new ResourceMetadata(null, null, null, [], [], $attributes))->shouldBeCalled(); + $resourceMetadataFactoryProphecy->create('Foo')->willReturn(new ResourceMetadata(null, null, null, [], [], $attributes)); $resourceMetadataFactory = $resourceMetadataFactoryProphecy->reveal(); + $requestStack = new RequestStack(); + $requestStack->push(new Request(['pagination' => true, 'itemsPerPage' => 80, 'page' => 1])); + + $pagination = new Pagination($requestStack, $resourceMetadataFactory, [ + 'client_enabled' => true, + 'client_items_per_page' => true, + 'maximum_items_per_page' => 50, + ]); + $queryBuilderProphecy = $this->prophesize(QueryBuilder::class); $queryBuilderProphecy->setFirstResult(0)->willReturn($queryBuilderProphecy)->shouldBeCalled(); $queryBuilderProphecy->setMaxResults(80)->shouldBeCalled(); @@ -320,97 +331,104 @@ public function testApplyToCollectionWithMaximumItemsPerPage() $extension = new PaginationExtension( $this->prophesize(ManagerRegistry::class)->reveal(), - $requestStack, $resourceMetadataFactory, - true, - true, - true, - 30, - 'page', - 'pagination', - 'itemsPerPage', - 50 + $pagination ); $extension->applyToCollection($queryBuilder, new QueryNameGenerator(), 'Foo', 'op'); } public function testSupportsResult() { + $resourceMetadataFactoryProphecy = $this->prophesize(ResourceMetadataFactoryInterface::class); + $resourceMetadataFactoryProphecy->create('Foo')->willReturn(new ResourceMetadata(null, null, null, [], [])); + $resourceMetadataFactory = $resourceMetadataFactoryProphecy->reveal(); + $requestStack = new RequestStack(); $requestStack->push(new Request()); - $resourceMetadataFactoryProphecy = $this->prophesize(ResourceMetadataFactoryInterface::class); - $resourceMetadataFactoryProphecy->create('Foo')->willReturn(new ResourceMetadata(null, null, null, [], []))->shouldBeCalled(); - $resourceMetadataFactory = $resourceMetadataFactoryProphecy->reveal(); + $pagination = new Pagination($requestStack, $resourceMetadataFactory); $extension = new PaginationExtension( $this->prophesize(ManagerRegistry::class)->reveal(), - $requestStack, - $resourceMetadataFactory + $resourceMetadataFactory, + $pagination ); $this->assertTrue($extension->supportsResult('Foo', 'op')); } public function testSupportsResultNoRequest() { + $resourceMetadataFactoryProphecy = $this->prophesize(ResourceMetadataFactoryInterface::class); + $resourceMetadataFactory = $resourceMetadataFactoryProphecy->reveal(); + + $pagination = new Pagination(new RequestStack(), $resourceMetadataFactory); + $extension = new PaginationExtension( $this->prophesize(ManagerRegistry::class)->reveal(), - new RequestStack(), - $this->prophesize(ResourceMetadataFactoryInterface::class)->reveal() + $resourceMetadataFactory, + $pagination ); $this->assertFalse($extension->supportsResult('Foo', 'op')); } public function testSupportsResultEmptyRequest() { + $resourceMetadataFactoryProphecy = $this->prophesize(ResourceMetadataFactoryInterface::class); + $resourceMetadataFactoryProphecy->create('Foo')->willReturn(new ResourceMetadata(null, null, null, [], [])); + $resourceMetadataFactory = $resourceMetadataFactoryProphecy->reveal(); + $requestStack = new RequestStack(); $requestStack->push(new Request()); - $resourceMetadataFactoryProphecy = $this->prophesize(ResourceMetadataFactoryInterface::class); - $resourceMetadataFactoryProphecy->create('Foo')->willReturn(new ResourceMetadata(null, null, null, [], []))->shouldBeCalled(); - $resourceMetadataFactory = $resourceMetadataFactoryProphecy->reveal(); + $pagination = new Pagination($requestStack, $resourceMetadataFactory); $extension = new PaginationExtension( $this->prophesize(ManagerRegistry::class)->reveal(), - $requestStack, - $resourceMetadataFactory + $resourceMetadataFactory, + $pagination ); $this->assertTrue($extension->supportsResult('Foo', 'op')); } public function testSupportsResultClientNotAllowedToPaginate() { + $resourceMetadataFactoryProphecy = $this->prophesize(ResourceMetadataFactoryInterface::class); + $resourceMetadataFactoryProphecy->create('Foo')->willReturn(new ResourceMetadata(null, null, null, [], [])); + $resourceMetadataFactory = $resourceMetadataFactoryProphecy->reveal(); + $requestStack = new RequestStack(); $requestStack->push(new Request(['pagination' => true])); - $resourceMetadataFactoryProphecy = $this->prophesize(ResourceMetadataFactoryInterface::class); - $resourceMetadataFactoryProphecy->create('Foo')->willReturn(new ResourceMetadata(null, null, null, [], []))->shouldBeCalled(); - $resourceMetadataFactory = $resourceMetadataFactoryProphecy->reveal(); + $pagination = new Pagination($requestStack, $resourceMetadataFactory, [ + 'enabled' => false, + 'client_enabled' => false, + ]); $extension = new PaginationExtension( $this->prophesize(ManagerRegistry::class)->reveal(), - $requestStack, $resourceMetadataFactory, - false, - false + $pagination ); $this->assertFalse($extension->supportsResult('Foo', 'op')); } public function testSupportsResultPaginationDisabled() { + $resourceMetadataFactoryProphecy = $this->prophesize(ResourceMetadataFactoryInterface::class); + $resourceMetadataFactoryProphecy->create('Foo')->willReturn(new ResourceMetadata(null, null, null, [], [])); + $resourceMetadataFactory = $resourceMetadataFactoryProphecy->reveal(); + $requestStack = new RequestStack(); $requestStack->push(new Request()); - $resourceMetadataFactoryProphecy = $this->prophesize(ResourceMetadataFactoryInterface::class); - $resourceMetadataFactoryProphecy->create('Foo')->willReturn(new ResourceMetadata(null, null, null, [], []))->shouldBeCalled(); - $resourceMetadataFactory = $resourceMetadataFactoryProphecy->reveal(); + $pagination = new Pagination($requestStack, $resourceMetadataFactory, [ + 'enabled' => false, + ]); $extension = new PaginationExtension( $this->prophesize(ManagerRegistry::class)->reveal(), - $requestStack, $resourceMetadataFactory, - false + $pagination ); $this->assertFalse($extension->supportsResult('Foo', 'op')); } @@ -449,36 +467,39 @@ public function testSimpleGetResult() private function getPaginationExtensionResult(bool $partial = false, bool $legacy = false, bool $fetchJoinCollection = true) { - $requestStack = new RequestStack(); - $requestStack->push(new Request(['partial' => $partial])); - $resourceMetadataFactoryProphecy = $this->prophesize(ResourceMetadataFactoryInterface::class); + $resourceMetadataFactory = $resourceMetadataFactoryProphecy->reveal(); if (!$legacy) { - $resourceMetadataFactoryProphecy->create('Foo')->willReturn(new ResourceMetadata(null, null, null, [], [], ['pagination_partial' => false, 'pagination_client_partial' => true, 'pagination_fetch_join_collection' => $fetchJoinCollection]))->shouldBeCalled(); + $resourceMetadataFactoryProphecy->create('Foo')->willReturn(new ResourceMetadata(null, null, null, [], [], ['pagination_partial' => false, 'pagination_client_partial' => true, 'pagination_fetch_join_collection' => $fetchJoinCollection])); } + $requestStack = new RequestStack(); + $requestStack->push(new Request(['partial' => $partial])); + + $pagination = new Pagination($requestStack, $resourceMetadataFactory); + $configuration = new Configuration(); $entityManagerProphecy = $this->prophesize(EntityManagerInterface::class); - $entityManagerProphecy->getConfiguration()->willReturn($configuration)->shouldBeCalled(); + $entityManagerProphecy->getConfiguration()->willReturn($configuration); $query = new Query($entityManagerProphecy->reveal()); $query->setFirstResult(0); $query->setMaxResults(42); $queryBuilderProphecy = $this->prophesize(QueryBuilder::class); - $queryBuilderProphecy->getRootEntities()->willReturn([])->shouldBeCalled(); - $queryBuilderProphecy->getQuery()->willReturn($query)->shouldBeCalled(); + $queryBuilderProphecy->getRootEntities()->willReturn([]); + $queryBuilderProphecy->getQuery()->willReturn($query); $queryBuilderProphecy->getDQLPart(Argument::that(function ($arg) { return \in_array($arg, ['having', 'orderBy', 'join'], true); - }))->willReturn('')->shouldBeCalled(); - $queryBuilderProphecy->getMaxResults()->willReturn(42)->shouldBeCalled(); + }))->willReturn(''); + $queryBuilderProphecy->getMaxResults()->willReturn(42); $paginationExtension = new PaginationExtension( $this->prophesize(ManagerRegistry::class)->reveal(), - $requestStack, - $resourceMetadataFactoryProphecy->reveal() + $resourceMetadataFactory, + $pagination ); $args = [$queryBuilderProphecy->reveal()]; diff --git a/tests/Bridge/Symfony/Bundle/DependencyInjection/ApiPlatformExtensionTest.php b/tests/Bridge/Symfony/Bundle/DependencyInjection/ApiPlatformExtensionTest.php index 81ba71f2bc2..3a1bc15dd71 100644 --- a/tests/Bridge/Symfony/Bundle/DependencyInjection/ApiPlatformExtensionTest.php +++ b/tests/Bridge/Symfony/Bundle/DependencyInjection/ApiPlatformExtensionTest.php @@ -406,14 +406,6 @@ private function getPartialContainerBuilderProphecy($test = false) ->willReturn($childDefinitionProphecy)->shouldBeCalledTimes(1); $childDefinitionProphecy->addTag('api_platform.subresource_data_provider')->shouldBeCalledTimes(1); - $containerBuilderProphecy->registerForAutoconfiguration(QueryItemExtensionInterface::class) - ->willReturn($childDefinitionProphecy)->shouldBeCalledTimes(1); - $childDefinitionProphecy->addTag('api_platform.doctrine.orm.query_extension.item')->shouldBeCalledTimes(1); - - $containerBuilderProphecy->registerForAutoconfiguration(QueryCollectionExtensionInterface::class) - ->willReturn($childDefinitionProphecy)->shouldBeCalledTimes(1); - $childDefinitionProphecy->addTag('api_platform.doctrine.orm.query_extension.collection')->shouldBeCalledTimes(1); - $containerBuilderProphecy->registerForAutoconfiguration(FilterInterface::class) ->willReturn($childDefinitionProphecy)->shouldBeCalledTimes(1); $childDefinitionProphecy->addTag('api_platform.filter')->shouldBeCalledTimes(1); @@ -437,17 +429,6 @@ private function getPartialContainerBuilderProphecy($test = false) $parameters = [ 'api_platform.collection.order' => 'ASC', 'api_platform.collection.order_parameter_name' => 'order', - 'api_platform.collection.pagination.client_enabled' => false, - 'api_platform.collection.pagination.client_items_per_page' => false, - 'api_platform.collection.pagination.enabled' => true, - 'api_platform.collection.pagination.enabled_parameter_name' => 'pagination', - 'api_platform.collection.pagination.items_per_page' => 30, - 'api_platform.collection.pagination.items_per_page_parameter_name' => 'itemsPerPage', - 'api_platform.collection.pagination.maximum_items_per_page' => null, - 'api_platform.collection.pagination.page_parameter_name' => 'page', - 'api_platform.collection.pagination.partial' => false, - 'api_platform.collection.pagination.client_partial' => false, - 'api_platform.collection.pagination.partial_parameter_name' => 'partial', 'api_platform.description' => 'description', 'api_platform.error_formats' => ['jsonproblem' => ['application/problem+json'], 'jsonld' => ['application/ld+json']], 'api_platform.formats' => ['jsonld' => ['application/ld+json'], 'jsonhal' => ['application/hal+json']], @@ -472,6 +453,24 @@ private function getPartialContainerBuilderProphecy($test = false) 'api_platform.enable_docs' => true, ]; + $pagination = [ + 'client_enabled' => false, + 'client_items_per_page' => false, + 'enabled' => true, + 'enabled_parameter_name' => 'pagination', + 'items_per_page' => 30, + 'items_per_page_parameter_name' => 'itemsPerPage', + 'maximum_items_per_page' => null, + 'page_parameter_name' => 'page', + 'partial' => false, + 'client_partial' => false, + 'partial_parameter_name' => 'partial', + ]; + foreach ($pagination as $key => $value) { + $parameters["api_platform.collection.pagination.{$key}"] = $value; + } + $parameters['api_platform.collection.pagination'] = $pagination; + foreach ($parameters as $key => $value) { $containerBuilderProphecy->setParameter($key, $value)->shouldBeCalled(); } @@ -547,6 +546,7 @@ private function getPartialContainerBuilderProphecy($test = false) 'api_platform.operation_path_resolver.router', 'api_platform.operation_path_resolver.generator', 'api_platform.operation_path_resolver.underscore', + 'api_platform.pagination', 'api_platform.path_segment_name_generator.underscore', 'api_platform.path_segment_name_generator.dash', 'api_platform.resource_class_resolver', @@ -617,6 +617,15 @@ private function getPartialContainerBuilderProphecy($test = false) private function getBaseContainerBuilderProphecy() { $containerBuilderProphecy = $this->getPartialContainerBuilderProphecy(); + $childDefinitionProphecy = $this->prophesize(ChildDefinition::class); + + $containerBuilderProphecy->registerForAutoconfiguration(QueryItemExtensionInterface::class) + ->willReturn($childDefinitionProphecy)->shouldBeCalledTimes(1); + $childDefinitionProphecy->addTag('api_platform.doctrine.orm.query_extension.item')->shouldBeCalledTimes(1); + + $containerBuilderProphecy->registerForAutoconfiguration(QueryCollectionExtensionInterface::class) + ->willReturn($childDefinitionProphecy)->shouldBeCalledTimes(1); + $childDefinitionProphecy->addTag('api_platform.doctrine.orm.query_extension.collection')->shouldBeCalledTimes(1); $containerBuilderProphecy->addResource(Argument::type(DirectoryResource::class))->shouldBeCalled(); diff --git a/tests/Bridge/Symfony/Bundle/DependencyInjection/ConfigurationTest.php b/tests/Bridge/Symfony/Bundle/DependencyInjection/ConfigurationTest.php index c309aa91124..89505a2187c 100644 --- a/tests/Bridge/Symfony/Bundle/DependencyInjection/ConfigurationTest.php +++ b/tests/Bridge/Symfony/Bundle/DependencyInjection/ConfigurationTest.php @@ -91,6 +91,10 @@ public function testDefaultConfig() 'enabled' => true, ], ], + 'elasticsearch' => [ + 'enabled' => false, + 'mapping' => [], + ], 'oauth' => [ 'enabled' => false, 'clientId' => '',