Skip to content

Commit 47c394e

Browse files
MC-30562: Storefront: Layered Navigation with configurable product
1 parent 420a8b6 commit 47c394e

File tree

5 files changed

+432
-1
lines changed

5 files changed

+432
-1
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
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+
use Magento\Catalog\Api\CategoryLinkManagementInterface;
9+
use Magento\Catalog\Helper\DefaultCategory;
10+
use Magento\TestFramework\Helper\Bootstrap;
11+
12+
require __DIR__ . '/../../Catalog/_files/category.php';
13+
require __DIR__ . '/product_configurable.php';
14+
15+
$objectManager = Bootstrap::getObjectManager();
16+
/** @var CategoryLinkManagementInterface $categoryLinkManagement */
17+
$categoryLinkManagement = $objectManager->create(CategoryLinkManagementInterface::class);
18+
/** @var DefaultCategory $categoryHelper */
19+
$categoryHelper = $objectManager->get(DefaultCategory::class);
20+
21+
foreach (['simple_10', 'simple_20', 'configurable'] as $sku) {
22+
$categoryLinkManagement->assignProductToCategories($sku, [$categoryHelper->getId(), 333]);
23+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
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+
require __DIR__ . '/../../Catalog/_files/category_rollback.php';
9+
require __DIR__ . '/product_configurable_rollback.php';

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,8 +182,12 @@ protected function updateAttribute(
182182
array $data
183183
): void {
184184
$attribute = $this->attributeRepository->get($this->getAttributeCode());
185+
$attribute->setDataChanges(false);
185186
$attribute->addData($data);
186-
$this->attributeRepository->save($attribute);
187+
188+
if ($attribute->hasDataChanges()) {
189+
$this->attributeRepository->save($attribute);
190+
}
187191
}
188192

189193
/**
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
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\Configurable;
9+
10+
use Magento\Catalog\Model\Layer\Resolver;
11+
use Magento\Catalog\Model\Product\Attribute\Source\Status;
12+
use Magento\Framework\Module\Manager;
13+
use Magento\LayeredNavigation\Block\Navigation\AbstractFiltersTest;
14+
use Magento\Catalog\Model\Layer\Filter\AbstractFilter;
15+
use Magento\Catalog\Model\Layer\Filter\Item;
16+
use Magento\Store\Model\Store;
17+
18+
/**
19+
* Provides price filter tests for configurable in navigation block on category page.
20+
*
21+
* @magentoAppArea frontend
22+
* @magentoAppIsolation enabled
23+
* @magentoDbIsolation disabled
24+
*/
25+
class PriceFilterTest extends AbstractFiltersTest
26+
{
27+
/**
28+
* @var Manager
29+
*/
30+
private $moduleManager;
31+
32+
/**
33+
* @inheritdoc
34+
*/
35+
protected function setUp()
36+
{
37+
parent::setUp();
38+
$this->moduleManager = $this->objectManager->get(Manager::class);
39+
//This check is needed because LayeredNavigation independent of Magento_ConfigurableProduct
40+
if (!$this->moduleManager->isEnabled('Magento_ConfigurableProduct')) {
41+
$this->markTestSkipped('Magento_ConfigurableProduct module disabled.');
42+
}
43+
}
44+
45+
/**
46+
* @magentoDataFixture Magento/ConfigurableProduct/_files/configurable_product_with_category.php
47+
* @magentoDataFixture Magento/Catalog/_files/category_product.php
48+
* @magentoConfigFixture current_store catalog/layered_navigation/price_range_calculation manual
49+
* @magentoConfigFixture current_store catalog/layered_navigation/price_range_step 10
50+
* @dataProvider getFiltersDataProvider
51+
* @param array $products
52+
* @param array $expectation
53+
* @return void
54+
*/
55+
public function testGetFilters(array $products, array $expectation): void
56+
{
57+
$this->updateProductData($products);
58+
$this->getCategoryFiltersAndAssert([], ['is_filterable' => '1'], $expectation, 'Category 1');
59+
}
60+
61+
/**
62+
* @return array
63+
*/
64+
public function getFiltersDataProvider(): array
65+
{
66+
return [
67+
'all_children_active' => [
68+
'products_data' => [
69+
'simple333' => ['price' => 60.00],
70+
],
71+
'expectation' => [
72+
[
73+
'label' => '<span class="price">$10.00</span> - <span class="price">$19.99</span>',
74+
'value' => '10-20',
75+
'count' => 1,
76+
],
77+
[
78+
'label' => '<span class="price">$60.00</span> and above',
79+
'value' => '60-',
80+
'count' => 1,
81+
],
82+
],
83+
],
84+
'one_child_disabled' => [
85+
'products_data' => [
86+
'simple333' => ['price' => 50.00],
87+
'simple_10' => ['status' => Status::STATUS_DISABLED],
88+
],
89+
'expectation' => [
90+
[
91+
'label' => '<span class="price">$20.00</span> - <span class="price">$29.99</span>',
92+
'value' => '20-30',
93+
'count' => 1,
94+
],
95+
[
96+
'label' => '<span class="price">$50.00</span> and above',
97+
'value' => '50-',
98+
'count' => 1,
99+
],
100+
],
101+
],
102+
];
103+
}
104+
105+
/**
106+
* @inheritdoc
107+
*/
108+
protected function getLayerType(): string
109+
{
110+
return Resolver::CATALOG_LAYER_CATEGORY;
111+
}
112+
113+
/**
114+
* @inheritdoc
115+
*/
116+
protected function getAttributeCode(): string
117+
{
118+
return 'price';
119+
}
120+
121+
/**
122+
* @inheritdoc
123+
*/
124+
protected function prepareFilterItems(AbstractFilter $filter): array
125+
{
126+
$items = [];
127+
/** @var Item $item */
128+
foreach ($filter->getItems() as $item) {
129+
$item = [
130+
'label' => __($item->getData('label'))->render(),
131+
'value' => $item->getData('value'),
132+
'count' => $item->getData('count'),
133+
];
134+
$items[] = $item;
135+
}
136+
137+
return $items;
138+
}
139+
140+
/**
141+
* Updates products data.
142+
*
143+
* @param array $products
144+
* @param int $storeId
145+
* @return void
146+
*/
147+
private function updateProductData(
148+
array $products,
149+
int $storeId = Store::DEFAULT_STORE_ID
150+
): void {
151+
foreach ($products as $productSku => $data) {
152+
$product = $this->productRepository->get($productSku, false, $storeId, true);
153+
$product->addData($data);
154+
$this->productRepository->save($product);
155+
}
156+
}
157+
}

0 commit comments

Comments
 (0)