Skip to content

Commit 7d19fe0

Browse files
committed
MC-19713: Relative Category links created using PageBuilder have the store name as a URL parameter
- Remove store query param from category and product URL on cms pages
1 parent 63cf5b3 commit 7d19fe0

File tree

2 files changed

+158
-82
lines changed

2 files changed

+158
-82
lines changed

app/code/Magento/Catalog/Block/Widget/Link.php

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,15 @@
44
* See COPYING.txt for license details.
55
*/
66

7-
/**
8-
* Widget to display catalog link
9-
*
10-
* @author Magento Core Team <core@magentocommerce.com>
11-
*/
127
namespace Magento\Catalog\Block\Widget;
138

149
use Magento\CatalogUrlRewrite\Model\ProductUrlRewriteGenerator;
1510
use Magento\UrlRewrite\Model\UrlFinderInterface;
1611
use Magento\UrlRewrite\Service\V1\Data\UrlRewrite;
1712

13+
/**
14+
* Render the URL of given entity
15+
*/
1816
class Link extends \Magento\Framework\View\Element\Html\Link implements \Magento\Widget\Block\BlockInterface
1917
{
2018
/**
@@ -63,10 +61,9 @@ public function __construct(
6361

6462
/**
6563
* Prepare url using passed id path and return it
66-
* or return false if path was not found in url rewrites.
6764
*
6865
* @throws \RuntimeException
69-
* @return string|false
66+
* @return string|false if path was not found in url rewrites.
7067
* @SuppressWarnings(PHPMD.NPathComplexity)
7168
*/
7269
public function getHref()
@@ -92,10 +89,6 @@ public function getHref()
9289

9390
if ($rewrite) {
9491
$href = $store->getUrl('', ['_direct' => $rewrite->getRequestPath()]);
95-
96-
if (strpos($href, '___store') === false) {
97-
$href .= (strpos($href, '?') === false ? '?' : '&') . '___store=' . $store->getCode();
98-
}
9992
}
10093
$this->_href = $href;
10194
}
@@ -121,6 +114,7 @@ protected function parseIdPath($idPath)
121114

122115
/**
123116
* Prepare label using passed text as parameter.
117+
*
124118
* If anchor text was not specified get entity name from DB.
125119
*
126120
* @return string
@@ -150,9 +144,8 @@ public function getLabel()
150144

151145
/**
152146
* Render block HTML
153-
* or return empty string if url can't be prepared
154147
*
155-
* @return string
148+
* @return string empty string if url can't be prepared
156149
*/
157150
protected function _toHtml()
158151
{

app/code/Magento/Catalog/Test/Unit/Block/Widget/LinkTest.php

Lines changed: 152 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -5,54 +5,81 @@
55
*/
66
namespace Magento\Catalog\Test\Unit\Block\Widget;
77

8+
use Exception;
9+
use Magento\Catalog\Block\Widget\Link;
10+
use Magento\Catalog\Model\ResourceModel\AbstractResource;
811
use Magento\CatalogUrlRewrite\Model\ProductUrlRewriteGenerator;
12+
use Magento\Framework\App\Config\ReinitableConfigInterface;
913
use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
14+
use Magento\Framework\Url;
15+
use Magento\Framework\Url\ModifierInterface;
16+
use Magento\Framework\View\Element\Template\Context;
17+
use Magento\Store\Model\Store;
18+
use Magento\Store\Model\StoreManagerInterface;
19+
use Magento\UrlRewrite\Model\UrlFinderInterface;
1020
use Magento\UrlRewrite\Service\V1\Data\UrlRewrite;
21+
use PHPUnit\Framework\TestCase;
22+
use PHPUnit_Framework_MockObject_MockObject;
23+
use ReflectionClass;
24+
use RuntimeException;
1125

12-
class LinkTest extends \PHPUnit\Framework\TestCase
26+
/**
27+
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
28+
* @SuppressWarnings(PHPMD.UnusedLocalVariable)
29+
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
30+
*/
31+
class LinkTest extends TestCase
1332
{
1433
/**
15-
* @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Store\Model\StoreManagerInterface
34+
* @var PHPUnit_Framework_MockObject_MockObject|StoreManagerInterface
1635
*/
1736
protected $storeManager;
1837

1938
/**
20-
* @var \PHPUnit_Framework_MockObject_MockObject|\Magento\UrlRewrite\Model\UrlFinderInterface
39+
* @var PHPUnit_Framework_MockObject_MockObject|UrlFinderInterface
2140
*/
2241
protected $urlFinder;
2342

2443
/**
25-
* @var \Magento\Catalog\Block\Widget\Link
44+
* @var Link
2645
*/
2746
protected $block;
2847

2948
/**
30-
* @var \Magento\Catalog\Model\ResourceModel\AbstractResource|\PHPUnit_Framework_MockObject_MockObject
49+
* @var AbstractResource|PHPUnit_Framework_MockObject_MockObject
3150
*/
3251
protected $entityResource;
3352

53+
/**
54+
* @inheritDoc
55+
*/
3456
protected function setUp()
3557
{
36-
$this->storeManager = $this->createMock(\Magento\Store\Model\StoreManagerInterface::class);
37-
$this->urlFinder = $this->createMock(\Magento\UrlRewrite\Model\UrlFinderInterface::class);
58+
$this->storeManager = $this->createMock(StoreManagerInterface::class);
59+
$this->urlFinder = $this->createMock(UrlFinderInterface::class);
3860

39-
$context = $this->createMock(\Magento\Framework\View\Element\Template\Context::class);
61+
$context = $this->createMock(Context::class);
4062
$context->expects($this->any())
4163
->method('getStoreManager')
4264
->will($this->returnValue($this->storeManager));
4365

4466
$this->entityResource =
45-
$this->createMock(\Magento\Catalog\Model\ResourceModel\AbstractResource::class);
46-
47-
$this->block = (new ObjectManager($this))->getObject(\Magento\Catalog\Block\Widget\Link::class, [
48-
'context' => $context,
49-
'urlFinder' => $this->urlFinder,
50-
'entityResource' => $this->entityResource
51-
]);
67+
$this->createMock(AbstractResource::class);
68+
69+
$this->block = (new ObjectManager($this))->getObject(
70+
Link::class,
71+
[
72+
'context' => $context,
73+
'urlFinder' => $this->urlFinder,
74+
'entityResource' => $this->entityResource
75+
]
76+
);
5277
}
5378

5479
/**
55-
* @expectedException \RuntimeException
80+
* Tests getHref with wrong id_path
81+
*
82+
* @expectedException RuntimeException
5683
* @expectedExceptionMessage Parameter id_path is not set.
5784
*/
5885
public function testGetHrefWithoutSetIdPath()
@@ -61,7 +88,9 @@ public function testGetHrefWithoutSetIdPath()
6188
}
6289

6390
/**
64-
* @expectedException \RuntimeException
91+
* Tests getHref with wrong id_path
92+
*
93+
* @expectedException RuntimeException
6594
* @expectedExceptionMessage Wrong id_path structure.
6695
*/
6796
public function testGetHrefIfSetWrongIdPath()
@@ -70,27 +99,30 @@ public function testGetHrefIfSetWrongIdPath()
7099
$this->block->getHref();
71100
}
72101

102+
/**
103+
* Tests getHref with wrong store ID
104+
*
105+
* @expectedException Exception
106+
*/
73107
public function testGetHrefWithSetStoreId()
74108
{
75109
$this->block->setData('id_path', 'type/id');
76110
$this->block->setData('store_id', 'store_id');
77-
78111
$this->storeManager->expects($this->once())
79-
->method('getStore')->with('store_id')
80-
// interrupt test execution
81-
->will($this->throwException(new \Exception()));
82-
83-
try {
84-
$this->block->getHref();
85-
} catch (\Exception $e) {
86-
}
112+
->method('getStore')
113+
->with('store_id')
114+
->will($this->throwException(new Exception()));
115+
$this->block->getHref();
87116
}
88117

118+
/**
119+
* Tests getHref with not found URL
120+
*/
89121
public function testGetHrefIfRewriteIsNotFound()
90122
{
91123
$this->block->setData('id_path', 'entity_type/entity_id');
92124

93-
$store = $this->createPartialMock(\Magento\Store\Model\Store::class, ['getId', '__wakeUp']);
125+
$store = $this->createPartialMock(Store::class, ['getId', '__wakeUp']);
94126
$store->expects($this->any())
95127
->method('getId');
96128

@@ -105,59 +137,104 @@ public function testGetHrefIfRewriteIsNotFound()
105137
}
106138

107139
/**
108-
* @param string $url
109-
* @param string $separator
140+
* Tests getHref whether it should include the store code or not
141+
*
110142
* @dataProvider dataProviderForTestGetHrefWithoutUrlStoreSuffix
143+
* @param string $path
144+
* @param bool $includeStoreCode
145+
* @param string $expected
146+
* @throws \ReflectionException
111147
*/
112-
public function testGetHrefWithoutUrlStoreSuffix($url, $separator)
113-
{
114-
$storeId = 15;
115-
$storeCode = 'store-code';
116-
$requestPath = 'request-path';
148+
public function testStoreCodeShouldBeIncludedInURLOnlyIfItIsConfiguredSo(
149+
string $path,
150+
bool $includeStoreCode,
151+
string $expected
152+
) {
117153
$this->block->setData('id_path', 'entity_type/entity_id');
118-
119-
$rewrite = $this->createMock(\Magento\UrlRewrite\Service\V1\Data\UrlRewrite::class);
120-
$rewrite->expects($this->once())
121-
->method('getRequestPath')
122-
->will($this->returnValue($requestPath));
123-
124-
$store = $this->createPartialMock(
125-
\Magento\Store\Model\Store::class,
126-
['getId', 'getUrl', 'getCode', '__wakeUp']
154+
$objectManager = new ObjectManager($this);
155+
156+
$rewrite = $this->createPartialMock(UrlRewrite::class, ['getRequestPath']);
157+
$url = $this->createPartialMock(Url::class, ['setScope', 'getUrl']);
158+
$urlModifier = $this->getMockForAbstractClass(ModifierInterface::class);
159+
$config = $this->getMockForAbstractClass(ReinitableConfigInterface::class);
160+
$store = $objectManager->getObject(
161+
Store::class,
162+
[
163+
'storeManager' => $this->storeManager,
164+
'url' => $url,
165+
'config' => $config
166+
]
127167
);
128-
$store->expects($this->once())
129-
->method('getId')
130-
->will($this->returnValue($storeId));
131-
$store->expects($this->once())
168+
$property = (new ReflectionClass(get_class($store)))->getProperty('urlModifier');
169+
$property->setAccessible(true);
170+
$property->setValue($store, $urlModifier);
171+
172+
$urlModifier->expects($this->any())
173+
->method('execute')
174+
->willReturnArgument(0);
175+
$config->expects($this->any())
176+
->method('getValue')
177+
->willReturnMap(
178+
[
179+
[Store::XML_PATH_USE_REWRITES, ReinitableConfigInterface::SCOPE_TYPE_DEFAULT, null, true],
180+
[
181+
Store::XML_PATH_STORE_IN_URL,
182+
ReinitableConfigInterface::SCOPE_TYPE_DEFAULT,
183+
null, $includeStoreCode
184+
]
185+
]
186+
);
187+
188+
$url->expects($this->any())
189+
->method('setScope')
190+
->willReturnSelf();
191+
192+
$url->expects($this->any())
132193
->method('getUrl')
133-
->with('', ['_direct' => $requestPath])
134-
->will($this->returnValue($url));
135-
$store->expects($this->once())
136-
->method('getCode')
137-
->will($this->returnValue($storeCode));
194+
->willReturnCallback(
195+
function ($route, $params) use ($store) {
196+
return rtrim($store->getBaseUrl(), '/') .'/'. ltrim($params['_direct'], '/');
197+
}
198+
);
138199

139-
$this->storeManager->expects($this->once())
200+
$store->addData(['store_id' => 1, 'code' => 'french']);
201+
202+
$this->storeManager
203+
->expects($this->any())
140204
->method('getStore')
141-
->will($this->returnValue($store));
205+
->willReturn($store);
142206

143-
$this->urlFinder->expects($this->once())->method('findOneByData')
144-
->with([
207+
$this->urlFinder->expects($this->once())
208+
->method('findOneByData')
209+
->with(
210+
[
145211
UrlRewrite::ENTITY_ID => 'entity_id',
146212
UrlRewrite::ENTITY_TYPE => 'entity_type',
147-
UrlRewrite::STORE_ID => $storeId,
148-
])
213+
UrlRewrite::STORE_ID => $store->getStoreId(),
214+
]
215+
)
149216
->will($this->returnValue($rewrite));
150217

151-
$this->assertEquals($url . $separator . '___store=' . $storeCode, $this->block->getHref());
218+
$rewrite->expects($this->once())
219+
->method('getRequestPath')
220+
->will($this->returnValue($path));
221+
222+
$this->assertContains($expected, $this->block->getHref());
152223
}
153224

225+
/**
226+
* Tests getLabel with custom text
227+
*/
154228
public function testGetLabelWithCustomText()
155229
{
156230
$customText = 'Some text';
157231
$this->block->setData('anchor_text', $customText);
158232
$this->assertEquals($customText, $this->block->getLabel());
159233
}
160234

235+
/**
236+
* Tests getLabel without custom text
237+
*/
161238
public function testGetLabelWithoutCustomText()
162239
{
163240
$category = 'Some text';
@@ -178,17 +255,20 @@ public function testGetLabelWithoutCustomText()
178255
public function dataProviderForTestGetHrefWithoutUrlStoreSuffix()
179256
{
180257
return [
181-
['url', '?'],
182-
['url?some_parameter', '&'],
258+
['/accessories.html', true, 'french/accessories.html'],
259+
['/accessories.html', false, '/accessories.html'],
183260
];
184261
}
185262

263+
/**
264+
* Tests getHref with product entity and additional category id in the id_path
265+
*/
186266
public function testGetHrefWithForProductWithCategoryIdParameter()
187267
{
188268
$storeId = 15;
189269
$this->block->setData('id_path', ProductUrlRewriteGenerator::ENTITY_TYPE . '/entity_id/category_id');
190270

191-
$store = $this->createPartialMock(\Magento\Store\Model\Store::class, ['getId', '__wakeUp']);
271+
$store = $this->createPartialMock(Store::class, ['getId', '__wakeUp']);
192272
$store->expects($this->any())
193273
->method('getId')
194274
->will($this->returnValue($storeId));
@@ -197,13 +277,16 @@ public function testGetHrefWithForProductWithCategoryIdParameter()
197277
->method('getStore')
198278
->will($this->returnValue($store));
199279

200-
$this->urlFinder->expects($this->once())->method('findOneByData')
201-
->with([
202-
UrlRewrite::ENTITY_ID => 'entity_id',
203-
UrlRewrite::ENTITY_TYPE => ProductUrlRewriteGenerator::ENTITY_TYPE,
204-
UrlRewrite::STORE_ID => $storeId,
205-
UrlRewrite::METADATA => ['category_id' => 'category_id'],
206-
])
280+
$this->urlFinder->expects($this->once())
281+
->method('findOneByData')
282+
->with(
283+
[
284+
UrlRewrite::ENTITY_ID => 'entity_id',
285+
UrlRewrite::ENTITY_TYPE => ProductUrlRewriteGenerator::ENTITY_TYPE,
286+
UrlRewrite::STORE_ID => $storeId,
287+
UrlRewrite::METADATA => ['category_id' => 'category_id'],
288+
]
289+
)
207290
->will($this->returnValue(false));
208291

209292
$this->block->getHref();

0 commit comments

Comments
 (0)