Skip to content

Commit 16b6a0c

Browse files
committed
MAGETWO-96663: UrlRewrite removes query string from url, if url has trailing slash
1 parent 514e3d0 commit 16b6a0c

File tree

2 files changed

+135
-32
lines changed

2 files changed

+135
-32
lines changed

app/code/Magento/UrlRewrite/Controller/Router.php

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ public function __construct(
7777
public function match(RequestInterface $request)
7878
{
7979
$rewrite = $this->getRewrite(
80-
$request->getPathInfo(),
80+
$this->getNormalisedRequestPath($request),
8181
$this->storeManager->getStore()->getId()
8282
);
8383

@@ -153,4 +153,30 @@ protected function getRewrite($requestPath, $storeId)
153153
]
154154
);
155155
}
156+
157+
/**
158+
* Get normalized request path
159+
*
160+
* @param RequestInterface|HttpRequest $request
161+
* @return string
162+
*/
163+
private function getNormalisedRequestPath(RequestInterface $request)
164+
{
165+
$path = $request->getPathInfo();
166+
/**
167+
* If request contains query params then we need to trim a slash in end of the path.
168+
* For example:
169+
* the original request is: http://my-host.com/category-url-key.html/?color=black
170+
* where the original path is: category-url-key.html/
171+
* and the result path will be: category-url-key.html
172+
*
173+
* It need to except a redirect like this:
174+
* http://my-host.com/category-url-key.html/?color=black => http://my-host.com/category-url-key.html
175+
*/
176+
if (!empty($path) && $request->getQuery()->count()) {
177+
$path = rtrim($path, '/');
178+
}
179+
180+
return $path;
181+
}
156182
}

app/code/Magento/UrlRewrite/Test/Unit/Controller/RouterTest.php

Lines changed: 108 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -3,61 +3,88 @@
33
* Copyright © Magento, Inc. All rights reserved.
44
* See COPYING.txt for license details.
55
*/
6-
76
namespace Magento\UrlRewrite\Test\Unit\Controller;
87

98
use Magento\Framework\App\Action\Forward;
109
use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
10+
use Magento\Framework\UrlInterface;
1111
use Magento\UrlRewrite\Service\V1\Data\UrlRewrite;
1212
use Magento\Store\Model\Store;
13+
use PHPUnit\Framework\MockObject\MockObject;
14+
use Zend\Stdlib\ParametersInterface;
1315

1416
/**
17+
* Test class for UrlRewrite Controller Router
18+
*
1519
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
1620
*/
1721
class RouterTest extends \PHPUnit\Framework\TestCase
1822
{
19-
/** @var \Magento\UrlRewrite\Controller\Router */
20-
protected $router;
23+
/**
24+
* @var \Magento\UrlRewrite\Controller\Router
25+
*/
26+
private $router;
27+
28+
/**
29+
* @var \Magento\Framework\App\ActionFactory|MockObject
30+
*/
31+
private $actionFactory;
2132

22-
/** @var \Magento\Framework\App\ActionFactory|\PHPUnit_Framework_MockObject_MockObject */
23-
protected $actionFactory;
33+
/**
34+
* @var UrlInterface|MockObject
35+
*/
36+
private $url;
2437

25-
/** @var \Magento\Framework\UrlInterface|\PHPUnit_Framework_MockObject_MockObject */
26-
protected $url;
38+
/**
39+
* @var \Magento\Store\Model\StoreManagerInterface|MockObject
40+
*/
41+
private $storeManager;
2742

28-
/** @var \Magento\Store\Model\StoreManagerInterface|\PHPUnit_Framework_MockObject_MockObject */
29-
protected $storeManager;
43+
/**
44+
* @var Store|MockObject
45+
*/
46+
private $store;
3047

31-
/** @var \Magento\Store\Model\Store|\PHPUnit_Framework_MockObject_MockObject */
32-
protected $store;
48+
/**
49+
* @var \Magento\Framework\App\ResponseInterface|MockObject
50+
*/
51+
private $response;
3352

34-
/** @var \Magento\Framework\App\ResponseInterface|\PHPUnit_Framework_MockObject_MockObject */
35-
protected $response;
53+
/**
54+
* @var \Magento\Framework\App\RequestInterface|MockObject
55+
*/
56+
private $request;
3657

37-
/** @var \Magento\Framework\App\RequestInterface|\PHPUnit_Framework_MockObject_MockObject */
38-
protected $request;
58+
/**
59+
* @var ParametersInterface|MockObject
60+
*/
61+
private $requestQuery;
3962

40-
/** @var \Magento\UrlRewrite\Model\UrlFinderInterface|\PHPUnit_Framework_MockObject_MockObject */
41-
protected $urlFinder;
63+
/**
64+
* @var \Magento\UrlRewrite\Model\UrlFinderInterface|MockObject
65+
*/
66+
private $urlFinder;
4267

4368
/**
44-
* @return void
69+
* @inheritDoc
4570
*/
4671
protected function setUp()
4772
{
4873
$objectManager = new ObjectManager($this);
4974
$this->actionFactory = $this->createMock(\Magento\Framework\App\ActionFactory::class);
50-
$this->url = $this->createMock(\Magento\Framework\UrlInterface::class);
75+
$this->url = $this->createMock(UrlInterface::class);
5176
$this->storeManager = $this->createMock(\Magento\Store\Model\StoreManagerInterface::class);
5277
$this->response = $this->createPartialMock(
5378
\Magento\Framework\App\ResponseInterface::class,
5479
['setRedirect', 'sendResponse']
5580
);
81+
$this->requestQuery = $this->createMock(ParametersInterface::class);
5682
$this->request = $this->getMockBuilder(\Magento\Framework\App\Request\Http::class)
5783
->disableOriginalConstructor()->getMock();
84+
$this->request->method('getQuery')->willReturn($this->requestQuery);
5885
$this->urlFinder = $this->createMock(\Magento\UrlRewrite\Model\UrlFinderInterface::class);
5986
$this->store = $this->getMockBuilder(
60-
\Magento\Store\Model\Store::class
87+
Store::class
6188
)->disableOriginalConstructor()->getMock();
6289

6390
$this->router = $objectManager->getObject(
@@ -166,17 +193,17 @@ public function testNoRewriteAfterStoreSwitcherWhenNoOldRewrite()
166193
$this->request->expects($this->any())->method('getPathInfo')->will($this->returnValue('request-path'));
167194
$this->request->expects($this->any())->method('getParam')->with('___from_store')
168195
->will($this->returnValue('old-store'));
169-
$oldStore = $this->getMockBuilder(\Magento\Store\Model\Store::class)->disableOriginalConstructor()->getMock();
196+
$oldStore = $this->getMockBuilder(Store::class)->disableOriginalConstructor()->getMock();
170197
$this->storeManager->expects($this->any())->method('getStore')
171198
->will($this->returnValueMap([['old-store', $oldStore], [null, $this->store]]));
172199
$oldStore->expects($this->any())->method('getId')->will($this->returnValue('old-store-id'));
173200
$this->store->expects($this->any())->method('getId')->will($this->returnValue('current-store-id'));
174-
$oldUrlRewrite = $this->getMockBuilder(\Magento\UrlRewrite\Service\V1\Data\UrlRewrite::class)
201+
$oldUrlRewrite = $this->getMockBuilder(UrlRewrite::class)
175202
->disableOriginalConstructor()->getMock();
176203
$oldUrlRewrite->expects($this->any())->method('getEntityType')->will($this->returnValue('entity-type'));
177204
$oldUrlRewrite->expects($this->any())->method('getEntityId')->will($this->returnValue('entity-id'));
178205
$oldUrlRewrite->expects($this->any())->method('getRequestPath')->will($this->returnValue('request-path'));
179-
$urlRewrite = $this->getMockBuilder(\Magento\UrlRewrite\Service\V1\Data\UrlRewrite::class)
206+
$urlRewrite = $this->getMockBuilder(UrlRewrite::class)
180207
->disableOriginalConstructor()->getMock();
181208
$urlRewrite->expects($this->any())->method('getRequestPath')->will($this->returnValue('request-path'));
182209

@@ -191,17 +218,17 @@ public function testNoRewriteAfterStoreSwitcherWhenOldRewriteEqualsToNewOne()
191218
$this->request->expects($this->any())->method('getPathInfo')->will($this->returnValue('request-path'));
192219
$this->request->expects($this->any())->method('getParam')->with('___from_store')
193220
->will($this->returnValue('old-store'));
194-
$oldStore = $this->getMockBuilder(\Magento\Store\Model\Store::class)->disableOriginalConstructor()->getMock();
221+
$oldStore = $this->getMockBuilder(Store::class)->disableOriginalConstructor()->getMock();
195222
$this->storeManager->expects($this->any())->method('getStore')
196223
->will($this->returnValueMap([['old-store', $oldStore], [null, $this->store]]));
197224
$oldStore->expects($this->any())->method('getId')->will($this->returnValue('old-store-id'));
198225
$this->store->expects($this->any())->method('getId')->will($this->returnValue('current-store-id'));
199-
$oldUrlRewrite = $this->getMockBuilder(\Magento\UrlRewrite\Service\V1\Data\UrlRewrite::class)
226+
$oldUrlRewrite = $this->getMockBuilder(UrlRewrite::class)
200227
->disableOriginalConstructor()->getMock();
201228
$oldUrlRewrite->expects($this->any())->method('getEntityType')->will($this->returnValue('entity-type'));
202229
$oldUrlRewrite->expects($this->any())->method('getEntityId')->will($this->returnValue('entity-id'));
203230
$oldUrlRewrite->expects($this->any())->method('getRequestPath')->will($this->returnValue('old-request-path'));
204-
$urlRewrite = $this->getMockBuilder(\Magento\UrlRewrite\Service\V1\Data\UrlRewrite::class)
231+
$urlRewrite = $this->getMockBuilder(UrlRewrite::class)
205232
->disableOriginalConstructor()->getMock();
206233
$urlRewrite->expects($this->any())->method('getRequestPath')->will($this->returnValue('old-request-path'));
207234

@@ -234,7 +261,7 @@ public function testNoRewriteAfterStoreSwitcherWhenOldRewriteEqualsToNewOne()
234261
public function testMatchWithRedirect()
235262
{
236263
$this->storeManager->expects($this->any())->method('getStore')->will($this->returnValue($this->store));
237-
$urlRewrite = $this->getMockBuilder(\Magento\UrlRewrite\Service\V1\Data\UrlRewrite::class)
264+
$urlRewrite = $this->getMockBuilder(UrlRewrite::class)
238265
->disableOriginalConstructor()->getMock();
239266
$urlRewrite->expects($this->any())->method('getRedirectType')->will($this->returnValue('redirect-code'));
240267
$urlRewrite->expects($this->any())->method('getTargetPath')->will($this->returnValue('target-path'));
@@ -256,7 +283,7 @@ public function testMatchWithRedirect()
256283
public function testMatchWithCustomInternalRedirect()
257284
{
258285
$this->storeManager->expects($this->any())->method('getStore')->will($this->returnValue($this->store));
259-
$urlRewrite = $this->getMockBuilder(\Magento\UrlRewrite\Service\V1\Data\UrlRewrite::class)
286+
$urlRewrite = $this->getMockBuilder(UrlRewrite::class)
260287
->disableOriginalConstructor()->getMock();
261288
$urlRewrite->expects($this->any())->method('getEntityType')->will($this->returnValue('custom'));
262289
$urlRewrite->expects($this->any())->method('getRedirectType')->will($this->returnValue('redirect-code'));
@@ -278,7 +305,7 @@ public function testMatchWithCustomInternalRedirect()
278305
public function testMatchWithCustomExternalRedirect($targetPath)
279306
{
280307
$this->storeManager->expects($this->any())->method('getStore')->will($this->returnValue($this->store));
281-
$urlRewrite = $this->getMockBuilder(\Magento\UrlRewrite\Service\V1\Data\UrlRewrite::class)
308+
$urlRewrite = $this->getMockBuilder(UrlRewrite::class)
282309
->disableOriginalConstructor()->getMock();
283310
$urlRewrite->expects($this->any())->method('getEntityType')->will($this->returnValue('custom'));
284311
$urlRewrite->expects($this->any())->method('getRedirectType')->will($this->returnValue('redirect-code'));
@@ -310,18 +337,68 @@ public function externalRedirectTargetPathDataProvider()
310337
public function testMatch()
311338
{
312339
$this->storeManager->expects($this->any())->method('getStore')->will($this->returnValue($this->store));
313-
$urlRewrite = $this->getMockBuilder(\Magento\UrlRewrite\Service\V1\Data\UrlRewrite::class)
340+
$urlRewrite = $this->getMockBuilder(UrlRewrite::class)
314341
->disableOriginalConstructor()->getMock();
315342
$urlRewrite->expects($this->any())->method('getRedirectType')->will($this->returnValue(0));
316343
$urlRewrite->expects($this->any())->method('getTargetPath')->will($this->returnValue('target-path'));
317344
$urlRewrite->expects($this->any())->method('getRequestPath')->will($this->returnValue('request-path'));
318345
$this->urlFinder->expects($this->any())->method('findOneByData')->will($this->returnValue($urlRewrite));
319346
$this->request->expects($this->once())->method('setPathInfo')->with('/target-path');
320347
$this->request->expects($this->once())->method('setAlias')
321-
->with(\Magento\Framework\UrlInterface::REWRITE_REQUEST_PATH_ALIAS, 'request-path');
348+
->with(UrlInterface::REWRITE_REQUEST_PATH_ALIAS, 'request-path');
322349
$this->actionFactory->expects($this->once())->method('create')
323350
->with(\Magento\Framework\App\Action\Forward::class);
324351

325352
$this->router->match($this->request);
326353
}
354+
355+
/**
356+
* Test to match corresponding URL Rewrite on request with query params
357+
*
358+
* @param string $originalRequestPath
359+
* @param string $requestPath
360+
* @param int $countOfQueryParams
361+
* @dataProvider matchWithQueryParamsDataProvider
362+
*/
363+
public function testMatchWithQueryParams(string $originalRequestPath, string $requestPath, int $countOfQueryParams)
364+
{
365+
$targetPath = 'target-path';
366+
367+
$this->storeManager->method('getStore')->willReturn($this->store);
368+
$urlRewrite = $this->createMock(UrlRewrite::class);
369+
$urlRewrite->method('getRedirectType')->willReturn(0);
370+
$urlRewrite->method('getTargetPath')->willReturn($targetPath);
371+
$urlRewrite->method('getRequestPath')->willReturn($requestPath);
372+
$this->urlFinder->method('findOneByData')
373+
->with([UrlRewrite::REQUEST_PATH => $requestPath, UrlRewrite::STORE_ID => $this->store->getId()])
374+
->willReturn($urlRewrite);
375+
376+
$this->requestQuery->method('count')->willReturn($countOfQueryParams);
377+
$this->request->method('getPathInfo')
378+
->willReturn($originalRequestPath);
379+
$this->request->expects($this->once())
380+
->method('setPathInfo')
381+
->with('/' . $targetPath);
382+
$this->request->expects($this->once())
383+
->method('setAlias')
384+
->with(UrlInterface::REWRITE_REQUEST_PATH_ALIAS, $requestPath);
385+
$this->actionFactory->expects($this->once())
386+
->method('create')
387+
->with(Forward::class);
388+
389+
$this->router->match($this->request);
390+
}
391+
392+
/**
393+
* Data provider for Test to match corresponding URL Rewrite on request with query params
394+
*
395+
* @return array
396+
*/
397+
public function matchWithQueryParamsDataProvider(): array
398+
{
399+
return [
400+
['/category.html/', 'category.html/', 0],
401+
['/category.html/', 'category.html', 1],
402+
];
403+
}
327404
}

0 commit comments

Comments
 (0)