Skip to content

29123 not getting correct label value of yes or no type attribute in aggregations data of products graphql response #31876

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: 2.4-develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,9 @@ class AttributeOptionProvider
/**
* @param ResourceConnection $resourceConnection
*/
public function __construct(ResourceConnection $resourceConnection)
{
public function __construct(
ResourceConnection $resourceConnection
) {
$this->resourceConnection = $resourceConnection;
}

Expand Down Expand Up @@ -62,6 +63,7 @@ public function getOptions(array $optionIds, ?int $storeId, array $attributeCode
'attribute_id' => 'a.attribute_id',
'attribute_code' => 'a.attribute_code',
'attribute_label' => 'a.frontend_label',
'frontend_input' => 'a.frontend_input',
]
)
->joinLeft(
Expand Down Expand Up @@ -126,8 +128,8 @@ private function formatResult(\Magento\Framework\DB\Select $select): array
$result[$option['attribute_code']] = [
'attribute_id' => $option['attribute_id'],
'attribute_code' => $option['attribute_code'],
'attribute_label' => $option['attribute_store_label']
? $option['attribute_store_label'] : $option['attribute_label'],
'attribute_label' => $option['attribute_store_label'] ?: $option['attribute_label'],
'frontend_input' => $option['frontend_input'],
'options' => [],
];
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,12 @@
namespace Magento\CatalogGraphQl\DataProvider\Product\LayeredNavigation\Builder;

use Magento\CatalogGraphQl\DataProvider\Product\LayeredNavigation\AttributeOptionProvider;
use Magento\CatalogGraphQl\DataProvider\Product\LayeredNavigation\Formatter\LayerFormatter;
use Magento\CatalogGraphQl\DataProvider\Product\LayeredNavigation\LayerBuilderInterface;
use Magento\Config\Model\Config\Source\Yesno;
use Magento\Framework\Api\Search\AggregationInterface;
use Magento\Framework\Api\Search\AggregationValueInterface;
use Magento\Framework\Api\Search\BucketInterface;
use Magento\CatalogGraphQl\DataProvider\Product\LayeredNavigation\Formatter\LayerFormatter;

/**
* @inheritdoc
Expand Down Expand Up @@ -49,19 +50,27 @@ class Attribute implements LayerBuilderInterface
self::CATEGORY_BUCKET
];

/**
* @var Yesno
*/
private $yesNo;

/**
* @param AttributeOptionProvider $attributeOptionProvider
* @param LayerFormatter $layerFormatter
* @param Yesno $yesNo
* @param array $bucketNameFilter
*/
public function __construct(
AttributeOptionProvider $attributeOptionProvider,
LayerFormatter $layerFormatter,
Yesno $yesNo,
$bucketNameFilter = []
) {
$this->attributeOptionProvider = $attributeOptionProvider;
$this->layerFormatter = $layerFormatter;
$this->bucketNameFilter = \array_merge($this->bucketNameFilter, $bucketNameFilter);
$this->yesNo = $yesNo;
}

/**
Expand Down Expand Up @@ -89,7 +98,7 @@ public function build(AggregationInterface $aggregation, ?int $storeId): array
foreach ($bucket->getValues() as $value) {
$metrics = $value->getMetrics();
$result[$bucketName]['options'][] = $this->layerFormatter->buildItem(
$attribute['options'][$metrics['value']] ?? $metrics['value'],
$this->getOptionLabel($attribute, $metrics),
$metrics['value'],
$metrics['count']
);
Expand All @@ -99,6 +108,23 @@ public function build(AggregationInterface $aggregation, ?int $storeId): array
return $result;
}

/**
* Get option label
*
* @param array $attribute
* @param array $metrics
* @return mixed
*/
private function getOptionLabel(array $attribute, array $metrics)
{
if ($attribute['frontend_input'] === 'boolean') {
$yesNoOptions = $this->yesNo->toArray();
return $yesNoOptions[$metrics['value']];
}

return $attribute['options'][$metrics['value']] ?? $metrics['value'];
}

/**
* Get attribute buckets excluding specified bucket names
*
Expand Down
14 changes: 3 additions & 11 deletions app/code/Magento/CatalogGraphQl/Model/Resolver/Aggregations.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,6 @@
*/
class Aggregations implements ResolverInterface
{
/**
* @var Layer\DataProvider\Filters
*/
private $filtersDataProvider;

/**
* @var LayerBuilder
*/
Expand All @@ -36,16 +31,13 @@ class Aggregations implements ResolverInterface
private $priceCurrency;

/**
* @param \Magento\CatalogGraphQl\Model\Resolver\Layer\DataProvider\Filters $filtersDataProvider
* @param LayerBuilder $layerBuilder
* @param PriceCurrency $priceCurrency
*/
public function __construct(
\Magento\CatalogGraphQl\Model\Resolver\Layer\DataProvider\Filters $filtersDataProvider,
LayerBuilder $layerBuilder,
PriceCurrency $priceCurrency = null
) {
$this->filtersDataProvider = $filtersDataProvider;
$this->layerBuilder = $layerBuilder;
$this->priceCurrency = $priceCurrency ?: ObjectManager::getInstance()->get(PriceCurrency::class);
}
Expand All @@ -60,7 +52,7 @@ public function resolve(
array $value = null,
array $args = null
) {
if (!isset($value['layer_type']) || !isset($value['search_result'])) {
if (!isset($value['layer_type'], $value['search_result'])) {
return null;
}

Expand All @@ -82,8 +74,8 @@ public function resolve(
}
}
return $results;
} else {
return [];
}

return [];
}
}
3 changes: 2 additions & 1 deletion app/code/Magento/CatalogGraphQl/composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@
"magento/module-eav-graph-ql": "*",
"magento/module-catalog-search": "*",
"magento/framework": "*",
"magento/module-graph-ql": "*"
"magento/module-graph-ql": "*",
"magento/module-config": "*"
},
"suggest": {
"magento/module-graph-ql-cache": "*",
Expand Down
1 change: 1 addition & 0 deletions app/code/Magento/CatalogGraphQl/etc/module.xml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
<module name="Magento_GraphQl"/>
<module name="Magento_StoreGraphQl"/>
<module name="Magento_EavGraphQl"/>
<module name="Magento_Config"/>
</sequence>
</module>
</config>
Original file line number Diff line number Diff line change
Expand Up @@ -14,108 +14,115 @@ class ProductSearchAggregationsTest extends GraphQlAbstract
/**
* @magentoApiDataFixture Magento/Catalog/_files/products_with_boolean_attribute.php
*/
public function testAggregationBooleanAttribute()
public function testAggregationBooleanAttribute(): void
{
$this->markTestSkipped('MC-22184: Elasticsearch returns incorrect aggregation options for booleans');

$query = $this->getGraphQlQuery(
'"search_product_1", "search_product_2", "search_product_3", "search_product_4" ,"search_product_5"'
);

$result = $this->graphQlQuery($query);

$this->assertArrayNotHasKey('errors', $result);
$this->assertArrayHasKey('items', $result['products']);
$this->assertCount(5, $result['products']['items']);
$this->assertArrayHasKey('aggregations', $result['products']);
self::assertArrayNotHasKey('errors', $result);
self::assertArrayHasKey('items', $result['products']);
self::assertCount(5, $result['products']['items']);
self::assertArrayHasKey('aggregations', $result['products']);

$booleanAggregation = array_filter(
$result['products']['aggregations'],
function ($a) {
return $a['attribute_code'] == 'boolean_attribute';
return $a['attribute_code'] === 'boolean_attribute';
}
);
$this->assertNotEmpty($booleanAggregation);
self::assertNotEmpty($booleanAggregation);
$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']);
self::assertEquals('Boolean Attribute', $booleanAggregation['label']);
self::assertEquals('boolean_attribute', $booleanAggregation['attribute_code']);
self::assertContainsEquals(['label' => 'Yes', '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']);
self::assertEquals(2, $booleanAggregation['count']);
self::assertCount(2, $booleanAggregation['options']);
self::assertContainsEquals(['label' => 'No', 'value'=> '0', 'count' => '2'], $booleanAggregation['options']);
}

/**
* @magentoApiDataFixture Magento/Catalog/_files/products_for_search.php
*/
public function testAggregationPriceRanges()
public function testAggregationPriceRanges(): void
{
$query = $this->getGraphQlQuery(
'"search_product_1", "search_product_2", "search_product_3", "search_product_4" ,"search_product_5"'
);
$result = $this->graphQlQuery($query);

$this->assertArrayNotHasKey('errors', $result);
$this->assertArrayHasKey('aggregations', $result['products']);
self::assertArrayNotHasKey('errors', $result);
self::assertArrayHasKey('aggregations', $result['products']);

$priceAggregation = array_filter(
$result['products']['aggregations'],
function ($a) {
return $a['attribute_code'] == 'price';
return $a['attribute_code'] === 'price';
}
);
$this->assertNotEmpty($priceAggregation);
self::assertNotEmpty($priceAggregation);
$priceAggregation = reset($priceAggregation);
$this->assertEquals('Price', $priceAggregation['label']);
$this->assertEquals(4, $priceAggregation['count']);
self::assertEquals('Price', $priceAggregation['label']);
self::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']
];
$this->assertEquals($expectedOptions, $priceAggregation['options']);
self::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
*/
public function testAggregationPriceRangesWithCurrencyHeader()
public function testAggregationPriceRangesWithCurrencyHeader(): void
{
$headerMap['Content-Currency'] = 'CNY';
$query = $this->getGraphQlQuery(
'"search_product_1", "search_product_2", "search_product_3", "search_product_4" ,"search_product_5"'
);
$result = $this->graphQlQuery($query, [], '', $headerMap);
$this->assertArrayNotHasKey('errors', $result);
$this->assertArrayHasKey('aggregations', $result['products']);
self::assertArrayNotHasKey('errors', $result);
self::assertArrayHasKey('aggregations', $result['products']);
$priceAggregation = array_filter(
$result['products']['aggregations'],
function ($a) {
return $a['attribute_code'] == 'price';
return $a['attribute_code'] === 'price';
}
);
$this->assertNotEmpty($priceAggregation);
self::assertNotEmpty($priceAggregation);
$priceAggregation = reset($priceAggregation);
$this->assertEquals('Price', $priceAggregation['label']);
$this->assertEquals(4, $priceAggregation['count']);
self::assertEquals('Price', $priceAggregation['label']);
self::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']
];
$this->assertEquals($expectedOptions, $priceAggregation['options']);
self::assertEquals($expectedOptions, $priceAggregation['options']);
}

private function getGraphQlQuery(string $skus)
/**
* Get query
*
* @param string $skus
* @return string
*/
private function getGraphQlQuery(string $skus): string
{
return <<<QUERY
{
products(filter: {sku: {in: [{$skus}]}}){
items{
sku
}
aggregations{
label
attribute_code
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@
*/

use Magento\Catalog\Api\ProductRepositoryInterface;
use Magento\Indexer\Model\Indexer;
use Magento\Indexer\Model\Indexer\Collection;
use Magento\TestFramework\Helper\Bootstrap;
use Magento\TestFramework\Helper\CacheCleaner;
use Magento\TestFramework\Workaround\Override\Fixture\Resolver;

Resolver::getInstance()->requireDataFixture('Magento/Catalog/_files/products_for_search.php');
Expand All @@ -28,11 +29,11 @@
$product->setBooleanAttribute(0);
$productRepository->save($product);
}
CacheCleaner::cleanAll();
/** @var \Magento\Indexer\Model\Indexer\Collection $indexerCollection */
$indexerCollection = $objectManager->get(\Magento\Indexer\Model\Indexer\Collection::class);

/** @var Collection $indexerCollection */
$indexerCollection = $objectManager->get(Collection::class);
$indexerCollection->load();
/** @var \Magento\Indexer\Model\Indexer $indexer */
/** @var Indexer $indexer */
foreach ($indexerCollection->getItems() as $indexer) {
$indexer->reindexAll();
}