Skip to content

Commit 17236cc

Browse files
committed
#27089 Fix issue with returning non-available default limit, coverage with Unit Tests
1 parent a3c2af0 commit 17236cc

File tree

2 files changed

+118
-63
lines changed

2 files changed

+118
-63
lines changed

app/code/Magento/Catalog/Helper/Product/ProductList.php

Lines changed: 44 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,17 @@
33
* Copyright © Magento, Inc. All rights reserved.
44
* See COPYING.txt for license details.
55
*/
6+
declare(strict_types=1);
67

78
namespace Magento\Catalog\Helper\Product;
89

10+
use Magento\Catalog\Model\Config;
11+
use Magento\Framework\App\Config\ScopeConfigInterface;
12+
use Magento\Framework\App\ObjectManager;
13+
use Magento\Framework\Registry;
14+
use Magento\Store\Model\ScopeInterface;
15+
916
/**
10-
* Class ProductList
11-
*
1217
* @api
1318
* @since 100.0.2
1419
*/
@@ -18,18 +23,15 @@ class ProductList
1823
* List mode configuration path
1924
*/
2025
const XML_PATH_LIST_MODE = 'catalog/frontend/list_mode';
21-
22-
const VIEW_MODE_LIST = 'list';
23-
const VIEW_MODE_GRID = 'grid';
24-
2526
const DEFAULT_SORT_DIRECTION = 'asc';
27+
2628
/**
27-
* @var \Magento\Framework\App\Config\ScopeConfigInterface
29+
* @var ScopeConfigInterface
2830
*/
2931
protected $scopeConfig;
3032

3133
/**
32-
* @var \Magento\Framework\Registry
34+
* @var Registry
3335
*/
3436
private $coreRegistry;
3537

@@ -38,20 +40,18 @@ class ProductList
3840
*
3941
* @var array
4042
*/
41-
protected $_defaultAvailableLimit = [10 => 10,20 => 20,50 => 50];
43+
protected $_defaultAvailableLimit = [10 => 10, 20 => 20, 50 => 50];
4244

4345
/**
44-
* @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
45-
* @param \Magento\Framework\Registry $coreRegistry
46+
* @param ScopeConfigInterface $scopeConfig
47+
* @param Registry $coreRegistry
4648
*/
4749
public function __construct(
48-
\Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
49-
\Magento\Framework\Registry $coreRegistry = null
50+
ScopeConfigInterface $scopeConfig,
51+
Registry $coreRegistry = null
5052
) {
5153
$this->scopeConfig = $scopeConfig;
52-
$this->coreRegistry = $coreRegistry ?: \Magento\Framework\App\ObjectManager::getInstance()->get(
53-
\Magento\Framework\Registry::class
54-
);
54+
$this->coreRegistry = $coreRegistry ?? ObjectManager::getInstance()->get(Registry::class);
5555
}
5656

5757
/**
@@ -61,31 +61,23 @@ public function __construct(
6161
*/
6262
public function getAvailableViewMode()
6363
{
64-
$value = $this->scopeConfig->getValue(
65-
self::XML_PATH_LIST_MODE,
66-
\Magento\Store\Model\ScopeInterface::SCOPE_STORE
67-
);
64+
$value = $this->scopeConfig->getValue(self::XML_PATH_LIST_MODE, ScopeInterface::SCOPE_STORE);
65+
6866
switch ($value) {
6967
case 'grid':
70-
$availableMode = ['grid' => __('Grid')];
71-
break;
68+
return ['grid' => __('Grid')];
7269

7370
case 'list':
74-
$availableMode = ['list' => __('List')];
75-
break;
71+
return ['list' => __('List')];
7672

7773
case 'grid-list':
78-
$availableMode = ['grid' => __('Grid'), 'list' => __('List')];
79-
break;
74+
return ['grid' => __('Grid'), 'list' => __('List')];
8075

8176
case 'list-grid':
82-
$availableMode = ['list' => __('List'), 'grid' => __('Grid')];
83-
break;
84-
default:
85-
$availableMode = null;
86-
break;
77+
return ['list' => __('List'), 'grid' => __('Grid')];
8778
}
88-
return $availableMode;
79+
80+
return null;
8981
}
9082

9183
/**
@@ -99,12 +91,14 @@ public function getDefaultViewMode($options = [])
9991
if (empty($options)) {
10092
$options = $this->getAvailableViewMode();
10193
}
94+
10295
return current(array_keys($options));
10396
}
10497

10598
/**
10699
* Get default sort field
107100
*
101+
* @FIXME Helper should be context-independent
108102
* @return null|string
109103
*/
110104
public function getDefaultSortField()
@@ -114,59 +108,46 @@ public function getDefaultSortField()
114108
return $currentCategory->getDefaultSortBy();
115109
}
116110

117-
return $this->scopeConfig->getValue(
118-
\Magento\Catalog\Model\Config::XML_PATH_LIST_DEFAULT_SORT_BY,
119-
\Magento\Store\Model\ScopeInterface::SCOPE_STORE
120-
);
111+
return $this->scopeConfig->getValue(Config::XML_PATH_LIST_DEFAULT_SORT_BY, ScopeInterface::SCOPE_STORE);
121112
}
122113

123114
/**
124115
* Retrieve available limits for specified view mode
125116
*
126-
* @param string $mode
117+
* @param string $viewMode
127118
* @return array
128119
*/
129-
public function getAvailableLimit($mode)
120+
public function getAvailableLimit($viewMode): array
130121
{
131-
if (!in_array($mode, [self::VIEW_MODE_GRID, self::VIEW_MODE_LIST])) {
122+
$availableViewModes = $this->getAvailableViewMode();
123+
124+
if (!isset($availableViewModes[$viewMode])) {
132125
return $this->_defaultAvailableLimit;
133126
}
134-
$perPageConfigKey = 'catalog/frontend/' . $mode . '_per_page_values';
135-
$perPageValues = (string)$this->scopeConfig->getValue(
136-
$perPageConfigKey,
137-
\Magento\Store\Model\ScopeInterface::SCOPE_STORE
138-
);
127+
128+
$perPageConfigPath = 'catalog/frontend/' . $viewMode . '_per_page_values';
129+
$perPageValues = (string)$this->scopeConfig->getValue($perPageConfigPath, ScopeInterface::SCOPE_STORE);
139130
$perPageValues = explode(',', $perPageValues);
140131
$perPageValues = array_combine($perPageValues, $perPageValues);
141-
if ($this->scopeConfig->isSetFlag(
142-
'catalog/frontend/list_allow_all',
143-
\Magento\Store\Model\ScopeInterface::SCOPE_STORE
144-
)) {
132+
if ($this->scopeConfig->isSetFlag('catalog/frontend/list_allow_all', ScopeInterface::SCOPE_STORE)) {
145133
return ($perPageValues + ['all' => __('All')]);
146134
} else {
147135
return $perPageValues;
148136
}
149137
}
150138

151139
/**
152-
* Retrieve default per page values
140+
* Returns default value of `per_page` for view mode provided
153141
*
154142
* @param string $viewMode
155-
* @return string (comma separated)
143+
* @return int
156144
*/
157-
public function getDefaultLimitPerPageValue($viewMode)
145+
public function getDefaultLimitPerPageValue($viewMode): int
158146
{
159-
if ($viewMode == self::VIEW_MODE_LIST) {
160-
return $this->scopeConfig->getValue(
161-
'catalog/frontend/list_per_page',
162-
\Magento\Store\Model\ScopeInterface::SCOPE_STORE
163-
);
164-
} elseif ($viewMode == self::VIEW_MODE_GRID) {
165-
return $this->scopeConfig->getValue(
166-
'catalog/frontend/grid_per_page',
167-
\Magento\Store\Model\ScopeInterface::SCOPE_STORE
168-
);
169-
}
170-
return 0;
147+
$xmlConfigPath = sprintf('catalog/frontend/%s_per_page', $viewMode);
148+
$defaultLimit = $this->scopeConfig->getValue($xmlConfigPath, ScopeInterface::SCOPE_STORE);
149+
150+
$availableLimits = $this->getAvailableLimit($viewMode);
151+
return (int)($availableLimits[$defaultLimit] ?? current($availableLimits));
171152
}
172153
}
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
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\Catalog\Test\Unit\Helper\Product;
9+
10+
11+
use Magento\Catalog\Helper\Product\ProductList;
12+
use Magento\Framework\App\Config\ScopeConfigInterface;
13+
use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
14+
use PHPUnit\Framework\MockObject\MockObject;
15+
use PHPUnit\Framework\TestCase;
16+
17+
class ProductListTest extends TestCase
18+
{
19+
const STUB_VIEW_MODE = 'grid';
20+
/**
21+
* @var ScopeConfigInterface|MockObject
22+
*/
23+
private $scopeConfigMock;
24+
25+
/**
26+
* @var ProductList
27+
*/
28+
private $productListHelper;
29+
30+
protected function setUp()
31+
{
32+
$objectManager = new ObjectManager($this);
33+
34+
$this->scopeConfigMock = $this->getMockForAbstractClass(ScopeConfigInterface::class);
35+
$this->productListHelper = $objectManager->getObject(ProductList::class, [
36+
'scopeConfig' => $this->scopeConfigMock
37+
]);
38+
}
39+
40+
/**
41+
* @dataProvider defaultAvailableLimitsDataProvider
42+
*/
43+
public function testGetDefaultLimitPerPageValueReturnsOneOfAvailableLimits(
44+
string $availableValues,
45+
int $defaultValue,
46+
int $expectedReturn
47+
) {
48+
$this->scopeConfigMock->method('getValue')
49+
->willReturnMap([
50+
[sprintf('catalog/frontend/%s_per_page_values', self::STUB_VIEW_MODE), $availableValues],
51+
[sprintf('catalog/frontend/%s_per_page', self::STUB_VIEW_MODE), $defaultValue]
52+
]);
53+
54+
$returnedValue = $this->productListHelper->getDefaultLimitPerPageValue(self::STUB_VIEW_MODE);
55+
56+
$this->assertSame($expectedReturn, $returnedValue);
57+
}
58+
59+
public function defaultAvailableLimitsDataProvider(): array
60+
{
61+
return [
62+
'limit-available' => [
63+
'values' => '10,20,30',
64+
'default' => 10,
65+
'expected' => 10
66+
],
67+
'limit-not-available' => [
68+
'values' => '10,20,30',
69+
'default' => 1,
70+
'expected' => 10
71+
]
72+
];
73+
}
74+
}

0 commit comments

Comments
 (0)