Skip to content

Commit

Permalink
Fix magento#13401 - Multi-Store: "Store View" sort order values are n…
Browse files Browse the repository at this point in the history
…ot reflected in front-end store-switcher
  • Loading branch information
Bartlomiejsz committed May 8, 2020
1 parent 6b6f428 commit 85b6d05
Show file tree
Hide file tree
Showing 2 changed files with 126 additions and 42 deletions.
5 changes: 5 additions & 0 deletions app/code/Magento/Store/Block/Switcher.php
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,12 @@ public function getStores()
$stores = [];
} else {
$stores = $rawStores[$groupId];

uasort($stores, static function ($itemA, $itemB) {
return (int)$itemA->getSortOrder() <=> (int)$itemB->getSortOrder();
});
}

$this->setData('stores', $stores);
}
return $this->getData('stores');
Expand Down
163 changes: 121 additions & 42 deletions app/code/Magento/Store/Test/Unit/Block/SwitcherTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,84 +3,163 @@
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types=1);

namespace Magento\Store\Test\Unit\Block;

use Magento\Directory\Helper\Data;
use Magento\Framework\App\Config\ScopeConfigInterface;
use Magento\Framework\Data\Helper\PostHelper;
use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
use Magento\Framework\UrlInterface;
use Magento\Framework\View\Element\Template\Context;
use Magento\Store\Api\Data\StoreInterface;
use Magento\Store\Block\Switcher;
use Magento\Store\Model\ScopeInterface;
use Magento\Store\Model\Store;
use Magento\Store\Model\StoreManagerInterface;
use Magento\Store\Model\Website;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;

class SwitcherTest extends \PHPUnit\Framework\TestCase
/**
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
*/
class SwitcherTest extends TestCase
{
/** @var \Magento\Store\Block\Switcher */
protected $switcher;

/** @var \Magento\Framework\View\Element\Template\Context|\PHPUnit_Framework_MockObject_MockObject */
protected $context;
/**
* @var Switcher
*/
private $switcher;

/** @var \Magento\Framework\Data\Helper\PostHelper|\PHPUnit_Framework_MockObject_MockObject */
protected $corePostDataHelper;
/**
* @var PostHelper|MockObject
*/
private $corePostDataHelperMock;

/** @var \Magento\Store\Model\StoreManagerInterface|\PHPUnit_Framework_MockObject_MockObject */
protected $storeManager;
/**
* @var StoreManagerInterface|MockObject
*/
private $storeManagerMock;

/** @var \Magento\Framework\UrlInterface|\PHPUnit_Framework_MockObject_MockObject */
protected $urlBuilder;
/**
* @var UrlInterface|MockObject
*/
private $urlBuilderMock;

/** @var \Magento\Store\Api\Data\StoreInterface|\PHPUnit_Framework_MockObject_MockObject */
private $store;
/**
* @var ScopeConfigInterface|MockObject
*/
private $scopeConfigMock;

/**
* @return void
*/
protected function setUp()
protected function setUp(): void
{
$this->storeManager = $this->getMockBuilder(\Magento\Store\Model\StoreManagerInterface::class)->getMock();
$this->urlBuilder = $this->createMock(\Magento\Framework\UrlInterface::class);
$this->context = $this->createMock(\Magento\Framework\View\Element\Template\Context::class);
$this->context->expects($this->any())->method('getStoreManager')->will($this->returnValue($this->storeManager));
$this->context->expects($this->any())->method('getUrlBuilder')->will($this->returnValue($this->urlBuilder));
$this->corePostDataHelper = $this->createMock(\Magento\Framework\Data\Helper\PostHelper::class);
$this->store = $this->getMockBuilder(\Magento\Store\Api\Data\StoreInterface::class)
->disableOriginalConstructor()
->getMockForAbstractClass();
$this->storeManagerMock = $this->getMockBuilder(StoreManagerInterface::class)->getMock();
$this->urlBuilderMock = $this->createMock(UrlInterface::class);
$this->scopeConfigMock = $this->createMock(ScopeConfigInterface::class);
$contextMock = $this->createMock(Context::class);
$contextMock->method('getStoreManager')->willReturn($this->storeManagerMock);
$contextMock->method('getUrlBuilder')->willReturn($this->urlBuilderMock);
$contextMock->method('getScopeConfig')->willReturn($this->scopeConfigMock);
$this->corePostDataHelperMock = $this->createMock(PostHelper::class);
$this->switcher = (new ObjectManager($this))->getObject(
\Magento\Store\Block\Switcher::class,
Switcher::class,
[
'context' => $this->context,
'postDataHelper' => $this->corePostDataHelper,
'context' => $contextMock,
'postDataHelper' => $this->corePostDataHelperMock,
]
);
}

public function testGetStoresSortOrder()
{
$groupId = 1;
$storesSortOrder = [
1 => 2,
2 => 4,
3 => 1,
4 => 3
];

$currentStoreMock = $this->getMockBuilder(Store::class)
->disableOriginalConstructor()
->getMock();
$currentStoreMock->method('getGroupId')->willReturn($groupId);
$currentStoreMock->method('isUseStoreInUrl')->willReturn(false);
$this->storeManagerMock->method('getStore')
->willReturn($currentStoreMock);

$currentWebsiteMock = $this->getMockBuilder(Website::class)
->disableOriginalConstructor()
->getMock();
$this->storeManagerMock->method('getWebsite')
->willReturn($currentWebsiteMock);

$stores = [];
foreach ($storesSortOrder as $storeId => $sortOrder) {
$storeMock = $this->getMockBuilder(Store::class)
->disableOriginalConstructor()
->setMethods(['getId', 'getGroupId', 'getSortOrder', 'isActive', 'getUrl'])
->getMock();
$storeMock->method('getId')->willReturn($storeId);
$storeMock->method('getGroupId')->willReturn($groupId);
$storeMock->method('getSortOrder')->willReturn($sortOrder);
$storeMock->method('isActive')->willReturn(true);
$storeMock->method('getUrl')->willReturn('https://example.org');
$stores[] = $storeMock;
}

$scopeConfigMap = array_map(static function ($item) {
return [
Data::XML_PATH_DEFAULT_LOCALE,
ScopeInterface::SCOPE_STORE,
$item,
'en_US'
];
}, $stores);
$this->scopeConfigMock->method('getValue')
->willReturnMap($scopeConfigMap);

$currentWebsiteMock->method('getStores')
->willReturn($stores);

$this->assertEquals([3, 1, 4, 2], array_keys($this->switcher->getStores()));
}

/**
* @return void
*/
public function testGetTargetStorePostData()
{
$store = $this->getMockBuilder(\Magento\Store\Model\Store::class)
$storeMock = $this->getMockBuilder(Store::class)
->disableOriginalConstructor()
->getMock();
$store->expects($this->any())
->method('getCode')
$oldStoreMock = $this->getMockBuilder(StoreInterface::class)
->disableOriginalConstructor()
->getMockForAbstractClass();
$storeMock->method('getCode')
->willReturn('new-store');
$storeSwitchUrl = 'http://domain.com/stores/store/redirect';
$store->expects($this->atLeastOnce())
$storeMock->expects($this->atLeastOnce())
->method('getCurrentUrl')
->with(false)
->willReturn($storeSwitchUrl);
$this->storeManager->expects($this->once())
$this->storeManagerMock->expects($this->once())
->method('getStore')
->willReturn($this->store);
$this->store->expects($this->once())
->willReturn($oldStoreMock);
$oldStoreMock->expects($this->once())
->method('getCode')
->willReturn('old-store');
$this->urlBuilder->expects($this->once())
$this->urlBuilderMock->expects($this->once())
->method('getUrl')
->willReturn($storeSwitchUrl);
$this->corePostDataHelper->expects($this->any())
->method('getPostData')
$this->corePostDataHelperMock->method('getPostData')
->with($storeSwitchUrl, ['___store' => 'new-store', 'uenc' => null, '___from_store' => 'old-store']);

$this->switcher->getTargetStorePostData($store);
$this->switcher->getTargetStorePostData($storeMock);
}

/**
Expand All @@ -89,11 +168,11 @@ public function testGetTargetStorePostData()
*/
public function testIsStoreInUrl($isUseStoreInUrl)
{
$storeMock = $this->createMock(\Magento\Store\Model\Store::class);
$storeMock = $this->createMock(Store::class);

$storeMock->expects($this->once())->method('isUseStoreInUrl')->will($this->returnValue($isUseStoreInUrl));
$storeMock->expects($this->once())->method('isUseStoreInUrl')->willReturn($isUseStoreInUrl);

$this->storeManager->expects($this->any())->method('getStore')->will($this->returnValue($storeMock));
$this->storeManagerMock->method('getStore')->willReturn($storeMock);
$this->assertEquals($this->switcher->isStoreInUrl(), $isUseStoreInUrl);
// check value is cached
$this->assertEquals($this->switcher->isStoreInUrl(), $isUseStoreInUrl);
Expand All @@ -103,7 +182,7 @@ public function testIsStoreInUrl($isUseStoreInUrl)
* @see self::testIsStoreInUrlDataProvider()
* @return array
*/
public function isStoreInUrlDataProvider()
public function isStoreInUrlDataProvider(): array
{
return [[true], [false]];
}
Expand Down

0 comments on commit 85b6d05

Please sign in to comment.