Skip to content

Commit

Permalink
LYNX-17: [GraphQL] Products query returns aggregations for products n…
Browse files Browse the repository at this point in the history
…ot assigned to a shared catalog (#79)
  • Loading branch information
bl4de authored Jan 4, 2023
1 parent 3e5be99 commit 24f0719
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 44 deletions.
67 changes: 37 additions & 30 deletions app/code/Magento/CatalogGraphQl/Model/Resolver/Aggregations.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,6 @@
*/
class Aggregations implements ResolverInterface
{
/**
* @var Layer\DataProvider\Filters
*/
private $filtersDataProvider;

/**
* @var LayerBuilder
*/
Expand All @@ -42,18 +37,15 @@ class Aggregations implements ResolverInterface
private $includeDirectChildrenOnly;

/**
* @param \Magento\CatalogGraphQl\Model\Resolver\Layer\DataProvider\Filters $filtersDataProvider
* @param LayerBuilder $layerBuilder
* @param PriceCurrency $priceCurrency
* @param Category\IncludeDirectChildrenOnly $includeDirectChildrenOnly
*/
public function __construct(
\Magento\CatalogGraphQl\Model\Resolver\Layer\DataProvider\Filters $filtersDataProvider,
LayerBuilder $layerBuilder,
PriceCurrency $priceCurrency = null,
Category\IncludeDirectChildrenOnly $includeDirectChildrenOnly = null
) {
$this->filtersDataProvider = $filtersDataProvider;
$this->layerBuilder = $layerBuilder;
$this->priceCurrency = $priceCurrency ?: ObjectManager::getInstance()->get(PriceCurrency::class);
$this->includeDirectChildrenOnly = $includeDirectChildrenOnly
Expand All @@ -75,30 +67,45 @@ public function resolve(
}

$aggregations = $value['search_result']->getSearchAggregation();
if (!$aggregations || (int)$value['total_count'] == 0) {
return [];
}

if ($aggregations) {
$categoryFilter = $value['categories'] ?? [];
$includeDirectChildrenOnly = $args['filter']['category']['includeDirectChildrenOnly'] ?? false;
if ($includeDirectChildrenOnly && !empty($categoryFilter)) {
$this->includeDirectChildrenOnly->setFilter(['category' => $categoryFilter]);
}
/** @var StoreInterface $store */
$store = $context->getExtensionAttributes()->getStore();
$storeId = (int)$store->getId();
$results = $this->layerBuilder->build($aggregations, $storeId);
if (isset($results['price_bucket'])) {
foreach ($results['price_bucket']['options'] as &$value) {
list($from, $to) = explode('-', $value['label']);
$newLabel = $this->priceCurrency->convertAndRound($from)
. '-'
. $this->priceCurrency->convertAndRound($to);
$value['label'] = $newLabel;
$value['value'] = str_replace('-', '_', $newLabel);
}
}
$categoryFilter = $value['categories'] ?? [];
$includeDirectChildrenOnly = $args['filter']['category']['includeDirectChildrenOnly'] ?? false;
if ($includeDirectChildrenOnly && !empty($categoryFilter)) {
$this->includeDirectChildrenOnly->setFilter(['category' => $categoryFilter]);
}

$results = $this->layerBuilder->build(
$aggregations,
(int)$context->getExtensionAttributes()->getStore()->getId()
);
if (!isset($results['price_bucket']['options'])) {
return $results;
} else {
return [];
}

$priceBucketOptions = [];
foreach ($results['price_bucket']['options'] as $optionValue) {
$priceBucketOptions[] = $this->getConvertedAndRoundedOptionValue($optionValue);
}
$results['price_bucket']['options'] = $priceBucketOptions;

return $results;
}

/**
* Converts and rounds option value
*
* @param String[] $optionValue
* @return String[]
*/
private function getConvertedAndRoundedOptionValue(array $optionValue): array
{
list($from, $to) = explode('-', $optionValue['label']);
$newLabel = $this->priceCurrency->convertAndRound($from) . '-' . $this->priceCurrency->convertAndRound($to);
$optionValue['label'] = $newLabel;
$optionValue['value'] = str_replace('-', '_', $newLabel);
return $optionValue;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,11 @@ function ($a) {
$booleanAggregation = reset($booleanAggregation);
$this->assertEquals('Boolean Attribute', $booleanAggregation['label']);
$this->assertEquals('boolean_attribute', $booleanAggregation['attribute_code']);
$this->assertContainsEquals(['label' => '1', 'value'=> '1', 'count' => '3'], $booleanAggregation['options']);
$this->assertContainsEquals(['label' => '1', 'value' => '1', 'count' => '3'], $booleanAggregation['options']);

$this->assertEquals(2, $booleanAggregation['count']);
$this->assertCount(2, $booleanAggregation['options']);
$this->assertContainsEquals(['label' => '0', 'value'=> '0', 'count' => '2'], $booleanAggregation['options']);
$this->assertContainsEquals(['label' => '0', 'value' => '0', 'count' => '2'], $booleanAggregation['options']);
}

/**
Expand All @@ -68,18 +68,18 @@ function ($a) {
$this->assertEquals('Price', $priceAggregation['label']);
$this->assertEquals(4, $priceAggregation['count']);
$expectedOptions = [
['label' => '10-20', 'value'=> '10_20', 'count' => '2'],
['label' => '20-30', 'value'=> '20_30', 'count' => '1'],
['label' => '30-40', 'value'=> '30_40', 'count' => '1'],
['label' => '40-50', 'value'=> '40_50', 'count' => '1']
['label' => '10-20', 'value' => '10_20', 'count' => '2'],
['label' => '20-30', 'value' => '20_30', 'count' => '1'],
['label' => '30-40', 'value' => '30_40', 'count' => '1'],
['label' => '40-50', 'value' => '40_50', 'count' => '1']
];
$this->assertEquals($expectedOptions, $priceAggregation['options']);
}

/**
* @magentoApiDataFixture Magento/Catalog/_files/products_for_search.php
* @magentoApiDataFixture Magento/Directory/_files/usd_cny_rate.php
* @magentoConfigFixture default_store currency/options/allow CNY,USD
* @magentoConfigFixture default_store currency/options/allow CNY,USD,EUR
*/
public function testAggregationPriceRangesWithCurrencyHeader()
{
Expand All @@ -101,14 +101,30 @@ function ($a) {
$this->assertEquals('Price', $priceAggregation['label']);
$this->assertEquals(4, $priceAggregation['count']);
$expectedOptions = [
['label' => '70-140', 'value'=> '70_140', 'count' => '2'],
['label' => '140-210', 'value'=> '140_210', 'count' => '1'],
['label' => '210-280', 'value'=> '210_280', 'count' => '1'],
['label' => '280-350', 'value'=> '280_350', 'count' => '1']
['label' => '70-140', 'value' => '70_140', 'count' => '2'],
['label' => '140-210', 'value' => '140_210', 'count' => '1'],
['label' => '210-280', 'value' => '210_280', 'count' => '1'],
['label' => '280-350', 'value' => '280_350', 'count' => '1']
];
$this->assertEquals($expectedOptions, $priceAggregation['options']);
}

/**
* @magentoApiDataFixture Magento/Catalog/_files/products_for_search.php
* @magentoConfigFixture default_store currency/options/allow USD,EUR
*/
public function testEmptyAggregationsForNotFoundProducts()
{
$headerMap['Content-Currency'] = 'USD';
$query = $this->getGraphQlQuery(
'"search_product_9999", "search_product_8888"'
);
$result = $this->graphQlQuery($query, [], '', $headerMap);
$this->assertArrayNotHasKey('errors', $result);
$this->assertArrayHasKey('aggregations', $result['products']);
$this->assertEmpty($result['products']['aggregations']);
}

/**
* @magentoApiDataFixture Magento/Catalog/_files/products_for_search_with_custom_price_attribute.php
*/
Expand All @@ -132,8 +148,8 @@ function ($a) {
$priceAggregation = reset($priceAggregation);
$this->assertEquals(2, $priceAggregation['count']);
$expectedOptions = [
['label' => '0_1000', 'value'=> '0_1000', 'count' => '3'],
['label' => '1000_2000', 'value'=> '1000_2000', 'count' => '2']
['label' => '0_1000', 'value' => '0_1000', 'count' => '3'],
['label' => '1000_2000', 'value' => '1000_2000', 'count' => '2']
];
$this->assertEquals($expectedOptions, $priceAggregation['options']);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@

$objectManager = Bootstrap::getObjectManager();

$rates = ['USD' => ['CNY' => '7.0000']];
$rates = [
'USD' => ['CNY' => '7.0000'],
'EUR' => ['CNY' => '7.0000']
];
/** @var Currency $currencyModel */
$currencyModel = $objectManager->create(Currency::class);
$currencyModel->saveRates($rates);

0 comments on commit 24f0719

Please sign in to comment.