Skip to content

Commit 510e061

Browse files
ENGCOM-2966: Improve graphql product pagination #175
- Merge Pull Request magento/graphql-ce#175 from Spaggel/graphql-ce:improve-graphql-product-pagination - Merged commits: 1. 651ee47 2. 5f05572 3. 4edafcf 4. d0231e8 5. 096e37e 6. 2e3d4b0 7. 9ad5a2c 8. 541098b 9. 2296d84
2 parents 8460e4e + 2296d84 commit 510e061

File tree

3 files changed

+32
-116
lines changed

3 files changed

+32
-116
lines changed

app/code/Magento/CatalogGraphQl/Model/Resolver/Products.php

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
namespace Magento\CatalogGraphQl\Model\Resolver;
99

10+
use Magento\CatalogGraphQl\Model\Resolver\Layer\DataProvider\Filters;
1011
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
1112
use Magento\CatalogGraphQl\Model\Resolver\Products\Query\Filter;
1213
use Magento\CatalogGraphQl\Model\Resolver\Products\Query\Search;
@@ -51,13 +52,15 @@ class Products implements ResolverInterface
5152
* @param Builder $searchCriteriaBuilder
5253
* @param Search $searchQuery
5354
* @param Filter $filterQuery
55+
* @param SearchFilter $searchFilter
56+
* @param Filters $filtersDataProvider
5457
*/
5558
public function __construct(
5659
Builder $searchCriteriaBuilder,
5760
Search $searchQuery,
5861
Filter $filterQuery,
5962
SearchFilter $searchFilter,
60-
\Magento\CatalogGraphQl\Model\Resolver\Layer\DataProvider\Filters $filtersDataProvider
63+
Filters $filtersDataProvider
6164
) {
6265
$this->searchCriteriaBuilder = $searchCriteriaBuilder;
6366
$this->searchQuery = $searchQuery;
@@ -100,10 +103,10 @@ public function resolve(
100103

101104
$currentPage = $searchCriteria->getCurrentPage();
102105
if ($searchCriteria->getCurrentPage() > $maxPages && $searchResult->getTotalCount() > 0) {
103-
$currentPage = new GraphQlInputException(
106+
throw new GraphQlInputException(
104107
__(
105-
'currentPage value %1 specified is greater than the number of pages available.',
106-
[$maxPages]
108+
'currentPage value %1 specified is greater than the %2 page(s) available.',
109+
[$currentPage, $maxPages]
107110
)
108111
);
109112
}
@@ -113,7 +116,8 @@ public function resolve(
113116
'items' => $searchResult->getProductsSearchResult(),
114117
'page_info' => [
115118
'page_size' => $searchCriteria->getPageSize(),
116-
'current_page' => $currentPage
119+
'current_page' => $currentPage,
120+
'total_pages' => $maxPages
117121
],
118122
'filters' => $this->filtersDataProvider->getData($layerType)
119123
];

app/code/Magento/GraphQl/etc/schema.graphqls

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ input FilterTypeInput @doc(description: "FilterTypeInput specifies which action
2929
type SearchResultPageInfo @doc(description: "SearchResultPageInfo provides navigation for the query response") {
3030
page_size: Int @doc(description: "Specifies the maximum number of items to return")
3131
current_page: Int @doc(description: "Specifies which page of results to return")
32+
total_pages: Int @doc(description: "Total pages")
3233
}
3334

3435
enum SortEnum @doc(description: "This enumeration indicates whether to return results in ascending or descending order") {

dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductSearchTest.php

Lines changed: 22 additions & 111 deletions
Original file line numberDiff line numberDiff line change
@@ -381,84 +381,11 @@ public function testSearchWithFilterWithPageSizeEqualTotalCount()
381381
}
382382
QUERY;
383383
$this->expectException(\Exception::class);
384-
$this->expectExceptionMessage('GraphQL response contains errors: currentPage value 1 specified is greater ' .
385-
'than the number of pages available.');
384+
$this->expectExceptionMessage('GraphQL response contains errors: currentPage value 2 specified is greater ' .
385+
'than the 1 page(s) available');
386386
$this->graphQlQuery($query);
387387
}
388388

389-
/**
390-
* The query returns a total_count of 2 records; setting the pageSize = 1 and currentPage2
391-
* Expected result is to get the second product on the list on the second page
392-
*
393-
* @magentoApiDataFixture Magento/Catalog/_files/multiple_products.php
394-
*/
395-
public function testSearchWithFilterPageSizeLessThanCurrentPage()
396-
{
397-
398-
$query
399-
= <<<QUERY
400-
{
401-
products(
402-
search : "simple"
403-
filter:
404-
{
405-
special_price:{neq:"null"}
406-
price:{lt:"60"}
407-
or:
408-
{
409-
sku:{like:"%simple%"}
410-
name:{like:"%configurable%"}
411-
}
412-
weight:{eq:"1"}
413-
}
414-
pageSize:1
415-
currentPage:2
416-
sort:
417-
{
418-
price:DESC
419-
}
420-
)
421-
{
422-
items
423-
{
424-
sku
425-
price {
426-
minimalPrice {
427-
amount {
428-
value
429-
currency
430-
}
431-
}
432-
}
433-
name
434-
... on PhysicalProductInterface {
435-
weight
436-
}
437-
type_id
438-
attribute_set_id
439-
}
440-
total_count
441-
page_info
442-
{
443-
page_size
444-
}
445-
}
446-
}
447-
QUERY;
448-
/**
449-
* @var ProductRepositoryInterface $productRepository
450-
*/
451-
$productRepository = ObjectManager::getInstance()->get(ProductRepositoryInterface::class);
452-
// when pagSize =1 and currentPage = 2, it should have simple2 on first page and simple1 on 2nd page
453-
// since sorting is done on price in the DESC order
454-
$product = $productRepository->get('simple1');
455-
$filteredProducts = [$product];
456-
457-
$response = $this->graphQlQuery($query);
458-
$this->assertEquals(1, $response['products']['total_count']);
459-
$this->assertProductItems($filteredProducts, $response);
460-
}
461-
462389
/**
463390
* Requesting for items that match a specific SKU or NAME within a certain price range sorted by Price in ASC order
464391
*
@@ -549,71 +476,55 @@ public function testQueryProductsInCurrentPageSortedByPriceASC()
549476
}
550477

551478
/**
552-
* Verify the items in the second page is correct after sorting their name in ASC order
479+
* Verify the items is correct after sorting their name in ASC order
553480
*
554481
* @magentoApiDataFixture Magento/Catalog/_files/multiple_mixed_products_2.php
555-
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
556482
*/
557-
public function testFilterProductsInNextPageSortedByNameASC()
483+
public function testQueryProductsSortedByNameASC()
558484
{
559485
$query
560486
= <<<QUERY
561487
{
562488
products(
563489
filter:
564490
{
565-
price:{gt: "5", lt: "50"}
566-
or:
567-
{
568-
sku:{eq:"simple1"}
569-
name:{like:"configurable%"}
570-
}
491+
sku:{in:["simple2", "simple1"]}
571492
}
572-
pageSize:4
493+
pageSize:1
573494
currentPage:2
574495
sort:
575496
{
576-
name:ASC
497+
name:ASC
577498
}
578499
)
579500
{
580501
items
581502
{
582503
sku
583-
price {
584-
minimalPrice {
585-
amount {
586-
value
587-
currency
588-
}
589-
}
590-
}
591504
name
592-
type_id
593-
... on PhysicalProductInterface {
594-
weight
595-
}
596-
attribute_set_id
597-
}
598-
total_count
599-
page_info
600-
{
505+
}
506+
total_count
507+
page_info
508+
{
601509
page_size
602-
}
510+
current_page
511+
}
603512
}
604513
}
605514
QUERY;
606515
/**
607516
* @var ProductRepositoryInterface $productRepository
608517
*/
609518
$productRepository = ObjectManager::getInstance()->get(ProductRepositoryInterface::class);
610-
$product = $productRepository->get('simple1');
611-
$filteredProducts = [$product];
519+
$product = $productRepository->get('simple2');
612520

613521
$response = $this->graphQlQuery($query);
614-
$this->assertEquals(1, $response['products']['total_count']);
615-
$this->assertProductItems($filteredProducts, $response);
616-
$this->assertEquals(4, $response['products']['page_info']['page_size']);
522+
$this->assertEquals(2, $response['products']['total_count']);
523+
$this->assertEquals(['page_size' => 1, 'current_page' => 2], $response['products']['page_info']);
524+
$this->assertEquals(
525+
[['sku' => $product->getSku(), 'name' => $product->getName()]],
526+
$response['products']['items']
527+
);
617528
}
618529

619530
/**
@@ -1132,8 +1043,8 @@ public function testQueryPageOutOfBoundException()
11321043
QUERY;
11331044

11341045
$this->expectException(\Exception::class);
1135-
$this->expectExceptionMessage('GraphQL response contains errors: currentPage value 1 specified is greater ' .
1136-
'than the number of pages available.');
1046+
$this->expectExceptionMessage('GraphQL response contains errors: currentPage value 2 specified is greater ' .
1047+
'than the 1 page(s) available.');
11371048
$this->graphQlQuery($query);
11381049
}
11391050

0 commit comments

Comments
 (0)