diff --git a/app/code/Magento/Catalog/Block/Product/ProductList/Toolbar.php b/app/code/Magento/Catalog/Block/Product/ProductList/Toolbar.php index f461b525152530cb15a8a2ea8964c6170390aa09..df98969c262cea0b631504f57abd1353c4ab26d3 100644 --- a/app/code/Magento/Catalog/Block/Product/ProductList/Toolbar.php +++ b/app/code/Magento/Catalog/Block/Product/ProductList/Toolbar.php @@ -192,7 +192,14 @@ class Toolbar extends \Magento\Framework\View\Element\Template $this->_collection->setPageSize($limit); } if ($this->getCurrentOrder()) { - $this->_collection->setOrder($this->getCurrentOrder(), $this->getCurrentDirection()); + if ($this->getCurrentOrder() == 'position') { + $this->_collection->addAttributeToSort( + $this->getCurrentOrder(), + $this->getCurrentDirection() + )->addAttributeToSort('entity_id', $this->getCurrentDirection()); + } else { + $this->_collection->setOrder($this->getCurrentOrder(), $this->getCurrentDirection()); + } } return $this; } diff --git a/app/code/Magento/Catalog/Model/Indexer/Category/Flat/AbstractAction.php b/app/code/Magento/Catalog/Model/Indexer/Category/Flat/AbstractAction.php index 24d81f0054c5a1bde1f90ab1212bd629e36c81ec..8f0e6e9c0cdb5c60d1a065f4176a2aed829071d8 100644 --- a/app/code/Magento/Catalog/Model/Indexer/Category/Flat/AbstractAction.php +++ b/app/code/Magento/Catalog/Model/Indexer/Category/Flat/AbstractAction.php @@ -369,25 +369,55 @@ class AbstractAction } $values = []; - foreach ($entityIds as $entityId) { - $values[$entityId] = []; + $linkIds = $this->getLinkIds($entityIds); + foreach ($linkIds as $linkId) { + $values[$linkId] = []; } + $attributes = $this->getAttributes(); $attributesType = ['varchar', 'int', 'decimal', 'text', 'datetime']; + $linkField = $this->getCategoryMetadata()->getLinkField(); foreach ($attributesType as $type) { foreach ($this->getAttributeTypeValues($type, $entityIds, $storeId) as $row) { - if (isset($row[$this->getCategoryMetadata()->getLinkField()]) && isset($row['attribute_id'])) { + if (isset($row[$linkField]) && isset($row['attribute_id'])) { $attributeId = $row['attribute_id']; if (isset($attributes[$attributeId])) { $attributeCode = $attributes[$attributeId]['attribute_code']; - $values[$row[$this->getCategoryMetadata()->getLinkField()]][$attributeCode] = $row['value']; + $values[$row[$linkField]][$attributeCode] = $row['value']; } } } } + return $values; } + /** + * Translate entity ids into link ids + * + * Used for rows with no EAV attributes set. + * + * @param array $entityIds + * @return array + */ + private function getLinkIds(array $entityIds) + { + $linkField = $this->getCategoryMetadata()->getLinkField(); + if ($linkField === 'entity_id') { + return $entityIds; + } + + $select = $this->connection->select()->from( + ['e' => $this->connection->getTableName($this->getTableName('catalog_category_entity'))], + [$linkField] + )->where( + 'e.entity_id IN (?)', + $entityIds + ); + + return $this->connection->fetchCol($select); + } + /** * Return attribute values for given entities and store of specific attribute type * diff --git a/app/code/Magento/Catalog/Model/Indexer/Category/Flat/Action/Full.php b/app/code/Magento/Catalog/Model/Indexer/Category/Flat/Action/Full.php index eeac2e80af97e355233457518db92cf9ea86d31d..64a8f930d83ee4ab2298bb69fd0f597ad0f53755 100644 --- a/app/code/Magento/Catalog/Model/Indexer/Category/Flat/Action/Full.php +++ b/app/code/Magento/Catalog/Model/Indexer/Category/Flat/Action/Full.php @@ -64,18 +64,22 @@ class Full extends \Magento\Catalog\Model\Indexer\Category\Flat\AbstractAction } /** @TODO Do something with chunks */ $categoriesIdsChunks = array_chunk($categoriesIds[$store->getRootCategoryId()], 500); + foreach ($categoriesIdsChunks as $categoriesIdsChunk) { $attributesData = $this->getAttributeValues($categoriesIdsChunk, $store->getId()); + $linkField = $this->categoryMetadata->getLinkField(); + $data = []; foreach ($categories[$store->getRootCategoryId()] as $category) { - if (!isset($attributesData[$category[$this->categoryMetadata->getLinkField()]])) { + if (!isset($attributesData[$category[$linkField]])) { continue; } $category['store_id'] = $store->getId(); $data[] = $this->prepareValuesToInsert( - array_merge($category, $attributesData[$category[$this->categoryMetadata->getLinkField()]]) + array_merge($category, $attributesData[$category[$linkField]]) ); } + $this->connection->insertMultiple( $this->addTemporaryTableSuffix($this->getMainStoreTable($store->getId())), $data diff --git a/app/code/Magento/Catalog/Model/Indexer/Category/Flat/Action/Rows.php b/app/code/Magento/Catalog/Model/Indexer/Category/Flat/Action/Rows.php index 2368c27e02d72b1e64fcc5c23a29b01e0f10436e..bc17d731f04c0a00cf1c0e62300bbba33230de68 100644 --- a/app/code/Magento/Catalog/Model/Indexer/Category/Flat/Action/Rows.php +++ b/app/code/Magento/Catalog/Model/Indexer/Category/Flat/Action/Rows.php @@ -69,22 +69,24 @@ class Rows extends \Magento\Catalog\Model\Indexer\Category\Flat\AbstractAction $categoriesIdsChunk = $this->filterIdsByStore($categoriesIdsChunk, $store); $attributesData = $this->getAttributeValues($categoriesIdsChunk, $store->getId()); + $linkField = $this->categoryMetadata->getLinkField(); $data = []; foreach ($categoriesIdsChunk as $categoryId) { - if (!isset($attributesData[$categoryId])) { - continue; - } - try { $category = $this->categoryRepository->get($categoryId); } catch (NoSuchEntityException $e) { continue; } + $categoryData = $category->getData(); + if (!isset($attributesData[$categoryData[$linkField]])) { + continue; + } + $data[] = $this->prepareValuesToInsert( array_merge( - $category->getData(), - $attributesData[$categoryId], + $categoryData, + $attributesData[$categoryData[$linkField]], ['store_id' => $store->getId()] ) ); diff --git a/app/code/Magento/Catalog/Model/Product.php b/app/code/Magento/Catalog/Model/Product.php index cf1392a7e9e8c80082d8375f4d6b1ccb02492532..cb5669a4bb42e9215efada3b49885d8fd013b62f 100644 --- a/app/code/Magento/Catalog/Model/Product.php +++ b/app/code/Magento/Catalog/Model/Product.php @@ -1712,7 +1712,7 @@ class Product extends \Magento\Catalog\Model\AbstractModel implements * Get attribute text by its code * * @param string $attributeCode Code of the attribute - * @return string + * @return string|array|null */ public function getAttributeText($attributeCode) { diff --git a/app/code/Magento/Catalog/Model/Product/Option/Value.php b/app/code/Magento/Catalog/Model/Product/Option/Value.php index 0e86510ebcee7f82f96fc250e07940e664ca5971..d4c78772e7c0be357ac95845dc8f3f1f56d1a72f 100644 --- a/app/code/Magento/Catalog/Model/Product/Option/Value.php +++ b/app/code/Magento/Catalog/Model/Product/Option/Value.php @@ -190,6 +190,7 @@ class Value extends AbstractModel implements \Magento\Catalog\Api\Data\ProductCu public function saveValues() { foreach ($this->getValues() as $value) { + $this->isDeleted(false); $this->setData( $value )->setData( diff --git a/app/code/Magento/Customer/Controller/Ajax/Login.php b/app/code/Magento/Customer/Controller/Ajax/Login.php index f1384ba188a0a113abb269e0621082a531ff3293..8664e0cbf87ea3abdcf36a16340ead10fd432c74 100644 --- a/app/code/Magento/Customer/Controller/Ajax/Login.php +++ b/app/code/Magento/Customer/Controller/Ajax/Login.php @@ -13,6 +13,8 @@ use Magento\Framework\App\ObjectManager; use Magento\Customer\Model\Account\Redirect as AccountRedirect; use Magento\Framework\App\Config\ScopeConfigInterface; use Magento\Framework\Exception\LocalizedException; +use Magento\Framework\Stdlib\CookieManagerInterface; +use Magento\Framework\Stdlib\Cookie\CookieMetadataFactory; /** * Login controller @@ -58,6 +60,16 @@ class Login extends \Magento\Framework\App\Action\Action */ protected $scopeConfig; + /** + * @var CookieManagerInterface + */ + private $cookieManager; + + /** + * @var CookieMetadataFactory + */ + private $cookieMetadataFactory; + /** * Initialize Login controller * @@ -67,6 +79,8 @@ class Login extends \Magento\Framework\App\Action\Action * @param AccountManagementInterface $customerAccountManagement * @param \Magento\Framework\Controller\Result\JsonFactory $resultJsonFactory * @param \Magento\Framework\Controller\Result\RawFactory $resultRawFactory + * @param CookieManagerInterface $cookieManager + * @param CookieMetadataFactory $cookieMetadataFactory */ public function __construct( \Magento\Framework\App\Action\Context $context, @@ -74,7 +88,9 @@ class Login extends \Magento\Framework\App\Action\Action \Magento\Framework\Json\Helper\Data $helper, AccountManagementInterface $customerAccountManagement, \Magento\Framework\Controller\Result\JsonFactory $resultJsonFactory, - \Magento\Framework\Controller\Result\RawFactory $resultRawFactory + \Magento\Framework\Controller\Result\RawFactory $resultRawFactory, + CookieManagerInterface $cookieManager = null, + CookieMetadataFactory $cookieMetadataFactory = null ) { parent::__construct($context); $this->customerSession = $customerSession; @@ -82,6 +98,12 @@ class Login extends \Magento\Framework\App\Action\Action $this->customerAccountManagement = $customerAccountManagement; $this->resultJsonFactory = $resultJsonFactory; $this->resultRawFactory = $resultRawFactory; + $this->cookieManager = $cookieManager ?: ObjectManager::getInstance()->get( + CookieManagerInterface::class + ); + $this->cookieMetadataFactory = $cookieMetadataFactory ?: ObjectManager::getInstance()->get( + CookieMetadataFactory::class + ); } /** @@ -169,6 +191,11 @@ class Login extends \Magento\Framework\App\Action\Action $this->customerSession->setCustomerDataAsLoggedIn($customer); $this->customerSession->regenerateId(); $redirectRoute = $this->getAccountRedirect()->getRedirectCookie(); + if ($this->cookieManager->getCookie('mage-cache-sessid')) { + $metadata = $this->cookieMetadataFactory->createCookieMetadata(); + $metadata->setPath('/'); + $this->cookieManager->deleteCookie('mage-cache-sessid', $metadata); + } if (!$this->getScopeConfig()->getValue('customer/startup/redirect_dashboard') && $redirectRoute) { $response['redirectUrl'] = $this->_redirect->success($redirectRoute); $this->getAccountRedirect()->clearRedirectCookie(); diff --git a/app/code/Magento/Customer/Test/Unit/Controller/Ajax/LoginTest.php b/app/code/Magento/Customer/Test/Unit/Controller/Ajax/LoginTest.php index b759b1a62573f45d6621bcc7a786e25ff03ec993..2fca6c99be31993f6e1cd59ce53b849cbb04ad9c 100644 --- a/app/code/Magento/Customer/Test/Unit/Controller/Ajax/LoginTest.php +++ b/app/code/Magento/Customer/Test/Unit/Controller/Ajax/LoginTest.php @@ -73,6 +73,21 @@ class LoginTest extends \PHPUnit\Framework\TestCase */ protected $redirectMock; + /** + * @var \Magento\Framework\Stdlib\CookieManagerInterface| \PHPUnit_Framework_MockObject_MockObject + */ + private $cookieManager; + + /** + * @var \Magento\Framework\Stdlib\Cookie\CookieMetadataFactory| \PHPUnit_Framework_MockObject_MockObject + */ + private $cookieMetadataFactory; + + /** + * @var \Magento\Framework\Stdlib\Cookie\CookieMetadata| \PHPUnit_Framework_MockObject_MockObject + */ + private $cookieMetadata; + protected function setUp() { $this->request = $this->getMockBuilder(\Magento\Framework\App\Request\Http::class) @@ -100,6 +115,16 @@ class LoginTest extends \PHPUnit\Framework\TestCase ->setMethods(['create']) ->getMock(); + $this->cookieManager = $this->getMockBuilder(\Magento\Framework\Stdlib\CookieManagerInterface::class) + ->setMethods(['getCookie', 'deleteCookie']) + ->getMockForAbstractClass(); + $this->cookieMetadataFactory = $this->getMockBuilder(\Magento\Framework\Stdlib\Cookie\CookieMetadataFactory::class) + ->disableOriginalConstructor() + ->getMock(); + $this->cookieMetadata = $this->getMockBuilder(\Magento\Framework\Stdlib\Cookie\CookieMetadata::class) + ->disableOriginalConstructor() + ->getMock(); + $this->resultRaw = $this->getMockBuilder(\Magento\Framework\Controller\Result\Raw::class) ->disableOriginalConstructor() ->getMock(); @@ -128,6 +153,8 @@ class LoginTest extends \PHPUnit\Framework\TestCase 'resultJsonFactory' => $this->resultJsonFactory, 'objectManager' => $this->objectManager, 'customerAccountManagement' => $this->customerAccountManagementMock, + 'cookieManager' => $this->cookieManager, + 'cookieMetadataFactory' => $this->cookieMetadataFactory ] ); } @@ -179,6 +206,22 @@ class LoginTest extends \PHPUnit\Framework\TestCase $this->object->setAccountRedirect($redirectMock); $redirectMock->expects($this->once())->method('getRedirectCookie')->willReturn('some_url1'); + $this->cookieManager->expects($this->once()) + ->method('getCookie') + ->with('mage-cache-sessid') + ->willReturn(true); + $this->cookieMetadataFactory->expects($this->once()) + ->method('createCookieMetadata') + ->willReturn($this->cookieMetadata); + $this->cookieMetadata->expects($this->once()) + ->method('setPath') + ->with('/') + ->willReturnSelf(); + $this->cookieManager->expects($this->once()) + ->method('deleteCookie') + ->with('mage-cache-sessid', $this->cookieMetadata) + ->willReturnSelf(); + $scopeConfigMock = $this->createMock(\Magento\Framework\App\Config\ScopeConfigInterface::class); $this->object->setScopeConfig($scopeConfigMock); $scopeConfigMock->expects($this->once())->method('getValue') diff --git a/app/code/Magento/Directory/Model/Currency.php b/app/code/Magento/Directory/Model/Currency.php index a8df4936b8fae8ba0ece3f90a1efb3e01519fb0c..0b5b836b4ac93933b65c44f9d4447722dabc1c3a 100644 --- a/app/code/Magento/Directory/Model/Currency.php +++ b/app/code/Magento/Directory/Model/Currency.php @@ -6,6 +6,7 @@ namespace Magento\Directory\Model; +use Magento\Framework\App\ObjectManager; use Magento\Framework\Exception\InputException; use Magento\Directory\Model\Currency\Filter; @@ -65,6 +66,11 @@ class Currency extends \Magento\Framework\Model\AbstractModel */ protected $_localeCurrency; + /** + * @var CurrencyConfig + */ + private $currencyConfig; + /** * @param \Magento\Framework\Model\Context $context * @param \Magento\Framework\Registry $registry @@ -76,6 +82,7 @@ class Currency extends \Magento\Framework\Model\AbstractModel * @param \Magento\Framework\Model\ResourceModel\AbstractResource $resource * @param \Magento\Framework\Data\Collection\AbstractDb $resourceCollection * @param array $data + * @param CurrencyConfig $currencyConfig * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ public function __construct( @@ -88,7 +95,8 @@ class Currency extends \Magento\Framework\Model\AbstractModel \Magento\Framework\Locale\CurrencyInterface $localeCurrency, \Magento\Framework\Model\ResourceModel\AbstractResource $resource = null, \Magento\Framework\Data\Collection\AbstractDb $resourceCollection = null, - array $data = [] + array $data = [], + CurrencyConfig $currencyConfig = null ) { parent::__construct( $context, @@ -102,6 +110,7 @@ class Currency extends \Magento\Framework\Model\AbstractModel $this->_directoryHelper = $directoryHelper; $this->_currencyFilterFactory = $currencyFilterFactory; $this->_localeCurrency = $localeCurrency; + $this->currencyConfig = $currencyConfig ?: ObjectManager::getInstance()->get(CurrencyConfig::class); } /** @@ -347,7 +356,7 @@ class Currency extends \Magento\Framework\Model\AbstractModel */ public function getConfigAllowCurrencies() { - $allowedCurrencies = $this->_getResource()->getConfigCurrencies($this, self::XML_PATH_CURRENCY_ALLOW); + $allowedCurrencies = $this->currencyConfig->getConfigCurrencies(self::XML_PATH_CURRENCY_ALLOW); $appBaseCurrencyCode = $this->_directoryHelper->getBaseCurrencyCode(); if (!in_array($appBaseCurrencyCode, $allowedCurrencies)) { $allowedCurrencies[] = $appBaseCurrencyCode; @@ -369,8 +378,7 @@ class Currency extends \Magento\Framework\Model\AbstractModel */ public function getConfigDefaultCurrencies() { - $defaultCurrencies = $this->_getResource()->getConfigCurrencies($this, self::XML_PATH_CURRENCY_DEFAULT); - return $defaultCurrencies; + return $this->currencyConfig->getConfigCurrencies(self::XML_PATH_CURRENCY_DEFAULT); } /** @@ -378,8 +386,7 @@ class Currency extends \Magento\Framework\Model\AbstractModel */ public function getConfigBaseCurrencies() { - $defaultCurrencies = $this->_getResource()->getConfigCurrencies($this, self::XML_PATH_CURRENCY_BASE); - return $defaultCurrencies; + return $this->currencyConfig->getConfigCurrencies(self::XML_PATH_CURRENCY_BASE); } /** diff --git a/app/code/Magento/Directory/Model/CurrencyConfig.php b/app/code/Magento/Directory/Model/CurrencyConfig.php new file mode 100644 index 0000000000000000000000000000000000000000..fdb561c2241706c83daf0b389319c59847ddfe93 --- /dev/null +++ b/app/code/Magento/Directory/Model/CurrencyConfig.php @@ -0,0 +1,99 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Directory\Model; + +use Magento\Framework\App\Area; +use Magento\Framework\App\Config\ScopeConfigInterface; +use Magento\Framework\App\State; +use Magento\Store\Model\ScopeInterface; +use Magento\Store\Model\StoreManagerInterface; + +/** + * Provide config values for allowed, base and default currencies. + */ +class CurrencyConfig +{ + /** + * @var State + */ + private $appState; + + /** + * @var ScopeConfigInterface + */ + private $config; + + /** + * @var StoreManagerInterface + */ + private $storeManager; + + /** + * CurrencyConfig constructor. + * + * @param State $appState + * @param ScopeConfigInterface $config + * @param StoreManagerInterface $storeManager + */ + public function __construct( + State $appState, + ScopeConfigInterface $config, + StoreManagerInterface $storeManager + ) { + $this->appState = $appState; + $this->config = $config; + $this->storeManager = $storeManager; + } + + /** + * Retrieve config currency data by config path. + * + * @param string $path + * @return array + */ + public function getConfigCurrencies(string $path) + { + $result = $this->appState->getAreaCode() === Area::AREA_ADMINHTML + ? $this->getConfigForAllStores($path) + : $this->getConfigForCurrentStore($path); + sort($result); + + return array_unique($result); + } + + /** + * Get allowed, base and default currency codes for all stores. + * + * @param string $path + * @return array + */ + private function getConfigForAllStores(string $path) + { + $storesResult = [[]]; + foreach ($this->storeManager->getStores() as $store) { + $storesResult[] = explode( + ',', + $this->config->getValue($path, ScopeInterface::SCOPE_STORE, $store->getCode()) + ); + } + + return array_merge(...$storesResult); + } + + /** + * Get allowed, base and default currency codes for current store. + * + * @param string $path + * @return mixed + */ + private function getConfigForCurrentStore(string $path) + { + $store = $this->storeManager->getStore(); + + return explode(',', $this->config->getValue($path, ScopeInterface::SCOPE_STORE, $store->getCode())); + } +} diff --git a/app/code/Magento/Directory/Model/ResourceModel/Currency.php b/app/code/Magento/Directory/Model/ResourceModel/Currency.php index ac0716fc4e67e0bc5dc07900fd95104e8a8d56f9..ffbcce11cb4f62a17196d92d240879db52edb626 100644 --- a/app/code/Magento/Directory/Model/ResourceModel/Currency.php +++ b/app/code/Magento/Directory/Model/ResourceModel/Currency.php @@ -165,6 +165,8 @@ class Currency extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb * @param string $path * @return array * @SuppressWarnings(PHPMD.UnusedFormalParameter) + * @deprecated because doesn't take into consideration scopes and system config values. + * @see \Magento\Directory\Model\CurrencyConfig::getConfigCurrencies() */ public function getConfigCurrencies($model, $path) { diff --git a/app/code/Magento/Directory/Test/Unit/Model/CurrencyConfigTest.php b/app/code/Magento/Directory/Test/Unit/Model/CurrencyConfigTest.php new file mode 100644 index 0000000000000000000000000000000000000000..9b52bae26f90fd65298a0cbf6df97dd483eb77b2 --- /dev/null +++ b/app/code/Magento/Directory/Test/Unit/Model/CurrencyConfigTest.php @@ -0,0 +1,127 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Directory\Test\Unit\Model; + +use Magento\Config\App\Config\Type\System; +use Magento\Directory\Model\CurrencyConfig; +use Magento\Framework\App\Area; +use Magento\Framework\App\Config\ScopeConfigInterface; +use Magento\Framework\App\State; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; +use Magento\Store\Api\Data\StoreInterface; +use Magento\Store\Model\StoreManagerInterface; +use PHPUnit\Framework\TestCase; + +/** + * Provide tests for CurrencyConfig model. + */ +class CurrencyConfigTest extends TestCase +{ + /** + * @var CurrencyConfig + */ + private $testSubject; + + /** + * @var System|\PHPUnit_Framework_MockObject_MockObject + */ + private $config; + + /** + * @var StoreManagerInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $storeManager; + + /** + * @var State|\PHPUnit_Framework_MockObject_MockObject + */ + private $appState; + + /** + * @inheritdoc + */ + protected function setUp() + { + $this->config = $this->getMockBuilder(ScopeConfigInterface::class) + ->disableOriginalConstructor() + ->getMock(); + $this->storeManager = $this->getMockBuilder(StoreManagerInterface::class) + ->setMethods(['getStores', 'getWebsites']) + ->disableOriginalConstructor() + ->getMockForAbstractClass(); + $this->appState = $this->getMockBuilder(State::class) + ->disableOriginalConstructor() + ->getMock(); + $objectManager = new ObjectManager($this); + $this->testSubject = $objectManager->getObject( + CurrencyConfig::class, + [ + 'storeManager' => $this->storeManager, + 'appState' => $this->appState, + 'config' => $this->config, + ] + ); + } + + /** + * Test get currency config for admin and storefront areas. + * + * @dataProvider getConfigCurrenciesDataProvider + * @return void + */ + public function testGetConfigCurrencies(string $areCode) + { + $path = 'test/path'; + $expected = ['ARS', 'AUD', 'BZD']; + + $this->appState->expects(self::once()) + ->method('getAreaCode') + ->willReturn($areCode); + + /** @var StoreInterface|\PHPUnit_Framework_MockObject_MockObject $store */ + $store = $this->getMockBuilder(StoreInterface::class) + ->setMethods(['getCode']) + ->disableOriginalConstructor() + ->getMockForAbstractClass(); + $store->expects(self::once()) + ->method('getCode') + ->willReturn('testCode'); + + if ($areCode === Area::AREA_ADMINHTML) { + $this->storeManager->expects(self::once()) + ->method('getStores') + ->willReturn([$store]); + } else { + $this->storeManager->expects(self::once()) + ->method('getStore') + ->willReturn($store); + } + + $this->config->expects(self::once()) + ->method('getValue') + ->with( + self::identicalTo($path) + )->willReturn('ARS,AUD,BZD'); + + $result = $this->testSubject->getConfigCurrencies($path); + + self::assertEquals($expected, $result); + } + + /** + * Provide test data for getConfigCurrencies test. + * + * @return array + */ + public function getConfigCurrenciesDataProvider() + { + return [ + ['areaCode' => Area::AREA_ADMINHTML], + ['areaCode' => Area::AREA_FRONTEND], + ]; + } +} diff --git a/app/code/Magento/Sales/Model/AdminOrder/Create.php b/app/code/Magento/Sales/Model/AdminOrder/Create.php index c2f03ff5d9ac4cafe0356fc8f4455b167882b206..69f4d19e4dd630a45242df8e507de199525602d5 100644 --- a/app/code/Magento/Sales/Model/AdminOrder/Create.php +++ b/app/code/Magento/Sales/Model/AdminOrder/Create.php @@ -10,9 +10,12 @@ namespace Magento\Sales\Model\AdminOrder; use Magento\Customer\Api\AddressMetadataInterface; use Magento\Customer\Model\Metadata\Form as CustomerForm; +use Magento\Framework\Api\ExtensibleDataObjectConverter; use Magento\Framework\App\ObjectManager; use Magento\Quote\Model\Quote\Address; use Magento\Quote\Model\Quote\Item; +use Magento\Sales\Api\Data\OrderAddressInterface; +use Magento\Sales\Model\Order; /** * Order create model @@ -235,6 +238,11 @@ class Create extends \Magento\Framework\DataObject implements \Magento\Checkout\ */ private $serializer; + /** + * @var ExtensibleDataObjectConverter + */ + private $dataObjectConverter; + /** * @param \Magento\Framework\ObjectManagerInterface $objectManager * @param \Magento\Framework\Event\ManagerInterface $eventManager @@ -265,6 +273,7 @@ class Create extends \Magento\Framework\DataObject implements \Magento\Checkout\ * @param \Magento\Quote\Model\QuoteFactory $quoteFactory * @param array $data * @param \Magento\Framework\Serialize\Serializer\Json|null $serializer + * @param ExtensibleDataObjectConverter|null $dataObjectConverter * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ public function __construct( @@ -296,7 +305,8 @@ class Create extends \Magento\Framework\DataObject implements \Magento\Checkout\ \Magento\Sales\Api\OrderManagementInterface $orderManagement, \Magento\Quote\Model\QuoteFactory $quoteFactory, array $data = [], - \Magento\Framework\Serialize\Serializer\Json $serializer = null + \Magento\Framework\Serialize\Serializer\Json $serializer = null, + ExtensibleDataObjectConverter $dataObjectConverter = null ) { $this->_objectManager = $objectManager; $this->_eventManager = $eventManager; @@ -328,6 +338,8 @@ class Create extends \Magento\Framework\DataObject implements \Magento\Checkout\ $this->serializer = $serializer ?: ObjectManager::getInstance() ->get(\Magento\Framework\Serialize\Serializer\Json::class); parent::__construct($data); + $this->dataObjectConverter = $dataObjectConverter ?: ObjectManager::getInstance() + ->get(ExtensibleDataObjectConverter::class); } /** @@ -514,9 +526,7 @@ class Create extends \Magento\Framework\DataObject implements \Magento\Checkout\ $shippingAddress = $order->getShippingAddress(); if ($shippingAddress) { - $addressDiff = array_diff_assoc($shippingAddress->getData(), $order->getBillingAddress()->getData()); - unset($addressDiff['address_type'], $addressDiff['entity_id']); - $shippingAddress->setSameAsBilling(empty($addressDiff)); + $shippingAddress->setSameAsBilling($this->isAddressesAreEqual($order)); } $this->_initBillingAddressFromOrder($order); @@ -2010,4 +2020,26 @@ class Create extends \Magento\Framework\DataObject implements \Magento\Checkout\ return $email; } + + /** + * Checks id shipping and billing addresses are equal. + * + * @param Order $order + * @return bool + */ + private function isAddressesAreEqual(Order $order) + { + $shippingAddress = $order->getShippingAddress(); + $billingAddress = $order->getBillingAddress(); + $shippingData = $this->dataObjectConverter->toFlatArray($shippingAddress, [], OrderAddressInterface::class); + $billingData = $this->dataObjectConverter->toFlatArray($billingAddress, [], OrderAddressInterface::class); + unset( + $shippingData['address_type'], + $shippingData['entity_id'], + $billingData['address_type'], + $billingData['entity_id'] + ); + + return $shippingData == $billingData; + } } diff --git a/app/code/Magento/Sales/Model/Service/CreditmemoService.php b/app/code/Magento/Sales/Model/Service/CreditmemoService.php index 2f08c26de905878219b1c738d10c51be696367df..24f56c0dbd595215956cd9134f4e8ca23ecf194c 100644 --- a/app/code/Magento/Sales/Model/Service/CreditmemoService.php +++ b/app/code/Magento/Sales/Model/Service/CreditmemoService.php @@ -195,7 +195,7 @@ class CreditmemoService implements \Magento\Sales\Api\CreditmemoManagementInterf */ protected function validateForRefund(\Magento\Sales\Api\Data\CreditmemoInterface $creditmemo) { - if ($creditmemo->getId()) { + if ($creditmemo->getId() && $creditmemo->getState() != \Magento\Sales\Model\Order\Creditmemo::STATE_OPEN) { throw new \Magento\Framework\Exception\LocalizedException( __('We cannot register an existing credit memo.') ); diff --git a/app/code/Magento/Sales/Test/Unit/Model/AdminOrder/CreateTest.php b/app/code/Magento/Sales/Test/Unit/Model/AdminOrder/CreateTest.php index a265d39bafd931cbc94ddb7135cab1689cb9d4b7..b284a529d2a150132be62c141eee208997be94c4 100644 --- a/app/code/Magento/Sales/Test/Unit/Model/AdminOrder/CreateTest.php +++ b/app/code/Magento/Sales/Test/Unit/Model/AdminOrder/CreateTest.php @@ -8,8 +8,25 @@ namespace Magento\Sales\Test\Unit\Model\AdminOrder; +use Magento\Backend\Model\Session\Quote as SessionQuote; +use Magento\Customer\Api\Data\AttributeMetadataInterface; +use Magento\Customer\Api\Data\CustomerInterface; +use Magento\Customer\Api\Data\CustomerInterfaceFactory; +use Magento\Customer\Api\Data\GroupInterface; +use Magento\Customer\Api\GroupRepositoryInterface; +use Magento\Customer\Model\Customer\Mapper; +use Magento\Customer\Model\Metadata\Form; +use Magento\Customer\Model\Metadata\FormFactory; +use Magento\Framework\Api\DataObjectHelper; +use Magento\Framework\App\RequestInterface; use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; +use Magento\Quote\Model\Quote; +use Magento\Quote\Model\Quote\Address; +use Magento\Quote\Model\Quote\Item; +use Magento\Quote\Model\Quote\Item\Updater; +use Magento\Sales\Model\AdminOrder\Create; use Magento\Sales\Model\AdminOrder\Product; +use PHPUnit_Framework_MockObject_MockObject as MockObject; /** * @SuppressWarnings(PHPMD.CouplingBetweenObjects) @@ -19,161 +36,74 @@ class CreateTest extends \PHPUnit\Framework\TestCase { const CUSTOMER_ID = 1; - /** @var \Magento\Sales\Model\AdminOrder\Create */ - protected $adminOrderCreate; - - /** @var \Magento\Backend\Model\Session\Quote|\PHPUnit_Framework_MockObject_MockObject */ - protected $sessionQuoteMock; - - /** @var \Magento\Customer\Model\Metadata\FormFactory|\PHPUnit_Framework_MockObject_MockObject */ - protected $formFactoryMock; - - /** @var \Magento\Customer\Api\Data\CustomerInterfaceFactory|\PHPUnit_Framework_MockObject_MockObject */ - protected $customerFactoryMock; - - /** @var \Magento\Quote\Model\Quote\Item\Updater|\PHPUnit_Framework_MockObject_MockObject */ - protected $itemUpdater; - - /** @var \Magento\Customer\Model\Customer\Mapper|\PHPUnit_Framework_MockObject_MockObject */ - protected $customerMapper; - /** - * @var Product\Quote\Initializer|\PHPUnit_Framework_MockObject_MockObject + * @var Create */ - protected $quoteInitializerMock; + private $adminOrderCreate; /** - * @var \Magento\Customer\Api\CustomerRepositoryInterface|\PHPUnit_Framework_MockObject_MockObject + * @var SessionQuote|MockObject */ - protected $customerRepositoryMock; + private $sessionQuote; /** - * @var \Magento\Customer\Api\AddressRepositoryInterface|\PHPUnit_Framework_MockObject_MockObject + * @var FormFactory|MockObject */ - protected $addressRepositoryMock; + private $formFactory; /** - * @var \Magento\Customer\Api\Data\AddressInterfaceFactory|\PHPUnit_Framework_MockObject_MockObject + * @var CustomerInterfaceFactory|MockObject */ - protected $addressFactoryMock; + private $customerFactory; /** - * @var \Magento\Customer\Api\GroupRepositoryInterface|\PHPUnit_Framework_MockObject_MockObject + * @var Updater|MockObject */ - protected $groupRepositoryMock; + private $itemUpdater; /** - * @var \Magento\Framework\App\Config\ScopeConfigInterface|\PHPUnit_Framework_MockObject_MockObject + * @var Mapper|MockObject */ - protected $scopeConfigMock; + private $customerMapper; /** - * @var \Magento\Sales\Model\AdminOrder\EmailSender|\PHPUnit_Framework_MockObject_MockObject + * @var GroupRepositoryInterface|MockObject */ - protected $emailSenderMock; + private $groupRepository; /** - * @var \Magento\Customer\Api\AccountManagementInterface|\PHPUnit_Framework_MockObject_MockObject + * @var DataObjectHelper|MockObject */ - protected $accountManagementMock; + private $dataObjectHelper; - /** - * @var \Magento\Framework\Api\DataObjectHelper|\PHPUnit_Framework_MockObject_MockObject - */ - protected $dataObjectHelper; - - /** - * @var \PHPUnit_Framework_MockObject_MockObject - */ - protected $objectFactory; - - /** - * @SuppressWarnings(PHPMD.ExcessiveMethodLength) - */ protected function setUp() { - $objectManagerMock = $this->createMock(\Magento\Framework\ObjectManagerInterface::class); - $eventManagerMock = $this->createMock(\Magento\Framework\Event\ManagerInterface::class); - $registryMock = $this->createMock(\Magento\Framework\Registry::class); - $configMock = $this->createMock(\Magento\Sales\Model\Config::class); - $this->sessionQuoteMock = $this->createMock(\Magento\Backend\Model\Session\Quote::class); - $loggerMock = $this->createMock(\Psr\Log\LoggerInterface::class); - $copyMock = $this->createMock(\Magento\Framework\DataObject\Copy::class); - $messageManagerMock = $this->createMock(\Magento\Framework\Message\ManagerInterface::class); - $this->formFactoryMock = $this->createPartialMock(\Magento\Customer\Model\Metadata\FormFactory::class, ['create']); - $this->customerFactoryMock = $this->createPartialMock(\Magento\Customer\Api\Data\CustomerInterfaceFactory::class, ['create']); - - $this->itemUpdater = $this->createMock(\Magento\Quote\Model\Quote\Item\Updater::class); - - $this->objectFactory = $this->getMockBuilder(\Magento\Framework\DataObject\Factory::class) + $this->sessionQuote = $this->createMock(SessionQuote::class); + $this->formFactory = $this->createPartialMock(FormFactory::class, ['create']); + $this->customerFactory = $this->createPartialMock(CustomerInterfaceFactory::class, ['create']); + + $this->itemUpdater = $this->createMock(Updater::class); + + $this->customerMapper = $this->getMockBuilder(Mapper::class) + ->setMethods(['toFlatArray']) ->disableOriginalConstructor() - ->setMethods(['create']) ->getMock(); - $this->customerMapper = $this->getMockBuilder( - \Magento\Customer\Model\Customer\Mapper::class - )->setMethods(['toFlatArray'])->disableOriginalConstructor()->getMock(); - - $this->quoteInitializerMock = $this->createMock(\Magento\Sales\Model\AdminOrder\Product\Quote\Initializer::class); - $this->customerRepositoryMock = $this->getMockForAbstractClass( - \Magento\Customer\Api\CustomerRepositoryInterface::class, - [], - '', - false - ); - $this->addressRepositoryMock = $this->getMockForAbstractClass( - \Magento\Customer\Api\AddressRepositoryInterface::class, - [], - '', - false - ); - $this->addressFactoryMock = $this->createMock(\Magento\Customer\Api\Data\AddressInterfaceFactory::class); - $this->groupRepositoryMock = $this->getMockForAbstractClass( - \Magento\Customer\Api\GroupRepositoryInterface::class, - [], - '', - false - ); - $this->scopeConfigMock = $this->getMockForAbstractClass( - \Magento\Framework\App\Config\ScopeConfigInterface::class, - [], - '', - false - ); - $this->emailSenderMock = $this->createMock(\Magento\Sales\Model\AdminOrder\EmailSender::class); - $this->accountManagementMock = $this->getMockForAbstractClass( - \Magento\Customer\Api\AccountManagementInterface::class, - [], - '', - false - ); - $this->dataObjectHelper = $this->getMockBuilder(\Magento\Framework\Api\DataObjectHelper::class) + $this->groupRepository = $this->getMockForAbstractClass(GroupRepositoryInterface::class); + $this->dataObjectHelper = $this->getMockBuilder(DataObjectHelper::class) ->disableOriginalConstructor() ->getMock(); $objectManagerHelper = new ObjectManagerHelper($this); $this->adminOrderCreate = $objectManagerHelper->getObject( - \Magento\Sales\Model\AdminOrder\Create::class, + Create::class, [ - 'objectManager' => $objectManagerMock, - 'eventManager' => $eventManagerMock, - 'coreRegistry' => $registryMock, - 'salesConfig' => $configMock, - 'quoteSession' => $this->sessionQuoteMock, - 'logger' => $loggerMock, - 'objectCopyService' => $copyMock, - 'messageManager' => $messageManagerMock, - 'quoteInitializer' => $this->quoteInitializerMock, - 'customerRepository' => $this->customerRepositoryMock, - 'addressRepository' => $this->addressRepositoryMock, - 'addressFactory' => $this->addressFactoryMock, - 'metadataFormFactory' => $this->formFactoryMock, - 'customerFactory' => $this->customerFactoryMock, - 'groupRepository' => $this->groupRepositoryMock, + 'quoteSession' => $this->sessionQuote, + 'metadataFormFactory' => $this->formFactory, + 'customerFactory' => $this->customerFactory, + 'groupRepository' => $this->groupRepository, 'quoteItemUpdater' => $this->itemUpdater, 'customerMapper' => $this->customerMapper, - 'objectFactory' => $this->objectFactory, - 'accountManagement' => $this->accountManagementMock, 'dataObjectHelper' => $this->dataObjectHelper, ] ); @@ -188,64 +118,60 @@ class CreateTest extends \PHPUnit\Framework\TestCase ]; $attributeMocks = []; - foreach ($attributes as $attribute) { - $attributeMock = $this->createMock(\Magento\Customer\Api\Data\AttributeMetadataInterface::class); + foreach ($attributes as $value) { + $attribute = $this->createMock(AttributeMetadataInterface::class); + $attribute->method('getAttributeCode') + ->willReturn($value[0]); - $attributeMock->expects($this->any())->method('getAttributeCode')->will($this->returnValue($attribute[0])); - - $attributeMocks[] = $attributeMock; + $attributeMocks[] = $attribute; } - $customerGroupMock = $this->getMockForAbstractClass( - \Magento\Customer\Api\Data\GroupInterface::class, - [], - '', - false, - true, - true, - ['getTaxClassId'] - ); - $customerGroupMock->expects($this->once())->method('getTaxClassId')->will($this->returnValue($taxClassId)); - $customerFormMock = $this->createMock(\Magento\Customer\Model\Metadata\Form::class); - $customerFormMock->expects($this->any()) - ->method('getAttributes') - ->will($this->returnValue([$attributeMocks[1]])); - $customerFormMock->expects($this->any())->method('extractData')->will($this->returnValue([])); - $customerFormMock->expects($this->any())->method('restoreData')->will($this->returnValue(['group_id' => 1])); - - $customerFormMock->expects($this->any()) - ->method('prepareRequest') - ->will($this->returnValue($this->createMock(\Magento\Framework\App\RequestInterface::class))); - - $customerMock = $this->createMock(\Magento\Customer\Api\Data\CustomerInterface::class); - $this->customerMapper->expects($this->atLeastOnce()) + $customerGroup = $this->getMockForAbstractClass(GroupInterface::class); + $customerGroup->method('getTaxClassId') + ->willReturn($taxClassId); + $customerForm = $this->createMock(Form::class); + $customerForm->method('getAttributes') + ->willReturn([$attributeMocks[1]]); + $customerForm + ->method('extractData') + ->willReturn([]); + $customerForm + ->method('restoreData') + ->willReturn(['group_id' => 1]); + + $customerForm->method('prepareRequest') + ->willReturn($this->createMock(RequestInterface::class)); + + $customer = $this->createMock(CustomerInterface::class); + $this->customerMapper->expects(self::atLeastOnce()) ->method('toFlatArray') ->willReturn(['group_id' => 1]); - $quoteMock = $this->createMock(\Magento\Quote\Model\Quote::class); - $quoteMock->expects($this->any())->method('getCustomer')->will($this->returnValue($customerMock)); - $quoteMock->expects($this->once()) - ->method('addData') + $quote = $this->createMock(Quote::class); + $quote->method('getCustomer')->willReturn($customer); + $quote->method('addData') ->with( [ 'customer_group_id' => $attributes[1][1], 'customer_tax_class_id' => $taxClassId ] ); - $this->dataObjectHelper->expects($this->once()) - ->method('populateWithArray') + $this->dataObjectHelper->method('populateWithArray') ->with( - $customerMock, - ['group_id' => 1], \Magento\Customer\Api\Data\CustomerInterface::class + $customer, + ['group_id' => 1], CustomerInterface::class ); - $this->formFactoryMock->expects($this->any())->method('create')->will($this->returnValue($customerFormMock)); - $this->sessionQuoteMock->expects($this->any())->method('getQuote')->will($this->returnValue($quoteMock)); - $this->customerFactoryMock->expects($this->any())->method('create')->will($this->returnValue($customerMock)); + $this->formFactory->method('create') + ->willReturn($customerForm); + $this->sessionQuote + ->method('getQuote') + ->willReturn($quote); + $this->customerFactory->method('create') + ->willReturn($customer); - $this->groupRepositoryMock->expects($this->once()) - ->method('getById') - ->will($this->returnValue($customerGroupMock)); + $this->groupRepository->method('getById') + ->willReturn($customerGroup); $this->adminOrderCreate->setAccountData(['group_id' => 1]); } @@ -253,7 +179,7 @@ class CreateTest extends \PHPUnit\Framework\TestCase public function testUpdateQuoteItemsNotArray() { $object = $this->adminOrderCreate->updateQuoteItems('string'); - $this->assertEquals($this->adminOrderCreate, $object); + self::assertEquals($this->adminOrderCreate, $object); } public function testUpdateQuoteItemsEmptyConfiguredOption() @@ -266,22 +192,21 @@ class CreateTest extends \PHPUnit\Framework\TestCase ] ]; - $itemMock = $this->createMock(\Magento\Quote\Model\Quote\Item::class); + $item = $this->createMock(Item::class); - $quoteMock = $this->createMock(\Magento\Quote\Model\Quote::class); - $quoteMock->expects($this->once()) - ->method('getItemById') - ->will($this->returnValue($itemMock)); + $quote = $this->createMock(Quote::class); + $quote->method('getItemById') + ->willReturn($item); - $this->sessionQuoteMock->expects($this->any())->method('getQuote')->will($this->returnValue($quoteMock)); - $this->itemUpdater->expects($this->once()) - ->method('update') - ->with($this->equalTo($itemMock), $this->equalTo($items[1])) - ->will($this->returnSelf()); + $this->sessionQuote->method('getQuote') + ->willReturn($quote); + $this->itemUpdater->method('update') + ->with(self::equalTo($item), self::equalTo($items[1])) + ->willReturnSelf(); $this->adminOrderCreate->setRecollect(false); $object = $this->adminOrderCreate->updateQuoteItems($items); - $this->assertEquals($this->adminOrderCreate, $object); + self::assertEquals($this->adminOrderCreate, $object); } public function testUpdateQuoteItemsWithConfiguredOption() @@ -295,43 +220,50 @@ class CreateTest extends \PHPUnit\Framework\TestCase ] ]; - $itemMock = $this->createMock(\Magento\Quote\Model\Quote\Item::class); - $itemMock->expects($this->once()) - ->method('getQty') - ->will($this->returnValue($qty)); + $item = $this->createMock(Item::class); + $item->method('getQty') + ->willReturn($qty); - $quoteMock = $this->createMock(\Magento\Quote\Model\Quote::class); - $quoteMock->expects($this->once()) - ->method('updateItem') - ->will($this->returnValue($itemMock)); + $quote = $this->createMock(Quote::class); + $quote->method('updateItem') + ->willReturn($item); - $this->sessionQuoteMock->expects($this->any())->method('getQuote')->will($this->returnValue($quoteMock)); + $this->sessionQuote + ->method('getQuote') + ->willReturn($quote); $expectedInfo = $items[1]; $expectedInfo['qty'] = $qty; - $this->itemUpdater->expects($this->once()) - ->method('update') - ->with($this->equalTo($itemMock), $this->equalTo($expectedInfo)); + $this->itemUpdater->method('update') + ->with(self::equalTo($item), self::equalTo($expectedInfo)); $this->adminOrderCreate->setRecollect(false); $object = $this->adminOrderCreate->updateQuoteItems($items); - $this->assertEquals($this->adminOrderCreate, $object); + self::assertEquals($this->adminOrderCreate, $object); } public function testApplyCoupon() { - $couponCode = ''; - $quoteMock = $this->createPartialMock(\Magento\Quote\Model\Quote::class, ['getShippingAddress', 'setCouponCode']); - $this->sessionQuoteMock->expects($this->once())->method('getQuote')->willReturn($quoteMock); - - $addressMock = $this->createPartialMock(\Magento\Quote\Model\Quote\Address::class, ['setCollectShippingRates', 'setFreeShipping']); - $quoteMock->expects($this->exactly(2))->method('getShippingAddress')->willReturn($addressMock); - $quoteMock->expects($this->once())->method('setCouponCode')->with($couponCode)->willReturnSelf(); - - $addressMock->expects($this->once())->method('setCollectShippingRates')->with(true)->willReturnSelf(); - $addressMock->expects($this->once())->method('setFreeShipping')->with(0)->willReturnSelf(); + $couponCode = '123'; + $quote = $this->createPartialMock(Quote::class, ['getShippingAddress', 'setCouponCode']); + $this->sessionQuote->method('getQuote') + ->willReturn($quote); + + $address = $this->createPartialMock(Address::class, ['setCollectShippingRates', 'setFreeShipping']); + $quote->method('getShippingAddress') + ->willReturn($address); + $quote->method('setCouponCode') + ->with($couponCode) + ->willReturnSelf(); + + $address->method('setCollectShippingRates') + ->with(true) + ->willReturnSelf(); + $address->method('setFreeShipping') + ->with(0) + ->willReturnSelf(); $object = $this->adminOrderCreate->applyCoupon($couponCode); - $this->assertEquals($this->adminOrderCreate, $object); + self::assertEquals($this->adminOrderCreate, $object); } } diff --git a/app/code/Magento/Sales/Test/Unit/Model/Service/CreditmemoServiceTest.php b/app/code/Magento/Sales/Test/Unit/Model/Service/CreditmemoServiceTest.php index 9ecab6cf9ab52d76b80d4c195c7e00608db187ec..2e668f0b0d6f114ce3adb6efc14d2292c16b4cd2 100644 --- a/app/code/Magento/Sales/Test/Unit/Model/Service/CreditmemoServiceTest.php +++ b/app/code/Magento/Sales/Test/Unit/Model/Service/CreditmemoServiceTest.php @@ -243,6 +243,78 @@ class CreditmemoServiceTest extends \PHPUnit\Framework\TestCase $this->assertSame($creditMemoMock, $this->creditmemoService->refund($creditMemoMock, true)); } + public function testRefundPendingCreditMemo() + { + $creditMemoMock = $this->getMockBuilder(\Magento\Sales\Api\Data\CreditmemoInterface::class) + ->setMethods(['getId', 'getOrder', 'getState', 'getInvoice']) + ->disableOriginalConstructor() + ->getMockForAbstractClass(); + $creditMemoMock->expects($this->once())->method('getId')->willReturn(444); + $creditMemoMock->expects($this->once())->method('getState') + ->willReturn(\Magento\Sales\Model\Order\Creditmemo::STATE_OPEN); + $orderMock = $this->getMockBuilder(Order::class)->disableOriginalConstructor()->getMock(); + + $creditMemoMock->expects($this->atLeastOnce())->method('getOrder')->willReturn($orderMock); + $orderMock->expects($this->once())->method('getBaseTotalRefunded')->willReturn(0); + $orderMock->expects($this->once())->method('getBaseTotalPaid')->willReturn(10); + $creditMemoMock->expects($this->once())->method('getBaseGrandTotal')->willReturn(10); + + $this->priceCurrencyMock->expects($this->any()) + ->method('round') + ->willReturnArgument(0); + + // Set payment adapter dependency + $refundAdapterMock = $this->getMockBuilder(\Magento\Sales\Model\Order\RefundAdapterInterface::class) + ->disableOriginalConstructor() + ->getMockForAbstractClass(); + $this->objectManagerHelper->setBackwardCompatibleProperty( + $this->creditmemoService, + 'refundAdapter', + $refundAdapterMock + ); + + // Set resource dependency + $resourceMock = $this->getMockBuilder(\Magento\Framework\App\ResourceConnection::class) + ->disableOriginalConstructor() + ->getMock(); + $this->objectManagerHelper->setBackwardCompatibleProperty( + $this->creditmemoService, + 'resource', + $resourceMock + ); + + // Set order repository dependency + $orderRepositoryMock = $this->getMockBuilder(\Magento\Sales\Api\OrderRepositoryInterface::class) + ->disableOriginalConstructor() + ->getMockForAbstractClass(); + $this->objectManagerHelper->setBackwardCompatibleProperty( + $this->creditmemoService, + 'orderRepository', + $orderRepositoryMock + ); + + $adapterMock = $this->getMockBuilder(\Magento\Framework\DB\Adapter\AdapterInterface::class) + ->disableOriginalConstructor() + ->getMockForAbstractClass(); + $resourceMock->expects($this->once())->method('getConnection')->with('sales')->willReturn($adapterMock); + $adapterMock->expects($this->once())->method('beginTransaction'); + $refundAdapterMock->expects($this->once()) + ->method('refund') + ->with($creditMemoMock, $orderMock, false) + ->willReturn($orderMock); + $orderRepositoryMock->expects($this->once()) + ->method('save') + ->with($orderMock); + $creditMemoMock->expects($this->once()) + ->method('getInvoice') + ->willReturn(null); + $adapterMock->expects($this->once())->method('commit'); + $this->creditmemoRepositoryMock->expects($this->once()) + ->method('save'); + + $this->assertSame($creditMemoMock, $this->creditmemoService->refund($creditMemoMock, true)); + } + /** * @expectedExceptionMessage The most money available to refund is 1. * @expectedException \Magento\Framework\Exception\LocalizedException diff --git a/app/code/Magento/Sitemap/Model/Observer.php b/app/code/Magento/Sitemap/Model/Observer.php index 3ae3061310a0b24a76b7bc2c410cc64c156c7ecf..840a6a1858fae5974db7f2e908b13213780dd2c2 100644 --- a/app/code/Magento/Sitemap/Model/Observer.php +++ b/app/code/Magento/Sitemap/Model/Observer.php @@ -113,7 +113,6 @@ class Observer $sitemap->generateXml(); } catch (\Exception $e) { $errors[] = $e->getMessage(); - throw $e; } } @@ -122,8 +121,7 @@ class Observer \Magento\Store\Model\ScopeInterface::SCOPE_STORE ) ) { - $translate = $this->_translateModel->getTranslateInline(); - $this->_translateModel->setTranslateInline(false); + $this->inlineTranslation->suspend(); $this->_transportBuilder->setTemplateIdentifier( $this->_scopeConfig->getValue( diff --git a/app/code/Magento/Sitemap/Test/Unit/Model/ObserverTest.php b/app/code/Magento/Sitemap/Test/Unit/Model/ObserverTest.php index 92e6f4e2e2293d2b6b3e31058732df7d70810cd5..ac88f23ff9d6977f086df62cb84927f027c1eada 100644 --- a/app/code/Magento/Sitemap/Test/Unit/Model/ObserverTest.php +++ b/app/code/Magento/Sitemap/Test/Unit/Model/ObserverTest.php @@ -7,6 +7,10 @@ namespace Magento\Sitemap\Test\Unit\Model; use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; +/** + * Class ObserverTest + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + */ class ObserverTest extends \PHPUnit\Framework\TestCase { /** @@ -96,11 +100,11 @@ class ObserverTest extends \PHPUnit\Framework\TestCase ); } - /** - * @expectedException \Exception - */ - public function testScheduledGenerateSitemapsThrowsException() + public function testScheduledGenerateSitemapsSendsExceptionEmail() { + $exception = 'Sitemap Exception'; + $transport = $this->createMock(\Magento\Framework\Mail\TransportInterface::class); + $this->scopeConfigMock->expects($this->once())->method('isSetFlag')->willReturn(true); $this->collectionFactoryMock->expects($this->once()) @@ -111,7 +115,55 @@ class ObserverTest extends \PHPUnit\Framework\TestCase ->method('getIterator') ->willReturn(new \ArrayIterator([$this->sitemapMock])); - $this->sitemapMock->expects($this->once())->method('generateXml')->willThrowException(new \Exception()); + $this->sitemapMock->expects($this->once()) + ->method('generateXml') + ->willThrowException(new \Exception($exception)); + + $this->scopeConfigMock->expects($this->at(1)) + ->method('getValue') + ->with( + \Magento\Sitemap\Model\Observer::XML_PATH_ERROR_RECIPIENT, + \Magento\Store\Model\ScopeInterface::SCOPE_STORE + ) + ->willReturn('error-recipient@example.com'); + + $this->inlineTranslationMock->expects($this->once()) + ->method('suspend'); + + $this->transportBuilderMock->expects($this->once()) + ->method('setTemplateIdentifier') + ->will($this->returnSelf()); + + $this->transportBuilderMock->expects($this->once()) + ->method('setTemplateOptions') + ->with([ + 'area' => \Magento\Backend\App\Area\FrontNameResolver::AREA_CODE, + 'store' => \Magento\Store\Model\Store::DEFAULT_STORE_ID, + ]) + ->will($this->returnSelf()); + + $this->transportBuilderMock->expects($this->once()) + ->method('setTemplateVars') + ->with(['warnings' => $exception]) + ->will($this->returnSelf()); + + $this->transportBuilderMock->expects($this->once()) + ->method('setFrom') + ->will($this->returnSelf()); + + $this->transportBuilderMock->expects($this->once()) + ->method('addTo') + ->will($this->returnSelf()); + + $this->transportBuilderMock->expects($this->once()) + ->method('getTransport') + ->willReturn($transport); + + $transport->expects($this->once()) + ->method('sendMessage'); + + $this->inlineTranslationMock->expects($this->once()) + ->method('resume'); $this->observer->scheduledGenerateSitemaps(); } diff --git a/app/code/Magento/Tax/Model/Plugin/OrderSave.php b/app/code/Magento/Tax/Model/Plugin/OrderSave.php index 3c87086cdf585b285fbe49fda23912c167851c26..a1a3ebf861d60f9fa4e07dc02714bb59594b2b83 100644 --- a/app/code/Magento/Tax/Model/Plugin/OrderSave.php +++ b/app/code/Magento/Tax/Model/Plugin/OrderSave.php @@ -97,8 +97,12 @@ class OrderSave } else { $percentSum = 0; foreach ($taxRates as $rate) { - $realAmount = $rates['amount'] * $rate['percent'] / $rates['percent']; - $realBaseAmount = $rates['base_amount'] * $rate['percent'] / $rates['percent']; + $percentSum += $rate['percent']; + } + + foreach ($taxRates as $rate) { + $realAmount = $rates['amount'] * $rate['percent'] / $percentSum; + $realBaseAmount = $rates['base_amount'] * $rate['percent'] / $percentSum; $ratesIdQuoteItemId[$rates['id']][] = [ 'id' => $taxesArray['item_id'], 'percent' => $rate['percent'], @@ -110,7 +114,6 @@ class OrderSave 'real_amount' => $realAmount, 'real_base_amount' => $realBaseAmount, ]; - $percentSum += $rate['percent']; } } } diff --git a/app/design/frontend/Magento/luma/Magento_Email/email/footer.html b/app/design/frontend/Magento/luma/Magento_Email/email/footer.html index 994f9e6bffed8dea3f682fdb4d8a92a8aaf3f50d..0fc8e36a8207672e44fb00b63d2d2050665540dc 100644 --- a/app/design/frontend/Magento/luma/Magento_Email/email/footer.html +++ b/app/design/frontend/Magento/luma/Magento_Email/email/footer.html @@ -17,8 +17,16 @@ <table> <tr> <td> - <p><a href="#">{{trans "About Us"}}</a></p> - <p><a href="#">{{trans "Customer Service"}}</a></p> + {{depend url_about_us}} + <p> + {{trans '<a href=%url_about_us>About Us</a>' url_about_us=$url_about_us |raw}} + </p> + {{/depend}} + {{depend url_customer_service}} + <p> + {{trans '<a href=url_customer_service>Customer Service</a>' url_customer_service=$url_customer_service |raw}} + </p> + {{/depend}} </td> <td> {{depend store_phone}} diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/ProductGettersTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/ProductGettersTest.php index 74f640a021284eec3c90254d57fad52cd6483eb4..1ed0057ca2486512a43bed5d0baf4dac1f8cf2d5 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Model/ProductGettersTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/ProductGettersTest.php @@ -5,6 +5,7 @@ */ namespace Magento\Catalog\Model; +use Magento\Catalog\Api\ProductRepositoryInterface; use Magento\Framework\App\Filesystem\DirectoryList; /** @@ -25,11 +26,19 @@ class ProductGettersTest extends \PHPUnit\Framework\TestCase */ protected $_model; + /** + * @var ProductRepositoryInterface + */ + private $productRepository; + protected function setUp() { $this->_model = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create( \Magento\Catalog\Model\Product::class ); + $this->productRepository = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create( + ProductRepositoryInterface::class + ); } public function testGetResourceCollection() @@ -198,6 +207,24 @@ class ProductGettersTest extends \PHPUnit\Framework\TestCase $this->assertEquals('Enabled', $this->_model->getAttributeText('status')); } + /** + * @magentoDataFixture Magento/Catalog/_files/products_with_multiselect_attribute.php + */ + public function testGetAttributeTextArray() + { + $product = $this->productRepository->get('simple_ms_2'); + $product->getAttributeText('multiselect_attribute'); + $expected = [ + 'Option 2', + 'Option 3', + 'Option 4 "!@#$%^&*' + ]; + self::assertEquals( + $expected, + $product->getAttributeText('multiselect_attribute') + ); + } + public function testGetCustomDesignDate() { $this->assertEquals(['from' => null, 'to' => null], $this->_model->getCustomDesignDate()); diff --git a/dev/tests/integration/testsuite/Magento/Directory/Model/CurrencyConfigTest.php b/dev/tests/integration/testsuite/Magento/Directory/Model/CurrencyConfigTest.php new file mode 100644 index 0000000000000000000000000000000000000000..b620d9097b4befcc634d1ad4235129f632c66c5d --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Directory/Model/CurrencyConfigTest.php @@ -0,0 +1,202 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Directory\Model; + +use Magento\Directory\Model\Currency as CurrencyModel; +use Magento\Framework\App\Area; +use Magento\Framework\App\Config\ConfigResource\ConfigInterface; +use Magento\Framework\App\Config\ReinitableConfigInterface; +use Magento\Store\Model\Store; +use Magento\Store\Model\StoreManagerInterface; +use Magento\TestFramework\App\State; +use Magento\TestFramework\Helper\Bootstrap; +use PHPUnit\Framework\TestCase; + +/** + * Provide tests for CurrencyConfig model. + */ +class CurrencyConfigTest extends TestCase +{ + /** + * @var string + */ + private $baseCurrencyPath = 'currency/options/base'; + + /** + * @var string + */ + private $defaultCurrencyPath = 'currency/options/default'; + + /** + * @var string + */ + private $allowedCurrenciesPath = 'currency/options/allow'; + + /** + * @var ConfigInterface + */ + private $config; + + /** + * @var CurrencyModel + */ + private $currency; + + /** + * @inheritdoc + */ + protected function setUp() + { + $this->currency = Bootstrap::getObjectManager()->get(CurrencyModel::class); + $this->config = Bootstrap::getObjectManager()->get(ConfigInterface::class); + } + + /** + * Test get currency config for admin and storefront areas. + * + * @dataProvider getConfigCurrenciesDataProvider + * @magentoDataFixture Magento/Store/_files/store.php + * @magentoDbIsolation disabled + * @param string $areaCode + * @param array $expected + * @return void + */ + public function testGetConfigCurrencies(string $areaCode, array $expected) + { + /** @var State $appState */ + $appState = Bootstrap::getObjectManager()->get(State::class); + $appState->setAreaCode($areaCode); + $store = Bootstrap::getObjectManager()->get(Store::class); + $store->load('test', 'code'); + $this->clearCurrencyConfig(); + $this->setStoreConfig($store->getId()); + $storeManager = Bootstrap::getObjectManager()->get(StoreManagerInterface::class); + $storeManager->setCurrentStore($store->getId()); + + if ($areaCode === Area::AREA_ADMINHTML) { + self::assertEquals($expected['allowed'], $this->currency->getConfigAllowCurrencies()); + self::assertEquals($expected['base'], $this->currency->getConfigBaseCurrencies()); + self::assertEquals($expected['default'], $this->currency->getConfigDefaultCurrencies()); + } else { + /** @var StoreManagerInterface $storeManager */ + $storeManager = Bootstrap::getObjectManager()->get(StoreManagerInterface::class); + foreach ($storeManager->getStores() as $store) { + $storeManager->setCurrentStore($store->getId()); + self::assertEquals( + $expected[$store->getCode()]['allowed'], + $this->currency->getConfigAllowCurrencies() + ); + self::assertEquals( + $expected[$store->getCode()]['base'], + $this->currency->getConfigBaseCurrencies() + ); + self::assertEquals( + $expected[$store->getCode()]['default'], + $this->currency->getConfigDefaultCurrencies() + ); + } + } + } + + /** + * Provide test data for getConfigCurrencies test. + * + * @return array + */ + public function getConfigCurrenciesDataProvider() + { + return [ + [ + 'areaCode' => Area::AREA_ADMINHTML, + 'expected' => [ + 'allowed' => ['BDT', 'BNS', 'BTD', 'EUR', 'USD'], + 'base' => ['BDT', 'USD'], + 'default' => ['BDT', 'USD'], + ], + ], + [ + 'areaCode' => Area::AREA_FRONTEND, + 'expected' => [ + 'default' => [ + 'allowed' => ['EUR', 'USD'], + 'base' => ['USD'], + 'default' => ['USD'], + ], + 'test' => [ + 'allowed' => ['BDT', 'BNS', 'BTD', 'USD'], + 'base' => ['BDT'], + 'default' => ['BDT'], + ], + ], + ], + ]; + } + + /** + * Remove currency config form Db. + * + * @return void + */ + private function clearCurrencyConfig() + { + $storeManager = Bootstrap::getObjectManager()->get(StoreManagerInterface::class); + foreach ($storeManager->getStores() as $store) { + $this->config->deleteConfig( + $this->allowedCurrenciesPath, + 'stores', + $store->getId() + ); + $this->config->deleteConfig( + $this->baseCurrencyPath, + 'stores', + $store->getId() + ); + $this->config->deleteConfig( + $this->defaultCurrencyPath, + 'stores', + $store->getId() + ); + } + } + + /** + * Set allowed, base and default currency config values for given store. + * + * @param string $storeId + * @return void + */ + private function setStoreConfig(string $storeId) + { + $allowedCurrencies = 'BDT,BNS,BTD'; + $baseCurrency = 'BDT'; + $this->config->saveConfig( + $this->baseCurrencyPath, + $baseCurrency, + 'stores', + $storeId + ); + $this->config->saveConfig( + $this->defaultCurrencyPath, + $baseCurrency, + 'stores', + $storeId + ); + $this->config->saveConfig( + $this->allowedCurrenciesPath, + $allowedCurrencies, + 'stores', + $storeId + ); + Bootstrap::getObjectManager()->get(ReinitableConfigInterface::class)->reinit(); + Bootstrap::getObjectManager()->create(StoreManagerInterface::class)->reinitStores(); + } + + protected function tearDown() + { + $this->clearCurrencyConfig(); + } +} diff --git a/dev/tests/integration/testsuite/Magento/Sales/Model/AdminOrder/CreateTest.php b/dev/tests/integration/testsuite/Magento/Sales/Model/AdminOrder/CreateTest.php index ee7ddc1ba1abae57bb4daf4446e7be1f35ac30b3..408cc8d192e3749944dbc7e17b8c1a529a486811 100644 --- a/dev/tests/integration/testsuite/Magento/Sales/Model/AdminOrder/CreateTest.php +++ b/dev/tests/integration/testsuite/Magento/Sales/Model/AdminOrder/CreateTest.php @@ -5,10 +5,20 @@ */ namespace Magento\Sales\Model\AdminOrder; +use Magento\Backend\Model\Session\Quote as SessionQuote; +use Magento\Customer\Api\AddressRepositoryInterface; +use Magento\Customer\Api\CustomerRepositoryInterface; +use Magento\Customer\Model\Customer; +use Magento\Customer\Model\CustomerRegistry; +use Magento\Framework\Message\ManagerInterface; +use Magento\Framework\Registry; +use Magento\Quote\Model\Quote; +use Magento\Sales\Api\Data\OrderAddressExtensionInterface; +use Magento\Sales\Api\Data\OrderAddressExtensionInterfaceFactory; use Magento\Sales\Api\OrderManagementInterface; -use Magento\TestFramework\Helper\Bootstrap; use Magento\Sales\Model\Order; -use Magento\Framework\Registry; +use Magento\TestFramework\Helper\Bootstrap; +use Magento\TestFramework\ObjectManager; /** * @SuppressWarnings(PHPMD.CouplingBetweenObjects) @@ -18,21 +28,25 @@ use Magento\Framework\Registry; class CreateTest extends \PHPUnit\Framework\TestCase { /** - * @var \Magento\Sales\Model\AdminOrder\Create + * @var Create */ - protected $_model; + private $model; - /** @var \Magento\Framework\Message\ManagerInterface */ - protected $_messageManager; + /** + * @var ManagerInterface + */ + private $messageManager; + + /** + * @var ObjectManager + */ + private $objectManager; protected function setUp() { - parent::setUp(); - $this->_messageManager = Bootstrap::getObjectManager()->get(\Magento\Framework\Message\ManagerInterface::class); - $this->_model = Bootstrap::getObjectManager()->create( - \Magento\Sales\Model\AdminOrder\Create::class, - ['messageManager' => $this->_messageManager] - ); + $this->objectManager = Bootstrap::getObjectManager(); + $this->messageManager = $this->objectManager->get(ManagerInterface::class); + $this->model =$this->objectManager->create(Create::class, ['messageManager' => $this->messageManager]); } /** @@ -41,17 +55,15 @@ class CreateTest extends \PHPUnit\Framework\TestCase */ public function testInitFromOrderShippingAddressSameAsBillingWhenEmpty() { - /** @var $order \Magento\Sales\Model\Order */ - $order = Bootstrap::getObjectManager()->create(\Magento\Sales\Model\Order::class); + /** @var $order Order */ + $order = $this->objectManager->create(Order::class); $order->loadByIncrementId('100000001'); - $this->assertNull($order->getShippingAddress()); + self::assertNull($order->getShippingAddress()); - /** @var $objectManager \Magento\TestFramework\ObjectManager */ - $objectManager = Bootstrap::getObjectManager(); - $objectManager->get(\Magento\Framework\Registry::class)->unregister('rule_data'); - $this->_model->initFromOrder($order); + $this->objectManager->get(Registry::class)->unregister('rule_data'); + $this->model->initFromOrder($order); - $this->assertNull($order->getShippingAddress()); + self::assertNull($order->getShippingAddress()); } /** @@ -64,45 +76,45 @@ class CreateTest extends \PHPUnit\Framework\TestCase public function testInitFromOrderAndCreateOrderFromQuoteWithAdditionalOptions() { /** @var $serializer \Magento\Framework\Serialize\Serializer\Json */ - $serializer = Bootstrap::getObjectManager()->create(\Magento\Framework\Serialize\Serializer\Json::class); + $serializer = $this->objectManager->create(\Magento\Framework\Serialize\Serializer\Json::class); - /** @var $order \Magento\Sales\Model\Order */ - $order = Bootstrap::getObjectManager()->create(\Magento\Sales\Model\Order::class); + /** @var $order Order */ + $order = $this->objectManager->create(Order::class); $order->loadByIncrementId('100000001'); /** @var $orderCreate \Magento\Sales\Model\AdminOrder\Create */ - $orderCreate = $this->_model->initFromOrder($order); + $orderCreate = $this->model->initFromOrder($order); $quoteItems = $orderCreate->getQuote()->getItemsCollection(); - $this->assertEquals(1, $quoteItems->count()); + self::assertEquals(1, $quoteItems->count()); $quoteItem = $quoteItems->getFirstItem(); $quoteItemOptions = $quoteItem->getOptionsByCode(); - $this->assertEquals( + self::assertEquals( $serializer->serialize(['additional_option_key' => 'additional_option_value']), $quoteItemOptions['additional_options']->getValue() ); - $session = Bootstrap::getObjectManager()->get(\Magento\Backend\Model\Session\Quote::class); + $session = $this->objectManager->get(SessionQuote::class); $session->setCustomerId(1); - $customer = Bootstrap::getObjectManager()->create(\Magento\Customer\Model\Customer::class); + $customer = $this->objectManager->create(Customer::class); $customer->load(1)->setDefaultBilling(null)->setDefaultShipping(null)->save(); - $rate = Bootstrap::getObjectManager()->create(\Magento\Quote\Model\Quote\Address\Rate::class); + $rate = $this->objectManager->create(Quote\Address\Rate::class); $rate->setCode('freeshipping_freeshipping'); - $this->_model->getQuote()->getShippingAddress()->addShippingRate($rate); - $this->_model->getQuote()->getShippingAddress()->setCountryId('EE'); - $this->_model->setShippingAsBilling(0); - $this->_model->setPaymentData(['method' => 'checkmo']); + $this->model->getQuote()->getShippingAddress()->addShippingRate($rate); + $this->model->getQuote()->getShippingAddress()->setCountryId('EE'); + $this->model->setShippingAsBilling(0); + $this->model->setPaymentData(['method' => 'checkmo']); - $newOrder = $this->_model->createOrder(); + $newOrder = $this->model->createOrder(); $newOrderItems = $newOrder->getItemsCollection(); - $this->assertEquals(1, $newOrderItems->count()); + self::assertEquals(1, $newOrderItems->count()); $order->loadByIncrementId('100000001'); $this->assertEquals($newOrder->getRealOrderId(), $order->getRelationChildRealId()); @@ -110,7 +122,7 @@ class CreateTest extends \PHPUnit\Framework\TestCase $newOrderItem = $newOrderItems->getFirstItem(); - $this->assertEquals( + self::assertEquals( ['additional_option_key' => 'additional_option_value'], $newOrderItem->getProductOptionByCode('additional_options') ); @@ -123,18 +135,28 @@ class CreateTest extends \PHPUnit\Framework\TestCase */ public function testInitFromOrderShippingAddressSameAsBillingWhenSame() { - /** @var $order \Magento\Sales\Model\Order */ - $order = Bootstrap::getObjectManager()->create(\Magento\Sales\Model\Order::class); + /** @var $order Order */ + $order = $this->objectManager->create(Order::class); $order->loadByIncrementId('100000001'); - $this->assertNull($order->getShippingAddress()->getSameAsBilling()); + self::assertNull($order->getShippingAddress()->getSameAsBilling()); + + /** @var OrderAddressExtensionInterface $shippingExtAttributes */ + $shippingExtAttributes = $this->objectManager->get(OrderAddressExtensionInterfaceFactory::class) + ->create(); - /** @var $objectManager \Magento\TestFramework\ObjectManager */ - $objectManager = Bootstrap::getObjectManager(); - $objectManager->get(\Magento\Framework\Registry::class)->unregister('rule_data'); - $this->_model->initFromOrder($order); + $billingExtAttributes = clone $shippingExtAttributes; - $this->assertTrue($order->getShippingAddress()->getSameAsBilling()); + $shippingExtAttributes->setData('tmp', false); + $billingExtAttributes->setData('tmp', true); + + $order->getShippingAddress()->setExtensionAttributes($shippingExtAttributes); + $order->getBillingAddress()->setExtensionAttributes($billingExtAttributes); + + $this->objectManager->get(Registry::class)->unregister('rule_data'); + $this->model->initFromOrder($order); + + self::assertTrue($order->getShippingAddress()->getSameAsBilling()); } /** @@ -144,19 +166,16 @@ class CreateTest extends \PHPUnit\Framework\TestCase */ public function testInitFromOrderShippingAddressSameAsBillingWhenDifferent() { - /** @var $objectManager \Magento\TestFramework\ObjectManager */ - $objectManager = Bootstrap::getObjectManager(); - - /** @var $order \Magento\Sales\Model\Order */ - $order = $objectManager->create(\Magento\Sales\Model\Order::class); + /** @var $order Order */ + $order = $this->objectManager->create(Order::class); $order->loadByIncrementId('100000002'); - $this->assertNull($order->getShippingAddress()->getSameAsBilling()); + self::assertNull($order->getShippingAddress()->getSameAsBilling()); - $objectManager->get(\Magento\Framework\Registry::class)->unregister('rule_data'); - $this->_model->initFromOrder($order); + $this->objectManager->get(Registry::class)->unregister('rule_data'); + $this->model->initFromOrder($order); - $this->assertFalse($order->getShippingAddress()->getSameAsBilling()); + self::assertFalse($order->getShippingAddress()->getSameAsBilling()); } /** @@ -164,26 +183,23 @@ class CreateTest extends \PHPUnit\Framework\TestCase */ public function testInitFromOrderCcInformationDeleted() { - /** @var $objectManager \Magento\TestFramework\ObjectManager */ - $objectManager = Bootstrap::getObjectManager(); - - /** @var $order \Magento\Sales\Model\Order */ - $order = $objectManager->create(\Magento\Sales\Model\Order::class); + /** @var $order Order */ + $order = $this->objectManager->create(Order::class); $order->loadByIncrementId('100000001'); $payment = $order->getPayment(); - $this->assertEquals('5', $payment->getCcExpMonth()); - $this->assertEquals('2016', $payment->getCcExpYear()); - $this->assertEquals('AE', $payment->getCcType()); - $this->assertEquals('0005', $payment->getCcLast4()); - - $objectManager->get(\Magento\Framework\Registry::class)->unregister('rule_data'); - $payment = $this->_model->initFromOrder($order)->getQuote()->getPayment(); - - $this->assertNull($payment->getCcExpMonth()); - $this->assertNull($payment->getCcExpYear()); - $this->assertNull($payment->getCcType()); - $this->assertNull($payment->getCcLast4()); + self::assertEquals('5', $payment->getCcExpMonth()); + self::assertEquals('2016', $payment->getCcExpYear()); + self::assertEquals('AE', $payment->getCcType()); + self::assertEquals('0005', $payment->getCcLast4()); + + $this->objectManager->get(Registry::class)->unregister('rule_data'); + $payment = $this->model->initFromOrder($order)->getQuote()->getPayment(); + + self::assertNull($payment->getCcExpMonth()); + self::assertNull($payment->getCcExpYear()); + self::assertNull($payment->getCcType()); + self::assertNull($payment->getCcLast4()); } /** @@ -191,25 +207,23 @@ class CreateTest extends \PHPUnit\Framework\TestCase */ public function testInitFromOrderWithEmptyPaymentDetails() { - /** @var $objectManager \Magento\TestFramework\ObjectManager */ - $objectManager = Bootstrap::getObjectManager(); - /** @var $order \Magento\Sales\Model\Order */ - $order = $objectManager->create(Order::class); + /** @var $order Order */ + $order = $this->objectManager->create(Order::class); $order->loadByIncrementId('100000001'); - $objectManager->get(Registry::class) + $this->objectManager->get(Registry::class) ->unregister('rule_data'); - $initOrder = $this->_model->initFromOrder($order); + $initOrder = $this->model->initFromOrder($order); $payment = $initOrder->getQuote()->getPayment(); - static::assertEquals($initOrder->getQuote()->getId(), $payment->getData('quote_id')); + self::assertEquals($initOrder->getQuote()->getId(), $payment->getData('quote_id')); $payment->unsetData('quote_id'); - static::assertEmpty($payment->getMethod()); - static::assertEmpty($payment->getAdditionalInformation()); - static::assertEmpty($payment->getAdditionalData()); - static::assertEmpty($payment->getData()); + self::assertEmpty($payment->getMethod()); + self::assertEmpty($payment->getAdditionalInformation()); + self::assertEmpty($payment->getAdditionalData()); + self::assertEmpty($payment->getData()); } /** @@ -217,11 +231,11 @@ class CreateTest extends \PHPUnit\Framework\TestCase */ public function testGetCustomerWishlistNoCustomerId() { - /** @var \Magento\Backend\Model\Session\Quote $session */ - $session = Bootstrap::getObjectManager()->create(\Magento\Backend\Model\Session\Quote::class); + /** @var SessionQuote $session */ + $session = $this->objectManager->create(SessionQuote::class); $session->setCustomerId(null); - $this->assertFalse( - $this->_model->getCustomerWishlist(true), + self::assertFalse( + $this->model->getCustomerWishlist(true), 'If customer ID is not set to session, false is expected to be returned.' ); } @@ -236,24 +250,24 @@ class CreateTest extends \PHPUnit\Framework\TestCase { $customerIdFromFixture = 1; $productIdFromFixture = 1; - /** @var \Magento\Backend\Model\Session\Quote $session */ - $session = Bootstrap::getObjectManager()->create(\Magento\Backend\Model\Session\Quote::class); + /** @var SessionQuote $session */ + $session = $this->objectManager->create(SessionQuote::class); $session->setCustomerId($customerIdFromFixture); /** Test new wishlist creation for the customer specified above */ /** @var \Magento\Wishlist\Model\Wishlist $wishlist */ - $wishlist = $this->_model->getCustomerWishlist(true); - $this->assertInstanceOf( + $wishlist = $this->model->getCustomerWishlist(true); + self::assertInstanceOf( \Magento\Wishlist\Model\Wishlist::class, $wishlist, 'New Wish List is expected to be created if existing Customer does not have one yet.' ); - $this->assertEquals(0, $wishlist->getItemsCount(), 'New Wish List must be empty just after creation.'); + self::assertEquals(0, $wishlist->getItemsCount(), 'New Wish List must be empty just after creation.'); /** Add new item to wishlist and try to get it using getCustomerWishlist once again */ $wishlist->addNewItem($productIdFromFixture)->save(); - $updatedWishlist = $this->_model->getCustomerWishlist(true); - $this->assertEquals( + $updatedWishlist = $this->model->getCustomerWishlist(true); + self::assertEquals( 1, $updatedWishlist->getItemsCount(), 'Wish List must contain a Product which was added to it earlier.' @@ -261,14 +275,14 @@ class CreateTest extends \PHPUnit\Framework\TestCase /** Try to load wishlist from cache in the class after it is deleted from DB */ $wishlist->delete(); - $this->assertSame( + self::assertSame( $updatedWishlist, - $this->_model->getCustomerWishlist(false), + $this->model->getCustomerWishlist(false), 'Wish List cached in class variable is expected to be returned.' ); - $this->assertNotSame( + self::assertNotSame( $updatedWishlist, - $this->_model->getCustomerWishlist(true), + $this->model->getCustomerWishlist(true), 'New Wish List is expected to be created when cache is forced to be refreshed.' ); } @@ -278,12 +292,12 @@ class CreateTest extends \PHPUnit\Framework\TestCase */ public function testSetBillingAddress() { - $addressData = $this->_getValidAddressData(); + $addressData = $this->getValidAddressData(); /** Validate data before creating address object */ - $this->_model->setIsValidate(true)->setBillingAddress($addressData); - $this->assertInstanceOf( - \Magento\Quote\Model\Quote\Address::class, - $this->_model->getBillingAddress(), + $this->model->setIsValidate(true)->setBillingAddress($addressData); + self::assertInstanceOf( + Quote\Address::class, + $this->model->getBillingAddress(), 'Billing address object was not created.' ); @@ -291,7 +305,7 @@ class CreateTest extends \PHPUnit\Framework\TestCase $addressData, [ 'address_type' => 'billing', - 'quote_id' => $this->_model->getQuote()->getId(), + 'quote_id' => $this->model->getQuote()->getId(), 'street' => "Line1\nLine2", 'save_in_address_book' => 0, 'region' => '', @@ -299,10 +313,10 @@ class CreateTest extends \PHPUnit\Framework\TestCase ] ); - $result = $this->_model->getBillingAddress()->getData(); + $result = $this->model->getBillingAddress()->getData(); foreach ($expectedAddressData as $key => $value) { - $this->assertArrayHasKey($key, $result); - $this->assertEquals($value, $result[$key]); + self::assertArrayHasKey($key, $result); + self::assertEquals($value, $result[$key]); } } @@ -314,32 +328,32 @@ class CreateTest extends \PHPUnit\Framework\TestCase public function testSetBillingAddressValidationErrors() { $customerIdFromFixture = 1; - /** @var \Magento\Backend\Model\Session\Quote $session */ - $session = Bootstrap::getObjectManager()->create(\Magento\Backend\Model\Session\Quote::class); + /** @var SessionQuote $session */ + $session = $this->objectManager->create(SessionQuote::class); $session->setCustomerId($customerIdFromFixture); - $invalidAddressData = array_merge($this->_getValidAddressData(), ['firstname' => '', 'lastname' => '']); + $invalidAddressData = array_merge($this->getValidAddressData(), ['firstname' => '', 'lastname' => '']); /** * Note that validation errors are collected during setBillingAddress() call in the internal class variable, * but they are not set to message manager at this step. * They are set to message manager only during createOrder() call. */ - $this->_model->setIsValidate(true)->setBillingAddress($invalidAddressData); + $this->model->setIsValidate(true)->setBillingAddress($invalidAddressData); try { - $this->_model->createOrder(); + $this->model->createOrder(); $this->fail('Validation errors are expected to lead to exception during createOrder() call.'); } catch (\Magento\Framework\Exception\LocalizedException $e) { /** createOrder is expected to throw exception with empty message when validation error occurs */ } $errorMessages = []; /** @var $validationError \Magento\Framework\Message\Error */ - foreach ($this->_messageManager->getMessages()->getItems() as $validationError) { + foreach ($this->messageManager->getMessages()->getItems() as $validationError) { $errorMessages[] = $validationError->getText(); } - $this->assertTrue( + self::assertTrue( in_array('Billing Address: "First Name" is a required value.', $errorMessages), 'Expected validation message is absent.' ); - $this->assertTrue( + self::assertTrue( in_array('Billing Address: "Last Name" is a required value.', $errorMessages), 'Expected validation message is absent.' ); @@ -361,9 +375,9 @@ class CreateTest extends \PHPUnit\Framework\TestCase $orderData = [ 'currency' => 'USD', 'account' => ['group_id' => '1', 'email' => $customerEmail], - 'billing_address' => array_merge($this->_getValidAddressData(), ['save_in_address_book' => '1']), + 'billing_address' => array_merge($this->getValidAddressData(), ['save_in_address_book' => '1']), 'shipping_address' => array_merge( - $this->_getValidAddressData(), + $this->getValidAddressData(), ['save_in_address_book' => '1', 'firstname' => $firstNameForShippingAddress] ), 'shipping_method' => $shippingMethod, @@ -372,7 +386,7 @@ class CreateTest extends \PHPUnit\Framework\TestCase ]; $paymentData = ['method' => $paymentMethod]; - $this->_preparePreconditionsForCreateOrder( + $this->preparePreconditionsForCreateOrder( $productIdFromFixture, $customerEmail, $shippingMethod, @@ -381,12 +395,12 @@ class CreateTest extends \PHPUnit\Framework\TestCase $orderData, $paymentMethod ); - $order = $this->_model->createOrder(); - $this->_verifyCreatedOrder($order, $shippingMethod); - /** @var \Magento\Customer\Model\Customer $customer */ - $customer = Bootstrap::getObjectManager()->create(\Magento\Customer\Model\Customer::class); + $order = $this->model->createOrder(); + $this->verifyCreatedOrder($order, $shippingMethod); + /** @var Customer $customer */ + $customer = $this->objectManager->create(Customer::class); $customer->load($order->getCustomerId()); - $this->assertEquals( + self::assertEquals( $firstNameForShippingAddress, $customer->getPrimaryShippingAddress()->getFirstname(), 'Shipping address is saved incorrectly.' @@ -408,14 +422,14 @@ class CreateTest extends \PHPUnit\Framework\TestCase $orderData = [ 'currency' => 'USD', 'account' => ['group_id' => '1', 'email' => $customerEmail], - 'billing_address' => array_merge($this->_getValidAddressData(), ['save_in_address_book' => '1']), + 'billing_address' => array_merge($this->getValidAddressData(), ['save_in_address_book' => '1']), 'shipping_method' => $shippingMethod, 'comment' => ['customer_note' => ''], 'send_confirmation' => false, ]; $paymentData = ['method' => $paymentMethod]; - $this->_preparePreconditionsForCreateOrder( + $this->preparePreconditionsForCreateOrder( $productIdFromFixture, $customerEmail, $shippingMethod, @@ -424,12 +438,12 @@ class CreateTest extends \PHPUnit\Framework\TestCase $orderData, $paymentMethod ); - $order = $this->_model->createOrder(); + $order = $this->model->createOrder(); //Check, order considering decimal qty in product. foreach ($order->getItems() as $orderItem) { self::assertTrue($orderItem->getIsQtyDecimal()); } - $this->_verifyCreatedOrder($order, $shippingMethod); + $this->verifyCreatedOrder($order, $shippingMethod); } /** @@ -454,14 +468,14 @@ class CreateTest extends \PHPUnit\Framework\TestCase $orderData = [ 'currency' => 'USD', 'account' => ['group_id' => '1', 'email' => $customerEmail], - 'billing_address' => array_merge($this->_getValidAddressData(), ['save_in_address_book' => '1']), + 'billing_address' => array_merge($this->getValidAddressData(), ['save_in_address_book' => '1']), 'shipping_method' => $shippingMethod, 'comment' => ['customer_note' => ''], 'send_confirmation' => false, ]; $paymentData = ['method' => $paymentMethod]; - $this->_preparePreconditionsForCreateOrder( + $this->preparePreconditionsForCreateOrder( $productIdFromFixture, $customerEmail, $shippingMethod, @@ -475,17 +489,17 @@ class CreateTest extends \PHPUnit\Framework\TestCase $orderManagement = $this->getMockForAbstractClass(OrderManagementInterface::class); $orderManagement->method('place') ->willThrowException(new \Exception('Can\'t place order')); - Bootstrap::getObjectManager()->addSharedInstance($orderManagement, OrderManagementInterface::class); + $this->objectManager->addSharedInstance($orderManagement, OrderManagementInterface::class); try { - $this->_model->createOrder(); + $this->model->createOrder(); } catch (\Exception $e) { - Bootstrap::getObjectManager()->removeSharedInstance(OrderManagementInterface::class); + $this->objectManager->removeSharedInstance(OrderManagementInterface::class); } - $customerEmail = $customerEmailSecondAttempt ? :$this->_model->getQuote()->getCustomer()->getEmail(); + $customerEmail = $customerEmailSecondAttempt ? :$this->model->getQuote()->getCustomer()->getEmail(); $orderData['account']['email'] = $customerEmailSecondAttempt; - $this->_preparePreconditionsForCreateOrder( + $this->preparePreconditionsForCreateOrder( $productIdFromFixture, $customerEmail, $shippingMethod, @@ -495,8 +509,8 @@ class CreateTest extends \PHPUnit\Framework\TestCase $paymentMethod ); - $order = $this->_model->createOrder(); - $this->_verifyCreatedOrder($order, $shippingMethod); + $order = $this->model->createOrder(); + $this->verifyCreatedOrder($order, $shippingMethod); } /** @@ -537,9 +551,9 @@ class CreateTest extends \PHPUnit\Framework\TestCase $firstNameForShippingAddress = 'FirstNameForShipping'; $orderData = [ 'currency' => 'USD', - 'billing_address' => array_merge($this->_getValidAddressData(), ['save_in_address_book' => '1']), + 'billing_address' => array_merge($this->getValidAddressData(), ['save_in_address_book' => '1']), 'shipping_address' => array_merge( - $this->_getValidAddressData(), + $this->getValidAddressData(), ['save_in_address_book' => '1', 'firstname' => $firstNameForShippingAddress] ), 'shipping_method' => $shippingMethod, @@ -548,7 +562,7 @@ class CreateTest extends \PHPUnit\Framework\TestCase ]; $paymentData = ['method' => $paymentMethod]; - $this->_preparePreconditionsForCreateOrder( + $this->preparePreconditionsForCreateOrder( $productIdFromFixture, $customerEmailFromFixture, $shippingMethod, @@ -558,12 +572,15 @@ class CreateTest extends \PHPUnit\Framework\TestCase $paymentMethod, $customerIdFromFixture ); - $order = $this->_model->createOrder(); - $this->_verifyCreatedOrder($order, $shippingMethod); - $this->getCustomerRegistry()->remove($order->getCustomerId()); - $customer = $this->getCustomerById($order->getCustomerId()); - $address = $this->getAddressById($customer->getDefaultShipping()); - $this->assertEquals( + $order = $this->model->createOrder(); + $this->verifyCreatedOrder($order, $shippingMethod); + $this->objectManager->get(CustomerRegistry::class) + ->remove($order->getCustomerId()); + $customer = $this->objectManager->get(CustomerRepositoryInterface::class) + ->getById($order->getCustomerId()); + $address = $this->objectManager->get(AddressRepositoryInterface::class) + ->getById($customer->getDefaultShipping()); + self::assertEquals( $firstNameForShippingAddress, $address->getFirstname(), 'Shipping address is saved incorrectly.' @@ -586,14 +603,14 @@ class CreateTest extends \PHPUnit\Framework\TestCase $shippingAddressAsBilling = 1; $orderData = [ 'currency' => 'USD', - 'billing_address' => array_merge($this->_getValidAddressData(), ['save_in_address_book' => '1']), + 'billing_address' => array_merge($this->getValidAddressData(), ['save_in_address_book' => '1']), 'shipping_method' => $shippingMethod, 'comment' => ['customer_note' => ''], 'send_confirmation' => false, ]; $paymentData = ['method' => $paymentMethod]; - $this->_preparePreconditionsForCreateOrder( + $this->preparePreconditionsForCreateOrder( $productIdFromFixture, $customerEmailFromFixture, $shippingMethod, @@ -603,8 +620,8 @@ class CreateTest extends \PHPUnit\Framework\TestCase $paymentMethod, $customerIdFromFixture ); - $order = $this->_model->createOrder(); - $this->_verifyCreatedOrder($order, $shippingMethod); + $order = $this->model->createOrder(); + $this->verifyCreatedOrder($order, $shippingMethod); } /** @@ -617,21 +634,21 @@ class CreateTest extends \PHPUnit\Framework\TestCase $fixtureCustomerId = 1; /** Preconditions */ - /** @var \Magento\Backend\Model\Session\Quote $session */ - $session = Bootstrap::getObjectManager()->create(\Magento\Backend\Model\Session\Quote::class); + /** @var SessionQuote $session */ + $session = $this->objectManager->create(SessionQuote::class); $session->setCustomerId($fixtureCustomerId); - /** @var $quoteFixture \Magento\Quote\Model\Quote */ - $quoteFixture = Bootstrap::getObjectManager()->create(\Magento\Quote\Model\Quote::class); + /** @var $quoteFixture Quote */ + $quoteFixture = $this->objectManager->create(Quote::class); $quoteFixture->load('test01', 'reserved_order_id'); $quoteFixture->setCustomerIsGuest(false)->setCustomerId($fixtureCustomerId)->save(); /** SUT execution */ - $customerQuote = $this->_model->getCustomerCart(); - $this->assertEquals($quoteFixture->getId(), $customerQuote->getId(), 'Quote ID is invalid.'); + $customerQuote = $this->model->getCustomerCart(); + self::assertEquals($quoteFixture->getId(), $customerQuote->getId(), 'Quote ID is invalid.'); /** Try to load quote once again to ensure that caching works correctly */ - $customerQuoteFromCache = $this->_model->getCustomerCart(); - $this->assertSame($customerQuote, $customerQuoteFromCache, 'Customer quote caching does not work correctly.'); + $customerQuoteFromCache = $this->model->getCustomerCart(); + self::assertSame($customerQuote, $customerQuoteFromCache, 'Customer quote caching does not work correctly.'); } /** @@ -644,20 +661,20 @@ class CreateTest extends \PHPUnit\Framework\TestCase $fixtureCustomerId = 1; /** Preconditions */ - /** @var \Magento\Backend\Model\Session\Quote $session */ - $session = Bootstrap::getObjectManager()->create(\Magento\Backend\Model\Session\Quote::class); + /** @var SessionQuote $session */ + $session = $this->objectManager->create(SessionQuote::class); $session->setCustomerId($fixtureCustomerId); - /** @var $quoteFixture \Magento\Quote\Model\Quote */ - $quoteFixture = Bootstrap::getObjectManager()->create(\Magento\Quote\Model\Quote::class); + /** @var $quoteFixture Quote */ + $quoteFixture = $this->objectManager->create(Quote::class); $quoteFixture->load('test01', 'reserved_order_id'); $quoteFixture->setCustomerIsGuest(false)->setCustomerId($fixtureCustomerId)->save(); - $customerQuote = $this->_model->getCustomerCart(); + $customerQuote = $this->model->getCustomerCart(); $item = $customerQuote->getAllVisibleItems()[0]; - $this->_model->moveQuoteItem($item, 'cart', 3); - $this->assertEquals(4, $item->getQty(), 'Number of Qty isn\'t correct for Quote item.'); - $this->assertEquals(3, $item->getQtyToAdd(), 'Number of added qty isn\'t correct for Quote item.'); + $this->model->moveQuoteItem($item, 'cart', 3); + self::assertEquals(4, $item->getQty(), 'Number of Qty isn\'t correct for Quote item.'); + self::assertEquals(3, $item->getQtyToAdd(), 'Number of added qty isn\'t correct for Quote item.'); } /** @@ -671,14 +688,14 @@ class CreateTest extends \PHPUnit\Framework\TestCase $customerEmailFromFixture = 'customer@example.com'; /** Preconditions */ - /** @var \Magento\Backend\Model\Session\Quote $session */ - $session = Bootstrap::getObjectManager()->create(\Magento\Backend\Model\Session\Quote::class); + /** @var SessionQuote $session */ + $session = $this->objectManager->create(SessionQuote::class); $session->setCustomerId($customerIdFromFixture); /** SUT execution */ - $customerQuote = $this->_model->getCustomerCart(); - $this->assertNotEmpty($customerQuote->getId(), 'Quote ID is invalid.'); - $this->assertEquals( + $customerQuote = $this->model->getCustomerCart(); + self::assertNotEmpty($customerQuote->getId(), 'Quote ID is invalid.'); + self::assertEquals( $customerEmailFromFixture, $customerQuote->getCustomerEmail(), 'Customer data is preserved incorrectly in a newly quote.' @@ -697,7 +714,7 @@ class CreateTest extends \PHPUnit\Framework\TestCase * @param string $paymentMethod * @param int|null $customerIdFromFixture */ - protected function _preparePreconditionsForCreateOrder( + private function preparePreconditionsForCreateOrder( $productIdFromFixture, $customerEmail, $shippingMethod, @@ -709,18 +726,18 @@ class CreateTest extends \PHPUnit\Framework\TestCase ) { /** Disable product options */ /** @var \Magento\Catalog\Model\Product $product */ - $product = Bootstrap::getObjectManager()->create(\Magento\Catalog\Model\Product::class); + $product = $this->objectManager->create(\Magento\Catalog\Model\Product::class); $product->load($productIdFromFixture)->setHasOptions(false)->save(); /** Set current customer */ - /** @var \Magento\Backend\Model\Session\Quote $session */ - $session = Bootstrap::getObjectManager()->get(\Magento\Backend\Model\Session\Quote::class); + /** @var SessionQuote $session */ + $session = $this->objectManager->get(SessionQuote::class); if ($customerIdFromFixture !== null) { $session->setCustomerId($customerIdFromFixture); /** Unset fake IDs for default billing and shipping customer addresses */ - /** @var \Magento\Customer\Model\Customer $customer */ - $customer = Bootstrap::getObjectManager()->create(\Magento\Customer\Model\Customer::class); + /** @var Customer $customer */ + $customer = $this->objectManager->create(Customer::class); $customer->load($customerIdFromFixture)->setDefaultBilling(null)->setDefaultShipping(null)->save(); } else { /** @@ -731,48 +748,48 @@ class CreateTest extends \PHPUnit\Framework\TestCase } /** Emulate availability of shipping method (all are disabled by default) */ - /** @var $rate \Magento\Quote\Model\Quote\Address\Rate */ - $rate = Bootstrap::getObjectManager()->create(\Magento\Quote\Model\Quote\Address\Rate::class); + /** @var $rate Quote\Address\Rate */ + $rate = $this->objectManager->create(Quote\Address\Rate::class); $rate->setCode($shippingMethod); - $this->_model->getQuote()->getShippingAddress()->addShippingRate($rate); + $this->model->getQuote()->getShippingAddress()->addShippingRate($rate); - $this->_model->setShippingAsBilling($shippingAddressAsBilling); - $this->_model->addProduct($productIdFromFixture, ['qty' => 1]); - $this->_model->setPaymentData($paymentData); - $this->_model->setIsValidate(true)->importPostData($orderData); + $this->model->setShippingAsBilling($shippingAddressAsBilling); + $this->model->addProduct($productIdFromFixture, ['qty' => 1]); + $this->model->setPaymentData($paymentData); + $this->model->setIsValidate(true)->importPostData($orderData); /** Check preconditions */ - $this->assertEquals( + self::assertEquals( 0, - $this->_messageManager->getMessages()->getCount(), + $this->messageManager->getMessages()->getCount(), "Precondition failed: Errors occurred before SUT execution." ); /** Selectively check quote data */ - $createOrderData = $this->_model->getData(); - $this->assertEquals( + $createOrderData = $this->model->getData(); + self::assertEquals( $shippingMethod, $createOrderData['shipping_method'], 'Precondition failed: Shipping method specified in create order model is invalid' ); - $this->assertEquals( + self::assertEquals( 'FirstName', $createOrderData['billing_address']['firstname'], 'Precondition failed: Address data is invalid in create order model' ); - $this->assertEquals( + self::assertEquals( 'Simple Product', - $this->_model->getQuote()->getItemByProduct($product)->getData('name'), + $this->model->getQuote()->getItemByProduct($product)->getData('name'), 'Precondition failed: Quote items data is invalid in create order model' ); - $this->assertEquals( + self::assertEquals( $customerEmail, - $this->_model->getQuote()->getCustomer()->getEmail(), + $this->model->getQuote()->getCustomer()->getEmail(), 'Precondition failed: Customer data is invalid in create order model' ); - $this->assertEquals( + self::assertEquals( $paymentMethod, - $this->_model->getQuote()->getPayment()->getData('method'), + $this->model->getQuote()->getPayment()->getData('method'), 'Precondition failed: Payment method data is invalid in create order model' ); } @@ -780,26 +797,26 @@ class CreateTest extends \PHPUnit\Framework\TestCase /** * Ensure that order is created correctly via createOrder(). * - * @param \Magento\Sales\Model\Order $order + * @param Order $order * @param string $shippingMethod */ - protected function _verifyCreatedOrder($order, $shippingMethod) + private function verifyCreatedOrder($order, $shippingMethod) { /** Selectively check order data */ $orderData = $order->getData(); - $this->assertNotEmpty($orderData['increment_id'], 'Order increment ID is empty.'); - $this->assertEquals($this->_model->getQuote()->getId(), $orderData['quote_id'], 'Quote ID is invalid.'); - $this->assertEquals( - $this->_model->getQuote()->getCustomer()->getEmail(), + self::assertNotEmpty($orderData['increment_id'], 'Order increment ID is empty.'); + self::assertEquals($this->model->getQuote()->getId(), $orderData['quote_id'], 'Quote ID is invalid.'); + self::assertEquals( + $this->model->getQuote()->getCustomer()->getEmail(), $orderData['customer_email'], 'Customer email is invalid.' ); - $this->assertEquals( - $this->_model->getQuote()->getCustomer()->getFirstname(), + self::assertEquals( + $this->model->getQuote()->getCustomer()->getFirstname(), $orderData['customer_firstname'], 'Customer first name is invalid.' ); - $this->assertEquals($shippingMethod, $orderData['shipping_method'], 'Shipping method is invalid.'); + self::assertEquals($shippingMethod, $orderData['shipping_method'], 'Shipping method is invalid.'); } /** @@ -807,7 +824,7 @@ class CreateTest extends \PHPUnit\Framework\TestCase * * @return array */ - protected function _getValidAddressData() + private function getValidAddressData() { return [ 'prefix' => 'prefix', @@ -829,48 +846,4 @@ class CreateTest extends \PHPUnit\Framework\TestCase 'vat_id' => '' ]; } - - /** - * @param int $id - * @return \Magento\Customer\Api\Data\CustomerInterface - */ - private function getCustomerById($id) - { - return $this->getCustomerRepository()->getById($id); - } - - /** - * @return \Magento\Customer\Api\CustomerRepositoryInterface - */ - private function getCustomerRepository() - { - return Bootstrap::getObjectManager()->create(\Magento\Customer\Api\CustomerRepositoryInterface::class); - } - - /** - * @param int $id - * @return \Magento\Customer\Api\Data\AddressInterface - */ - private function getAddressById($id) - { - return $this->getAddressRepository()->getById($id); - } - - /** - * @return \Magento\Customer\Api\AddressRepositoryInterface - */ - private function getAddressRepository() - { - /** @var \Magento\Customer\Api\AddressRepositoryInterface $addressRepository */ - return Bootstrap::getObjectManager()->create(\Magento\Customer\Api\AddressRepositoryInterface::class); - } - - /** - * @return \Magento\Customer\Model\CustomerRegistry - */ - private function getCustomerRegistry() - { - /** @var \Magento\Customer\Model\CustomerRegistry $addressRepository */ - return Bootstrap::getObjectManager()->get(\Magento\Customer\Model\CustomerRegistry::class); - } } diff --git a/lib/internal/Magento/Framework/Data/Form/Filter/Date.php b/lib/internal/Magento/Framework/Data/Form/Filter/Date.php index 8765e136e2897a6da3dacb3fafefbb492180681c..864c0f3e27e6912c52f558f59bbbbce02a6b6f70 100644 --- a/lib/internal/Magento/Framework/Data/Form/Filter/Date.php +++ b/lib/internal/Magento/Framework/Data/Form/Filter/Date.php @@ -54,6 +54,10 @@ class Date implements \Magento\Framework\Data\Form\Filter\FilterInterface */ public function inputFilter($value) { + if (!$value) { + return $value; + } + $filterInput = new \Zend_Filter_LocalizedToNormalized( ['date_format' => $this->_dateFormat, 'locale' => $this->localeResolver->getLocale()] ); @@ -74,6 +78,10 @@ class Date implements \Magento\Framework\Data\Form\Filter\FilterInterface */ public function outputFilter($value) { + if (!$value) { + return $value; + } + $filterInput = new \Zend_Filter_LocalizedToNormalized( ['date_format' => DateTime::DATE_INTERNAL_FORMAT, 'locale' => $this->localeResolver->getLocale()] );