Skip to content

Commit 24f0719

Browse files
authored
LYNX-17: [GraphQL] Products query returns aggregations for products not assigned to a shared catalog (#79)
1 parent 3e5be99 commit 24f0719

File tree

3 files changed

+70
-44
lines changed

3 files changed

+70
-44
lines changed

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

Lines changed: 37 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,6 @@
2121
*/
2222
class Aggregations implements ResolverInterface
2323
{
24-
/**
25-
* @var Layer\DataProvider\Filters
26-
*/
27-
private $filtersDataProvider;
28-
2924
/**
3025
* @var LayerBuilder
3126
*/
@@ -42,18 +37,15 @@ class Aggregations implements ResolverInterface
4237
private $includeDirectChildrenOnly;
4338

4439
/**
45-
* @param \Magento\CatalogGraphQl\Model\Resolver\Layer\DataProvider\Filters $filtersDataProvider
4640
* @param LayerBuilder $layerBuilder
4741
* @param PriceCurrency $priceCurrency
4842
* @param Category\IncludeDirectChildrenOnly $includeDirectChildrenOnly
4943
*/
5044
public function __construct(
51-
\Magento\CatalogGraphQl\Model\Resolver\Layer\DataProvider\Filters $filtersDataProvider,
5245
LayerBuilder $layerBuilder,
5346
PriceCurrency $priceCurrency = null,
5447
Category\IncludeDirectChildrenOnly $includeDirectChildrenOnly = null
5548
) {
56-
$this->filtersDataProvider = $filtersDataProvider;
5749
$this->layerBuilder = $layerBuilder;
5850
$this->priceCurrency = $priceCurrency ?: ObjectManager::getInstance()->get(PriceCurrency::class);
5951
$this->includeDirectChildrenOnly = $includeDirectChildrenOnly
@@ -75,30 +67,45 @@ public function resolve(
7567
}
7668

7769
$aggregations = $value['search_result']->getSearchAggregation();
70+
if (!$aggregations || (int)$value['total_count'] == 0) {
71+
return [];
72+
}
7873

79-
if ($aggregations) {
80-
$categoryFilter = $value['categories'] ?? [];
81-
$includeDirectChildrenOnly = $args['filter']['category']['includeDirectChildrenOnly'] ?? false;
82-
if ($includeDirectChildrenOnly && !empty($categoryFilter)) {
83-
$this->includeDirectChildrenOnly->setFilter(['category' => $categoryFilter]);
84-
}
85-
/** @var StoreInterface $store */
86-
$store = $context->getExtensionAttributes()->getStore();
87-
$storeId = (int)$store->getId();
88-
$results = $this->layerBuilder->build($aggregations, $storeId);
89-
if (isset($results['price_bucket'])) {
90-
foreach ($results['price_bucket']['options'] as &$value) {
91-
list($from, $to) = explode('-', $value['label']);
92-
$newLabel = $this->priceCurrency->convertAndRound($from)
93-
. '-'
94-
. $this->priceCurrency->convertAndRound($to);
95-
$value['label'] = $newLabel;
96-
$value['value'] = str_replace('-', '_', $newLabel);
97-
}
98-
}
74+
$categoryFilter = $value['categories'] ?? [];
75+
$includeDirectChildrenOnly = $args['filter']['category']['includeDirectChildrenOnly'] ?? false;
76+
if ($includeDirectChildrenOnly && !empty($categoryFilter)) {
77+
$this->includeDirectChildrenOnly->setFilter(['category' => $categoryFilter]);
78+
}
79+
80+
$results = $this->layerBuilder->build(
81+
$aggregations,
82+
(int)$context->getExtensionAttributes()->getStore()->getId()
83+
);
84+
if (!isset($results['price_bucket']['options'])) {
9985
return $results;
100-
} else {
101-
return [];
10286
}
87+
88+
$priceBucketOptions = [];
89+
foreach ($results['price_bucket']['options'] as $optionValue) {
90+
$priceBucketOptions[] = $this->getConvertedAndRoundedOptionValue($optionValue);
91+
}
92+
$results['price_bucket']['options'] = $priceBucketOptions;
93+
94+
return $results;
95+
}
96+
97+
/**
98+
* Converts and rounds option value
99+
*
100+
* @param String[] $optionValue
101+
* @return String[]
102+
*/
103+
private function getConvertedAndRoundedOptionValue(array $optionValue): array
104+
{
105+
list($from, $to) = explode('-', $optionValue['label']);
106+
$newLabel = $this->priceCurrency->convertAndRound($from) . '-' . $this->priceCurrency->convertAndRound($to);
107+
$optionValue['label'] = $newLabel;
108+
$optionValue['value'] = str_replace('-', '_', $newLabel);
109+
return $optionValue;
103110
}
104111
}

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

Lines changed: 29 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,11 @@ function ($a) {
3737
$booleanAggregation = reset($booleanAggregation);
3838
$this->assertEquals('Boolean Attribute', $booleanAggregation['label']);
3939
$this->assertEquals('boolean_attribute', $booleanAggregation['attribute_code']);
40-
$this->assertContainsEquals(['label' => '1', 'value'=> '1', 'count' => '3'], $booleanAggregation['options']);
40+
$this->assertContainsEquals(['label' => '1', 'value' => '1', 'count' => '3'], $booleanAggregation['options']);
4141

4242
$this->assertEquals(2, $booleanAggregation['count']);
4343
$this->assertCount(2, $booleanAggregation['options']);
44-
$this->assertContainsEquals(['label' => '0', 'value'=> '0', 'count' => '2'], $booleanAggregation['options']);
44+
$this->assertContainsEquals(['label' => '0', 'value' => '0', 'count' => '2'], $booleanAggregation['options']);
4545
}
4646

4747
/**
@@ -68,18 +68,18 @@ function ($a) {
6868
$this->assertEquals('Price', $priceAggregation['label']);
6969
$this->assertEquals(4, $priceAggregation['count']);
7070
$expectedOptions = [
71-
['label' => '10-20', 'value'=> '10_20', 'count' => '2'],
72-
['label' => '20-30', 'value'=> '20_30', 'count' => '1'],
73-
['label' => '30-40', 'value'=> '30_40', 'count' => '1'],
74-
['label' => '40-50', 'value'=> '40_50', 'count' => '1']
71+
['label' => '10-20', 'value' => '10_20', 'count' => '2'],
72+
['label' => '20-30', 'value' => '20_30', 'count' => '1'],
73+
['label' => '30-40', 'value' => '30_40', 'count' => '1'],
74+
['label' => '40-50', 'value' => '40_50', 'count' => '1']
7575
];
7676
$this->assertEquals($expectedOptions, $priceAggregation['options']);
7777
}
7878

7979
/**
8080
* @magentoApiDataFixture Magento/Catalog/_files/products_for_search.php
8181
* @magentoApiDataFixture Magento/Directory/_files/usd_cny_rate.php
82-
* @magentoConfigFixture default_store currency/options/allow CNY,USD
82+
* @magentoConfigFixture default_store currency/options/allow CNY,USD,EUR
8383
*/
8484
public function testAggregationPriceRangesWithCurrencyHeader()
8585
{
@@ -101,14 +101,30 @@ function ($a) {
101101
$this->assertEquals('Price', $priceAggregation['label']);
102102
$this->assertEquals(4, $priceAggregation['count']);
103103
$expectedOptions = [
104-
['label' => '70-140', 'value'=> '70_140', 'count' => '2'],
105-
['label' => '140-210', 'value'=> '140_210', 'count' => '1'],
106-
['label' => '210-280', 'value'=> '210_280', 'count' => '1'],
107-
['label' => '280-350', 'value'=> '280_350', 'count' => '1']
104+
['label' => '70-140', 'value' => '70_140', 'count' => '2'],
105+
['label' => '140-210', 'value' => '140_210', 'count' => '1'],
106+
['label' => '210-280', 'value' => '210_280', 'count' => '1'],
107+
['label' => '280-350', 'value' => '280_350', 'count' => '1']
108108
];
109109
$this->assertEquals($expectedOptions, $priceAggregation['options']);
110110
}
111111

112+
/**
113+
* @magentoApiDataFixture Magento/Catalog/_files/products_for_search.php
114+
* @magentoConfigFixture default_store currency/options/allow USD,EUR
115+
*/
116+
public function testEmptyAggregationsForNotFoundProducts()
117+
{
118+
$headerMap['Content-Currency'] = 'USD';
119+
$query = $this->getGraphQlQuery(
120+
'"search_product_9999", "search_product_8888"'
121+
);
122+
$result = $this->graphQlQuery($query, [], '', $headerMap);
123+
$this->assertArrayNotHasKey('errors', $result);
124+
$this->assertArrayHasKey('aggregations', $result['products']);
125+
$this->assertEmpty($result['products']['aggregations']);
126+
}
127+
112128
/**
113129
* @magentoApiDataFixture Magento/Catalog/_files/products_for_search_with_custom_price_attribute.php
114130
*/
@@ -132,8 +148,8 @@ function ($a) {
132148
$priceAggregation = reset($priceAggregation);
133149
$this->assertEquals(2, $priceAggregation['count']);
134150
$expectedOptions = [
135-
['label' => '0_1000', 'value'=> '0_1000', 'count' => '3'],
136-
['label' => '1000_2000', 'value'=> '1000_2000', 'count' => '2']
151+
['label' => '0_1000', 'value' => '0_1000', 'count' => '3'],
152+
['label' => '1000_2000', 'value' => '1000_2000', 'count' => '2']
137153
];
138154
$this->assertEquals($expectedOptions, $priceAggregation['options']);
139155
}

dev/tests/integration/testsuite/Magento/Directory/_files/usd_cny_rate.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,10 @@
1010

1111
$objectManager = Bootstrap::getObjectManager();
1212

13-
$rates = ['USD' => ['CNY' => '7.0000']];
13+
$rates = [
14+
'USD' => ['CNY' => '7.0000'],
15+
'EUR' => ['CNY' => '7.0000']
16+
];
1417
/** @var Currency $currencyModel */
1518
$currencyModel = $objectManager->create(Currency::class);
1619
$currencyModel->saveRates($rates);

0 commit comments

Comments
 (0)