Skip to content

Commit 2e4e937

Browse files
committed
MC-36964: Create automated test for "[Elasticsearch] Search by multiple attributes"
1 parent 72f9180 commit 2e4e937

File tree

4 files changed

+263
-8
lines changed

4 files changed

+263
-8
lines changed

dev/tests/integration/testsuite/Magento/LayeredNavigation/Block/Navigation/AbstractFiltersTest.php

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,10 @@ abstract protected function getLayerType(): string;
9191
*
9292
* @return string
9393
*/
94-
abstract protected function getAttributeCode(): string;
94+
protected function getAttributeCode(): string
95+
{
96+
return '';
97+
}
9598

9699
/**
97100
* Tests getFilters method from navigation block on category page.
@@ -108,7 +111,7 @@ protected function getCategoryFiltersAndAssert(
108111
array $expectation,
109112
string $categoryName
110113
): void {
111-
$this->updateAttribute($attributeData);
114+
$this->updateAttribute($attributeData, $this->getAttributeCode());
112115
$this->updateProducts($products, $this->getAttributeCode());
113116
$this->clearInstanceAndReindexSearch();
114117
$category = $this->loadCategory($categoryName, Store::DEFAULT_STORE_ID);
@@ -141,7 +144,10 @@ protected function getCategoryActiveFiltersAndAssert(
141144
string $filterValue,
142145
int $productsCount
143146
): void {
144-
$this->updateAttribute(['is_filterable' => AbstractFilter::ATTRIBUTE_OPTIONS_ONLY_WITH_RESULTS]);
147+
$this->updateAttribute(
148+
['is_filterable' => AbstractFilter::ATTRIBUTE_OPTIONS_ONLY_WITH_RESULTS],
149+
$this->getAttributeCode()
150+
);
145151
$this->updateProducts($products, $this->getAttributeCode());
146152
$this->clearInstanceAndReindexSearch();
147153
$this->navigationBlock->getRequest()->setParams($this->getRequestParams($filterValue));
@@ -169,7 +175,7 @@ protected function getSearchFiltersAndAssert(
169175
array $attributeData,
170176
array $expectation
171177
): void {
172-
$this->updateAttribute($attributeData);
178+
$this->updateAttribute($attributeData, $this->getAttributeCode());
173179
$this->updateProducts($products, $this->getAttributeCode());
174180
$this->clearInstanceAndReindexSearch();
175181
$this->navigationBlock->getRequest()->setParams(['q' => $this->getSearchString()]);
@@ -200,7 +206,8 @@ protected function getSearchActiveFiltersAndAssert(
200206
int $productsCount
201207
): void {
202208
$this->updateAttribute(
203-
['is_filterable' => AbstractFilter::ATTRIBUTE_OPTIONS_ONLY_WITH_RESULTS, 'is_filterable_in_search' => 1]
209+
['is_filterable' => AbstractFilter::ATTRIBUTE_OPTIONS_ONLY_WITH_RESULTS, 'is_filterable_in_search' => 1],
210+
$this->getAttributeCode()
204211
);
205212
$this->updateProducts($products, $this->getAttributeCode());
206213
$this->clearInstanceAndReindexSearch();
@@ -239,12 +246,14 @@ function (AbstractFilter $filter) use ($code) {
239246
* Updates attribute data.
240247
*
241248
* @param array $data
249+
* @param string $attributeCode
242250
* @return void
243251
*/
244252
protected function updateAttribute(
245-
array $data
253+
array $data,
254+
string $attributeCode
246255
): void {
247-
$attribute = $this->attributeRepository->get($this->getAttributeCode());
256+
$attribute = $this->attributeRepository->get($attributeCode);
248257
$attribute->setDataChanges(false);
249258
$attribute->addData($data);
250259

dev/tests/integration/testsuite/Magento/LayeredNavigation/Block/Navigation/Category/FilterScopeTest.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,8 @@ public function testGetFilters(int $scope, array $products, array $expectation):
6363
[
6464
'is_filterable' => AbstractFilter::ATTRIBUTE_OPTIONS_ONLY_WITH_RESULTS,
6565
'is_global' => $scope,
66-
]
66+
],
67+
$this->getAttributeCode()
6768
);
6869
$this->updateProductsOnStore($products);
6970
$this->clearInstanceAndReindexSearch();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,187 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\LayeredNavigation\Block\Navigation\Category;
9+
10+
use Magento\Catalog\Model\Layer\Resolver;
11+
use Magento\Catalog\Model\ResourceModel\Product\Collection;
12+
use Magento\LayeredNavigation\Block\Navigation\AbstractFiltersTest;
13+
use Magento\Catalog\Model\Layer\Filter\AbstractFilter;
14+
use Magento\Store\Model\Store;
15+
16+
/**
17+
* Provides tests for multiple custom select filters in navigation block on category page.
18+
*
19+
* @magentoAppArea frontend
20+
* @magentoAppIsolation enabled
21+
* @magentoDbIsolation disabled
22+
*/
23+
class MultipleFiltersTest extends AbstractFiltersTest
24+
{
25+
/**
26+
* @magentoDataFixture Magento/Catalog/_files/product_dropdown_attribute.php
27+
* @magentoDataFixture Magento/Catalog/_files/configurable_attribute.php
28+
* @magentoDataFixture Magento/Catalog/_files/category_with_three_products.php
29+
* @dataProvider getMultipleActiveFiltersDataProvider
30+
* @param array $products
31+
* @param array $filters
32+
* @param array $expectedProducts
33+
* @return void
34+
*/
35+
public function testGetMultipleActiveFilters(
36+
array $products,
37+
array $filters,
38+
array $expectedProducts
39+
): void {
40+
$this->updateAttributesAndProducts(
41+
$products,
42+
['is_filterable' => AbstractFilter::ATTRIBUTE_OPTIONS_ONLY_WITH_RESULTS]
43+
);
44+
$this->clearInstanceAndReindexSearch();
45+
$this->navigationBlock->getRequest()->setParams($this->getMultipleRequestParams($filters));
46+
$this->navigationBlock->getLayer()->setCurrentCategory(
47+
$this->loadCategory('Category 999', Store::DEFAULT_STORE_ID)
48+
);
49+
$this->navigationBlock->setLayout($this->layout);
50+
$resultProducts = $this->getProductSkus($this->navigationBlock->getLayer()->getProductCollection());
51+
$this->assertEquals($expectedProducts, $resultProducts);
52+
}
53+
54+
/**
55+
* @return array
56+
*/
57+
public function getMultipleActiveFiltersDataProvider(): array
58+
{
59+
return [
60+
'without_filters' => [
61+
'products_data' => [
62+
'test_configurable' => [
63+
'simple1000' => 'Option 1',
64+
'simple1001' => 'Option 2',
65+
'simple1002' => 'Option 2',
66+
],
67+
'dropdown_attribute' => [
68+
'simple1000' => 'Option 1',
69+
'simple1001' => 'Option 2',
70+
'simple1002' => 'Option 3',
71+
],
72+
],
73+
'filters' => [],
74+
'expected_products' => ['simple1000', 'simple1001', 'simple1002'],
75+
],
76+
'applied_first_option_in_both_filters' => [
77+
'products_data' => [
78+
'test_configurable' => [
79+
'simple1000' => 'Option 1',
80+
'simple1001' => 'Option 1',
81+
'simple1002' => 'Option 2',
82+
],
83+
'dropdown_attribute' => [
84+
'simple1000' => 'Option 1',
85+
'simple1001' => 'Option 1',
86+
'simple1002' => 'Option 3',
87+
],
88+
],
89+
'filters' => ['test_configurable' => 'Option 1', 'dropdown_attribute' => 'Option 1'],
90+
'expected_products' => ['simple1000', 'simple1001'],
91+
],
92+
'applied_mixed_options_in_filters' => [
93+
'products_data' => [
94+
'test_configurable' => [
95+
'simple1000' => 'Option 1',
96+
'simple1001' => 'Option 2',
97+
'simple1002' => 'Option 2',
98+
],
99+
'dropdown_attribute' => [
100+
'simple1000' => 'Option 1',
101+
'simple1001' => 'Option 2',
102+
'simple1002' => 'Option 3',
103+
],
104+
],
105+
'filters' => ['test_configurable' => 'Option 2', 'dropdown_attribute' => 'Option 3'],
106+
'expected_products' => ['simple1002'],
107+
],
108+
];
109+
}
110+
111+
/**
112+
* @inheritdoc
113+
*/
114+
protected function getLayerType(): string
115+
{
116+
return Resolver::CATALOG_LAYER_CATEGORY;
117+
}
118+
119+
/**
120+
* Updates products and product attribute.
121+
*
122+
* @param array $productsData
123+
* @param array $attributesData
124+
* @return void
125+
*/
126+
protected function updateAttributesAndProducts(array $productsData, array $attributesData): void
127+
{
128+
$products = [];
129+
foreach ($productsData as $attributeCode => $data) {
130+
$this->updateAttribute($attributesData, $attributeCode);
131+
$attribute = $this->attributeRepository->get($attributeCode);
132+
133+
foreach ($data as $productSku => $stringValue) {
134+
if (empty($products[$productSku])) {
135+
$product = $this->productRepository->get($productSku, false, Store::DEFAULT_STORE_ID, true);
136+
$products[$productSku] = $product;
137+
} else {
138+
$product = $products[$productSku];
139+
}
140+
$productValue = $attribute->usesSource()
141+
? $attribute->getSource()->getOptionId($stringValue)
142+
: $stringValue;
143+
$product->addData([$attribute->getAttributeCode() => $productValue]);
144+
}
145+
}
146+
foreach ($products as $product) {
147+
$this->productRepository->save($product);
148+
}
149+
}
150+
151+
/**
152+
* Returns array with multiple filters.
153+
*
154+
* @param array $filters
155+
* @return array
156+
*/
157+
protected function getMultipleRequestParams(array $filters): array
158+
{
159+
$params = [];
160+
foreach ($filters as $attributeCode => $filterValue) {
161+
$attribute = $this->attributeRepository->get($attributeCode);
162+
$filterValue = $attribute->usesSource()
163+
? $attribute->getSource()->getOptionId($filterValue)
164+
: $filterValue;
165+
166+
$params[$attributeCode] = $filterValue;
167+
}
168+
169+
return $params;
170+
}
171+
172+
/**
173+
* Returns list of product skus from given collection.
174+
*
175+
* @param Collection $getProductCollection
176+
* @return array
177+
*/
178+
protected function getProductSkus(Collection $getProductCollection): array
179+
{
180+
$skus = [];
181+
foreach ($getProductCollection as $product) {
182+
$skus[] = $product->getSku();
183+
}
184+
185+
return $skus;
186+
}
187+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\LayeredNavigation\Block\Navigation\Search;
9+
10+
use Magento\Catalog\Model\Layer\Resolver;
11+
use Magento\LayeredNavigation\Block\Navigation\Category\MultipleFiltersTest as CategoryFilterTest;
12+
use Magento\Catalog\Model\Layer\Filter\AbstractFilter;
13+
14+
/**
15+
* Provides tests for multiple custom select filters in navigation block on search page.
16+
*
17+
* @magentoAppArea frontend
18+
* @magentoAppIsolation enabled
19+
* @magentoDbIsolation disabled
20+
*/
21+
class MultipleFiltersTest extends CategoryFilterTest
22+
{
23+
/**
24+
* @magentoDataFixture Magento/Catalog/_files/product_dropdown_attribute.php
25+
* @magentoDataFixture Magento/Catalog/_files/configurable_attribute.php
26+
* @magentoDataFixture Magento/Catalog/_files/category_with_three_products.php
27+
* @dataProvider getMultipleActiveFiltersDataProvider
28+
* @param array $products
29+
* @param array $filters
30+
* @param array $expectedProducts
31+
* @return void
32+
*/
33+
public function testGetMultipleActiveFilters(
34+
array $products,
35+
array $filters,
36+
array $expectedProducts
37+
): void {
38+
$this->updateAttributesAndProducts(
39+
$products,
40+
['is_filterable' => AbstractFilter::ATTRIBUTE_OPTIONS_ONLY_WITH_RESULTS, 'is_filterable_in_search' => 1]
41+
);
42+
$this->clearInstanceAndReindexSearch();
43+
$this->navigationBlock->getRequest()->setParams(
44+
array_merge($this->getMultipleRequestParams($filters), ['q' => $this->getSearchString()])
45+
);
46+
$this->navigationBlock->setLayout($this->layout);
47+
$resultProducts = $this->getProductSkus($this->navigationBlock->getLayer()->getProductCollection());
48+
$this->assertEquals($expectedProducts, $resultProducts);
49+
}
50+
51+
/**
52+
* @inheritdoc
53+
*/
54+
protected function getLayerType(): string
55+
{
56+
return Resolver::CATALOG_LAYER_SEARCH;
57+
}
58+
}

0 commit comments

Comments
 (0)