diff --git a/app/code/Magento/Store/Block/Switcher.php b/app/code/Magento/Store/Block/Switcher.php index f15349f11066d..df8eaa1cf85da 100644 --- a/app/code/Magento/Store/Block/Switcher.php +++ b/app/code/Magento/Store/Block/Switcher.php @@ -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'); diff --git a/app/code/Magento/Store/Test/Unit/Block/SwitcherTest.php b/app/code/Magento/Store/Test/Unit/Block/SwitcherTest.php index aca3525a4400e..60c69834f6aa6 100644 --- a/app/code/Magento/Store/Test/Unit/Block/SwitcherTest.php +++ b/app/code/Magento/Store/Test/Unit/Block/SwitcherTest.php @@ -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); } /** @@ -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); @@ -103,7 +182,7 @@ public function testIsStoreInUrl($isUseStoreInUrl) * @see self::testIsStoreInUrlDataProvider() * @return array */ - public function isStoreInUrlDataProvider() + public function isStoreInUrlDataProvider(): array { return [[true], [false]]; }