diff --git a/app/code/Magento/Signifyd/Block/Fingerprint.php b/app/code/Magento/Signifyd/Block/Fingerprint.php
index db76fc6c94468..f43bffce1fc1a 100644
--- a/app/code/Magento/Signifyd/Block/Fingerprint.php
+++ b/app/code/Magento/Signifyd/Block/Fingerprint.php
@@ -42,7 +42,7 @@ class Fingerprint extends Template
* @var string
* @since 100.2.0
*/
- protected $_template = 'fingerprint.phtml';
+ protected $_template = 'Magento_Signifyd::fingerprint.phtml';
/**
* @param Context $context
diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Shipping/LICENSE.txt b/app/code/Magento/Signifyd/Test/Mftf/LICENSE.txt
similarity index 100%
rename from dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Shipping/LICENSE.txt
rename to app/code/Magento/Signifyd/Test/Mftf/LICENSE.txt
diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Shipping/LICENSE_AFL.txt b/app/code/Magento/Signifyd/Test/Mftf/LICENSE_AFL.txt
similarity index 100%
rename from dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Shipping/LICENSE_AFL.txt
rename to app/code/Magento/Signifyd/Test/Mftf/LICENSE_AFL.txt
diff --git a/app/code/Magento/Signifyd/Test/Mftf/README.md b/app/code/Magento/Signifyd/Test/Mftf/README.md
new file mode 100644
index 0000000000000..9391d7b314ea5
--- /dev/null
+++ b/app/code/Magento/Signifyd/Test/Mftf/README.md
@@ -0,0 +1,3 @@
+# Signifyd Functional Tests
+
+The Functional Test Module for **Magento Signifyd** module.
diff --git a/app/code/Magento/Signifyd/Test/Mftf/composer.json b/app/code/Magento/Signifyd/Test/Mftf/composer.json
new file mode 100644
index 0000000000000..dde4d64ed7af3
--- /dev/null
+++ b/app/code/Magento/Signifyd/Test/Mftf/composer.json
@@ -0,0 +1,26 @@
+{
+ "name": "magento/functional-test-module-signifyd",
+ "description": "Submitting Case Entry to Signifyd on Order Creation",
+ "config": {
+ "sort-packages": true
+ },
+ "require": {
+ "php": "~7.0.13|~7.1.0",
+ "magento/functional-test-module-config": "100.0.0-dev",
+ "magento/magento2-functional-testing-framework": "2.2.0",
+ "magento/functional-test-module-sales": "100.0.0-dev",
+ "magento/functional-test-module-store": "100.0.0-dev",
+ "magento/functional-test-module-customer": "100.0.0-dev",
+ "magento/functional-test-module-directory": "100.0.0-dev",
+ "magento/functional-test-module-checkout": "100.0.0-dev",
+ "magento/functional-test-module-backend": "100.0.0-dev",
+ "magento/functional-test-module-payment": "100.0.0-dev"
+ },
+ "suggest": {
+ "magento/functional-test-module-config": "100.0.0-dev"
+ },
+ "type": "magento2-test",
+ "license": [
+ "proprietary"
+ ]
+}
diff --git a/app/code/Magento/Signifyd/Test/Unit/Controller/Webhooks/HandlerTest.php b/app/code/Magento/Signifyd/Test/Unit/Controller/Webhooks/HandlerTest.php
index 1a8cfdc703247..8b98be338b973 100644
--- a/app/code/Magento/Signifyd/Test/Unit/Controller/Webhooks/HandlerTest.php
+++ b/app/code/Magento/Signifyd/Test/Unit/Controller/Webhooks/HandlerTest.php
@@ -140,7 +140,7 @@ protected function setUp()
}
/**
- * Successfull case
+ * Successful case
*/
public function testExecuteSuccessfully()
{
diff --git a/app/code/Magento/Signifyd/Test/Unit/Model/Guarantee/CreateGuaranteeAbilityTest.php b/app/code/Magento/Signifyd/Test/Unit/Model/Guarantee/CreateGuaranteeAbilityTest.php
index 7ba3ab3eef4f6..6b7a6112a932e 100644
--- a/app/code/Magento/Signifyd/Test/Unit/Model/Guarantee/CreateGuaranteeAbilityTest.php
+++ b/app/code/Magento/Signifyd/Test/Unit/Model/Guarantee/CreateGuaranteeAbilityTest.php
@@ -198,6 +198,9 @@ public function testIsAvailableWithCanceledOrder($state)
$this->assertFalse($this->createGuaranteeAbility->isAvailable($orderId));
}
+ /**
+ * @return array
+ */
public function isAvailableWithCanceledOrderDataProvider()
{
return [
diff --git a/app/code/Magento/Signifyd/Test/Unit/Model/Guarantee/CreationServiceTest.php b/app/code/Magento/Signifyd/Test/Unit/Model/Guarantee/CreationServiceTest.php
index a22bfe12222a6..f80a9a83e7117 100644
--- a/app/code/Magento/Signifyd/Test/Unit/Model/Guarantee/CreationServiceTest.php
+++ b/app/code/Magento/Signifyd/Test/Unit/Model/Guarantee/CreationServiceTest.php
@@ -203,6 +203,12 @@ public function testCreateForOrderWithCaseUpdate()
);
}
+ /**
+ * @param $orderId
+ * @param array $caseData
+ *
+ * @return MockObject
+ */
private function withCaseEntityExistsForOrderId($orderId, array $caseData = [])
{
$this->createGuaranteeAbility->expects(self::once())
@@ -226,6 +232,9 @@ private function withCaseEntityExistsForOrderId($orderId, array $caseData = [])
return $dummyCaseEntity;
}
+ /**
+ * @param $failureMessage
+ */
private function withGatewayFailure($failureMessage)
{
$this->gateway
@@ -233,6 +242,9 @@ private function withGatewayFailure($failureMessage)
->willThrowException(new GatewayException($failureMessage));
}
+ /**
+ * @param $gatewayResult
+ */
private function withGatewaySuccess($gatewayResult)
{
$this->gateway
diff --git a/app/code/Magento/Signifyd/Test/Unit/Model/SignifydGateway/Client/ResponseHandlerTest.php b/app/code/Magento/Signifyd/Test/Unit/Model/SignifydGateway/Client/ResponseHandlerTest.php
index bf0c6ee238d5f..1ee55d7ad150c 100644
--- a/app/code/Magento/Signifyd/Test/Unit/Model/SignifydGateway/Client/ResponseHandlerTest.php
+++ b/app/code/Magento/Signifyd/Test/Unit/Model/SignifydGateway/Client/ResponseHandlerTest.php
@@ -92,6 +92,9 @@ public function testHandleFailureMessage($code, $message)
}
}
+ /**
+ * @return array
+ */
public function errorsProvider()
{
return [
diff --git a/app/code/Magento/Signifyd/Test/Unit/Model/SignifydGateway/GatewayTest.php b/app/code/Magento/Signifyd/Test/Unit/Model/SignifydGateway/GatewayTest.php
index 0039b271a4b0b..ce97a7baaeace 100644
--- a/app/code/Magento/Signifyd/Test/Unit/Model/SignifydGateway/GatewayTest.php
+++ b/app/code/Magento/Signifyd/Test/Unit/Model/SignifydGateway/GatewayTest.php
@@ -393,6 +393,9 @@ public function testCancelGuaranteeWithUnexpectedDisposition()
$this->assertEquals(Gateway::GUARANTEE_CANCELED, $result);
}
+ /**
+ * @return array
+ */
public function supportedGuaranteeDispositionsProvider()
{
return [
diff --git a/app/code/Magento/Signifyd/composer.json b/app/code/Magento/Signifyd/composer.json
index 461988f0c5bc7..cded060a54518 100644
--- a/app/code/Magento/Signifyd/composer.json
+++ b/app/code/Magento/Signifyd/composer.json
@@ -17,7 +17,7 @@
"magento/module-config": "101.0.*"
},
"type": "magento2-module",
- "version": "100.2.1",
+ "version": "100.2.2",
"license": [
"proprietary"
],
diff --git a/app/code/Magento/Signifyd/etc/adminhtml/system.xml b/app/code/Magento/Signifyd/etc/adminhtml/system.xml
index 71f5916ca5325..2dd75d2d91e5b 100644
--- a/app/code/Magento/Signifyd/etc/adminhtml/system.xml
+++ b/app/code/Magento/Signifyd/etc/adminhtml/system.xml
@@ -11,7 +11,7 @@
Fraud Protection
sales
Magento_Sales::fraud_protection
-
+
signifyd-logo-header
Magento\Signifyd\Block\Adminhtml\System\Config\Fieldset\Info
@@ -52,7 +52,7 @@
Magento\Config\Model\Config\Source\Yesno
fraud_protection/signifyd/debug
-
+
Webhook URL
configure a guarantee completed webhook in Signifyd. Webhooks are used to sync Signifyd`s guarantee decisions back to Magento.]]>
signifyd/webhooks/handler
diff --git a/app/code/Magento/Sitemap/Controller/Adminhtml/Sitemap/Generate.php b/app/code/Magento/Sitemap/Controller/Adminhtml/Sitemap/Generate.php
index 67d2ce4f4f148..d19b248c8008f 100644
--- a/app/code/Magento/Sitemap/Controller/Adminhtml/Sitemap/Generate.php
+++ b/app/code/Magento/Sitemap/Controller/Adminhtml/Sitemap/Generate.php
@@ -6,8 +6,29 @@
*/
namespace Magento\Sitemap\Controller\Adminhtml\Sitemap;
+use Magento\Backend\App\Action;
+use Magento\Store\Model\App\Emulation;
+use Magento\Framework\App\ObjectManager;
+
class Generate extends \Magento\Sitemap\Controller\Adminhtml\Sitemap
{
+ /** @var \Magento\Store\Model\App\Emulation $appEmulation */
+ private $appEmulation;
+
+ /**
+ * Generate constructor.
+ * @param Action\Context $context
+ * @param \Magento\Store\Model\App\Emulation|null $appEmulation
+ */
+ public function __construct(
+ Action\Context $context,
+ Emulation $appEmulation = null
+ ) {
+ parent::__construct($context);
+ $this->appEmulation = $appEmulation ?: ObjectManager::getInstance()
+ ->get(\Magento\Store\Model\App\Emulation::class);
+ }
+
/**
* Generate sitemap
*
@@ -23,6 +44,12 @@ public function execute()
// if sitemap record exists
if ($sitemap->getId()) {
try {
+ //We need to emulate to get the correct frontend URL for the product images
+ $this->appEmulation->startEnvironmentEmulation(
+ $sitemap->getStoreId(),
+ \Magento\Framework\App\Area::AREA_FRONTEND,
+ true
+ );
$sitemap->generateXml();
$this->messageManager->addSuccess(
@@ -32,6 +59,8 @@ public function execute()
$this->messageManager->addError($e->getMessage());
} catch (\Exception $e) {
$this->messageManager->addException($e, __('We can\'t generate the sitemap right now.'));
+ } finally {
+ $this->appEmulation->stopEnvironmentEmulation();
}
} else {
$this->messageManager->addError(__('We can\'t find a sitemap to generate.'));
diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Sitemap/LICENSE.txt b/app/code/Magento/Sitemap/Test/Mftf/LICENSE.txt
similarity index 100%
rename from dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Sitemap/LICENSE.txt
rename to app/code/Magento/Sitemap/Test/Mftf/LICENSE.txt
diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Sitemap/LICENSE_AFL.txt b/app/code/Magento/Sitemap/Test/Mftf/LICENSE_AFL.txt
similarity index 100%
rename from dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Sitemap/LICENSE_AFL.txt
rename to app/code/Magento/Sitemap/Test/Mftf/LICENSE_AFL.txt
diff --git a/app/code/Magento/Sitemap/Test/Mftf/README.md b/app/code/Magento/Sitemap/Test/Mftf/README.md
new file mode 100644
index 0000000000000..8d506744827f6
--- /dev/null
+++ b/app/code/Magento/Sitemap/Test/Mftf/README.md
@@ -0,0 +1,3 @@
+# Sitemap Functional Tests
+
+The Functional Test Module for **Magento Sitemap** module.
diff --git a/app/code/Magento/Sitemap/Test/Mftf/composer.json b/app/code/Magento/Sitemap/Test/Mftf/composer.json
new file mode 100644
index 0000000000000..046761ba34e80
--- /dev/null
+++ b/app/code/Magento/Sitemap/Test/Mftf/composer.json
@@ -0,0 +1,28 @@
+{
+ "name": "magento/functional-test-module-sitemap",
+ "description": "N/A",
+ "config": {
+ "sort-packages": true
+ },
+ "require": {
+ "php": "~7.0.13|~7.1.0",
+ "magento/functional-test-module-store": "100.0.0-dev",
+ "magento/functional-test-module-catalog": "100.0.0-dev",
+ "magento/functional-test-module-eav": "100.0.0-dev",
+ "magento/functional-test-module-cms": "100.0.0-dev",
+ "magento/functional-test-module-backend": "100.0.0-dev",
+ "magento/functional-test-module-catalog-url-rewrite": "100.0.0-dev",
+ "magento/functional-test-module-media-storage": "100.0.0-dev",
+ "magento/magento2-functional-testing-framework": "2.2.0",
+ "magento/functional-test-module-config": "100.0.0-dev",
+ "magento/functional-test-module-robots": "100.0.0-dev"
+ },
+ "suggest": {
+ "magento/functional-test-module-config": "100.0.0-dev"
+ },
+ "type": "magento2-test",
+ "license": [
+ "OSL-3.0",
+ "AFL-3.0"
+ ]
+}
diff --git a/app/code/Magento/Sitemap/composer.json b/app/code/Magento/Sitemap/composer.json
index b33d2d319242f..08fa3badf78e2 100644
--- a/app/code/Magento/Sitemap/composer.json
+++ b/app/code/Magento/Sitemap/composer.json
@@ -18,7 +18,7 @@
"magento/module-config": "101.0.*"
},
"type": "magento2-module",
- "version": "100.2.3",
+ "version": "100.2.4",
"license": [
"OSL-3.0",
"AFL-3.0"
diff --git a/app/code/Magento/Store/App/Action/Plugin/Context.php b/app/code/Magento/Store/App/Action/Plugin/Context.php
index 133bc9c4fa004..6887c43fa9737 100644
--- a/app/code/Magento/Store/App/Action/Plugin/Context.php
+++ b/app/code/Magento/Store/App/Action/Plugin/Context.php
@@ -131,14 +131,14 @@ private function processInvalidStoreRequested(
*/
private function updateContext(StoreInterface $store)
{
+ /** @var StoreInterface $defaultStore */
+ $defaultStore = $this->storeManager->getWebsite()->getDefaultStore();
$this->httpContext->setValue(
StoreManagerInterface::CONTEXT_STORE,
$store->getCode(),
- $this->storeManager->getDefaultStoreView()->getCode()
+ $defaultStore->getCode()
);
- /** @var StoreInterface $defaultStore */
- $defaultStore = $this->storeManager->getWebsite()->getDefaultStore();
$this->httpContext->setValue(
HttpContext::CONTEXT_CURRENCY,
$this->session->getCurrencyCode()
diff --git a/app/code/Magento/Store/App/Config/Type/Scopes.php b/app/code/Magento/Store/App/Config/Type/Scopes.php
index 9fbecc4db303e..e6b9d0000e4a6 100644
--- a/app/code/Magento/Store/App/Config/Type/Scopes.php
+++ b/app/code/Magento/Store/App/Config/Type/Scopes.php
@@ -114,5 +114,6 @@ private function convertIdPathToCodePath(array $patchChunks)
public function clean()
{
$this->data = null;
+ $this->idCodeMap = [];
}
}
diff --git a/app/code/Magento/Store/App/Response/Redirect.php b/app/code/Magento/Store/App/Response/Redirect.php
index d826ad3425f54..9c0da1a7a7adf 100644
--- a/app/code/Magento/Store/App/Response/Redirect.php
+++ b/app/code/Magento/Store/App/Response/Redirect.php
@@ -81,17 +81,16 @@ public function __construct(
protected function _getUrl()
{
$refererUrl = $this->_request->getServer('HTTP_REFERER');
- $url = (string)$this->_request->getParam(self::PARAM_NAME_REFERER_URL);
- if ($url) {
- $refererUrl = $url;
- }
- $url = $this->_request->getParam(\Magento\Framework\App\ActionInterface::PARAM_NAME_BASE64_URL);
- if ($url) {
- $refererUrl = $this->_urlCoder->decode($url);
- }
- $url = $this->_request->getParam(\Magento\Framework\App\ActionInterface::PARAM_NAME_URL_ENCODED);
- if ($url) {
- $refererUrl = $this->_urlCoder->decode($url);
+ $encodedUrl = $this->_request->getParam(\Magento\Framework\App\ActionInterface::PARAM_NAME_URL_ENCODED)
+ ?: $this->_request->getParam(\Magento\Framework\App\ActionInterface::PARAM_NAME_BASE64_URL);
+
+ if ($encodedUrl) {
+ $refererUrl = $this->_urlCoder->decode($encodedUrl);
+ } else {
+ $url = (string)$this->_request->getParam(self::PARAM_NAME_REFERER_URL);
+ if ($url) {
+ $refererUrl = $url;
+ }
}
if (!$this->_isUrlInternal($refererUrl)) {
@@ -171,16 +170,6 @@ public function success($defaultUrl)
*/
public function updatePathParams(array $arguments)
{
- if ($this->_session->getCookieShouldBeReceived()
- && $this->_sidResolver->getUseSessionInUrl()
- && $this->_canUseSessionIdInParam
- ) {
- $arguments += [
- '_query' => [
- $this->_sidResolver->getSessionIdQueryParam($this->_session) => $this->_session->getSessionId(),
- ]
- ];
- }
return $arguments;
}
diff --git a/app/code/Magento/Store/Block/Switcher.php b/app/code/Magento/Store/Block/Switcher.php
index 3d8d46983b5aa..2c437fb3577df 100644
--- a/app/code/Magento/Store/Block/Switcher.php
+++ b/app/code/Magento/Store/Block/Switcher.php
@@ -10,7 +10,10 @@
namespace Magento\Store\Block;
use Magento\Directory\Helper\Data;
+use Magento\Framework\App\ActionInterface;
+use Magento\Framework\App\ObjectManager;
use Magento\Store\Model\Group;
+use Magento\Framework\Url\Helper\Data as UrlHelper;
/**
* @api
@@ -28,20 +31,28 @@ class Switcher extends \Magento\Framework\View\Element\Template
*/
protected $_postDataHelper;
+ /**
+ * @var UrlHelper
+ */
+ private $urlHelper;
+
/**
* Constructs
*
* @param \Magento\Framework\View\Element\Template\Context $context
* @param \Magento\Framework\Data\Helper\PostHelper $postDataHelper
* @param array $data
+ * @param UrlHelper $urlHelper
*/
public function __construct(
\Magento\Framework\View\Element\Template\Context $context,
\Magento\Framework\Data\Helper\PostHelper $postDataHelper,
- array $data = []
+ array $data = [],
+ UrlHelper $urlHelper = null
) {
$this->_postDataHelper = $postDataHelper;
parent::__construct($context, $data);
+ $this->urlHelper = $urlHelper ?: ObjectManager::getInstance()->get(UrlHelper::class);
}
/**
@@ -220,15 +231,20 @@ public function getStoreName()
* @param \Magento\Store\Model\Store $store
* @param array $data
* @return string
+ * @throws \Magento\Framework\Exception\NoSuchEntityException
*/
public function getTargetStorePostData(\Magento\Store\Model\Store $store, $data = [])
{
- $data[\Magento\Store\Api\StoreResolverInterface::PARAM_NAME]
- = $store->getCode();
- //We need to fromStore as true because it will enable proper URL
- //rewriting during store switching.
+ $data[\Magento\Store\Api\StoreResolverInterface::PARAM_NAME] = $store->getCode();
+ $data['___from_store'] = $this->_storeManager->getStore()->getCode();
+
+ $urlOnTargetStore = $store->getCurrentUrl(false);
+ $data[ActionInterface::PARAM_NAME_URL_ENCODED] = $this->urlHelper->getEncodedUrl($urlOnTargetStore);
+
+ $url = $this->getUrl('stores/store/redirect');
+
return $this->_postDataHelper->getPostData(
- $store->getCurrentUrl(true),
+ $url,
$data
);
}
diff --git a/app/code/Magento/Store/Controller/Store/Redirect.php b/app/code/Magento/Store/Controller/Store/Redirect.php
new file mode 100644
index 0000000000000..04714b17a0cc0
--- /dev/null
+++ b/app/code/Magento/Store/Controller/Store/Redirect.php
@@ -0,0 +1,113 @@
+storeRepository = $storeRepository;
+ $this->storeResolver = $storeResolver;
+ $this->session = $session;
+ $this->sidResolver = $sidResolver;
+ }
+
+ /**
+ * @return ResponseInterface|\Magento\Framework\Controller\ResultInterface
+ * @throws NoSuchEntityException
+ */
+ public function execute()
+ {
+ /** @var \Magento\Store\Model\Store $currentStore */
+ $currentStore = $this->storeRepository->getById($this->storeResolver->getCurrentStoreId());
+ $targetStoreCode = $this->_request->getParam(StoreResolver::PARAM_NAME);
+ $fromStoreCode = $this->_request->getParam('___from_store');
+ $error = null;
+
+ if ($targetStoreCode === null) {
+ return $this->_redirect($currentStore->getBaseUrl());
+ }
+
+ try {
+ /** @var \Magento\Store\Model\Store $targetStore */
+ $fromStore = $this->storeRepository->get($fromStoreCode);
+ } catch (NoSuchEntityException $e) {
+ $error = __('Requested store is not found');
+ }
+
+ if ($error !== null) {
+ $this->messageManager->addErrorMessage($error);
+ $this->_redirect->redirect($this->_response, $currentStore->getBaseUrl());
+ } else {
+ $encodedUrl = $this->_request->getParam(\Magento\Framework\App\ActionInterface::PARAM_NAME_URL_ENCODED);
+
+ $query = [
+ '___from_store' => $fromStore->getCode(),
+ StoreResolverInterface::PARAM_NAME => $targetStoreCode,
+ \Magento\Framework\App\ActionInterface::PARAM_NAME_URL_ENCODED => $encodedUrl,
+ ];
+
+ if ($this->sidResolver->getUseSessionInUrl()) {
+ // allow customers to stay logged in during store switching
+ $sidName = $this->sidResolver->getSessionIdQueryParam($this->session);
+ $query[$sidName] = $this->session->getSessionId();
+ }
+
+ $arguments = [
+ '_nosid' => true,
+ '_query' => $query
+ ];
+ $this->_redirect->redirect($this->_response, 'stores/store/switch', $arguments);
+ }
+ }
+}
diff --git a/app/code/Magento/Store/Controller/Store/SwitchAction.php b/app/code/Magento/Store/Controller/Store/SwitchAction.php
index aa023e400460f..646ee4fe4d132 100644
--- a/app/code/Magento/Store/Controller/Store/SwitchAction.php
+++ b/app/code/Magento/Store/Controller/Store/SwitchAction.php
@@ -4,21 +4,25 @@
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
+
namespace Magento\Store\Controller\Store;
use Magento\Framework\App\Action\Action;
use Magento\Framework\App\Action\Context as ActionContext;
use Magento\Framework\App\Http\Context as HttpContext;
+use Magento\Framework\App\ObjectManager;
use Magento\Framework\Exception\NoSuchEntityException;
use Magento\Store\Api\StoreCookieManagerInterface;
use Magento\Store\Api\StoreRepositoryInterface;
-use Magento\Store\Model\Store;
use Magento\Store\Model\StoreIsInactiveException;
use Magento\Store\Model\StoreResolver;
use Magento\Store\Model\StoreManagerInterface;
+use Magento\Store\Model\StoreSwitcher;
+use Magento\Store\Model\StoreSwitcherInterface;
/**
- * Switch current store view.
+ * Handles store switching url and makes redirect.
+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
*/
class SwitchAction extends Action
{
@@ -29,6 +33,7 @@ class SwitchAction extends Action
/**
* @var HttpContext
+ * @deprecated
*/
protected $httpContext;
@@ -39,9 +44,15 @@ class SwitchAction extends Action
/**
* @var StoreManagerInterface
+ * @deprecated
*/
protected $storeManager;
+ /**
+ * @var StoreSwitcherInterface
+ */
+ private $storeSwitcher;
+
/**
* Initialize dependencies.
*
@@ -50,69 +61,55 @@ class SwitchAction extends Action
* @param HttpContext $httpContext
* @param StoreRepositoryInterface $storeRepository
* @param StoreManagerInterface $storeManager
+ * @param StoreSwitcherInterface $storeSwitcher
*/
public function __construct(
ActionContext $context,
StoreCookieManagerInterface $storeCookieManager,
HttpContext $httpContext,
StoreRepositoryInterface $storeRepository,
- StoreManagerInterface $storeManager
+ StoreManagerInterface $storeManager,
+ StoreSwitcherInterface $storeSwitcher = null
) {
parent::__construct($context);
$this->storeCookieManager = $storeCookieManager;
$this->httpContext = $httpContext;
$this->storeRepository = $storeRepository;
$this->storeManager = $storeManager;
+ $this->messageManager = $context->getMessageManager();
+ $this->storeSwitcher = $storeSwitcher ?: ObjectManager::getInstance()->get(StoreSwitcher::class);
}
/**
* @return void
+ * @throws StoreSwitcher\CannotSwitchStoreException
*/
public function execute()
{
- $currentActiveStore = $this->storeManager->getStore();
- $storeCode = $this->_request->getParam(
+ $targetStoreCode = $this->_request->getParam(
StoreResolver::PARAM_NAME,
$this->storeCookieManager->getStoreCodeFromCookie()
);
+ $fromStoreCode = $this->_request->getParam('___from_store');
+
+ $requestedUrlToRedirect = $this->_redirect->getRedirectUrl();
+ $redirectUrl = $requestedUrlToRedirect;
+ $error = null;
try {
- $store = $this->storeRepository->getActiveStoreByCode($storeCode);
+ $fromStore = $this->storeRepository->get($fromStoreCode);
+ $targetStore = $this->storeRepository->getActiveStoreByCode($targetStoreCode);
} catch (StoreIsInactiveException $e) {
$error = __('Requested store is inactive');
} catch (NoSuchEntityException $e) {
$error = __('Requested store is not found');
}
-
- if (isset($error)) {
- $this->messageManager->addError($error);
- $this->getResponse()->setRedirect($this->_redirect->getRedirectUrl());
- return;
- }
-
- $defaultStoreView = $this->storeManager->getDefaultStoreView();
- if ($defaultStoreView->getId() == $store->getId()) {
- $this->storeCookieManager->deleteStoreCookie($store);
+ if ($error !== null) {
+ $this->messageManager->addErrorMessage($error);
} else {
- $this->httpContext->setValue(Store::ENTITY, $store->getCode(), $defaultStoreView->getCode());
- $this->storeCookieManager->setStoreCookie($store);
+ $redirectUrl = $this->storeSwitcher->switch($fromStore, $targetStore, $requestedUrlToRedirect);
}
- if ($store->isUseStoreInUrl()) {
- // Change store code in redirect url
- if (strpos($this->_redirect->getRedirectUrl(), $currentActiveStore->getBaseUrl()) !== false) {
- $this->getResponse()->setRedirect(
- str_replace(
- $currentActiveStore->getBaseUrl(),
- $store->getBaseUrl(),
- $this->_redirect->getRedirectUrl()
- )
- );
- } else {
- $this->getResponse()->setRedirect($store->getBaseUrl());
- }
- } else {
- $this->getResponse()->setRedirect($this->_redirect->getRedirectUrl());
- }
+ $this->getResponse()->setRedirect($redirectUrl);
}
}
diff --git a/app/code/Magento/Store/Model/BaseUrlChecker.php b/app/code/Magento/Store/Model/BaseUrlChecker.php
index c0d27fd0d7a09..b22b18c5002ad 100644
--- a/app/code/Magento/Store/Model/BaseUrlChecker.php
+++ b/app/code/Magento/Store/Model/BaseUrlChecker.php
@@ -47,7 +47,7 @@ public function execute($uri, $request)
*/
public function isEnabled()
{
- return (bool) $this->scopeConfig->getValue(
+ return (bool)$this->scopeConfig->getValue(
'web/url/redirect_to_base',
\Magento\Store\Model\ScopeInterface::SCOPE_STORE
);
diff --git a/app/code/Magento/Store/Model/Config/Importer/Processor/Create.php b/app/code/Magento/Store/Model/Config/Importer/Processor/Create.php
index 768482aa44636..0a3f5eb5f31a3 100644
--- a/app/code/Magento/Store/Model/Config/Importer/Processor/Create.php
+++ b/app/code/Magento/Store/Model/Config/Importer/Processor/Create.php
@@ -52,6 +52,10 @@ class Create implements ProcessorInterface
/**
* The event manager.
*
+ * @deprecated logic moved inside of "afterSave" method
+ * \Magento\Store\Model\Website::afterSave
+ * \Magento\Store\Model\Group::afterSave
+ * \Magento\Store\Model\Store::afterSave
* @var ManagerInterface
*/
private $eventManager;
@@ -181,8 +185,6 @@ private function createGroups(array $items, array $data)
$group->setDefaultStoreId($store->getStoreId());
$group->setWebsite($website);
$group->getResource()->save($group);
-
- $this->eventManager->dispatch('store_group_save', ['group' => $group]);
});
}
}
diff --git a/app/code/Magento/Store/Model/Config/Importer/Processor/Delete.php b/app/code/Magento/Store/Model/Config/Importer/Processor/Delete.php
index 8660a0ba7152d..475c15122773e 100644
--- a/app/code/Magento/Store/Model/Config/Importer/Processor/Delete.php
+++ b/app/code/Magento/Store/Model/Config/Importer/Processor/Delete.php
@@ -168,10 +168,7 @@ private function deleteStores(array $items)
foreach ($items as $storeCode) {
$store = $this->storeRepository->get($storeCode);
- $store->getResource()->delete($store);
- $store->getResource()->addCommitCallback(function () use ($store) {
- $this->eventManager->dispatch('store_delete', ['store' => $store]);
- });
+ $store->delete();
}
}
diff --git a/app/code/Magento/Store/Model/Config/Importer/Processor/Update.php b/app/code/Magento/Store/Model/Config/Importer/Processor/Update.php
index 35f3957b168d7..155506291e59d 100644
--- a/app/code/Magento/Store/Model/Config/Importer/Processor/Update.php
+++ b/app/code/Magento/Store/Model/Config/Importer/Processor/Update.php
@@ -176,10 +176,7 @@ private function updateStores(array $items, array $data)
$store->setGroup($group);
}
- $store->getResource()->save($store);
- $store->getResource()->addCommitCallback(function () use ($store) {
- $this->eventManager->dispatch('store_edit', ['store' => $store]);
- });
+ $store->save();
}
}
@@ -214,11 +211,7 @@ private function updateGroups(array $items, array $data)
if ($website && $website->getId() != $group->getWebsiteId()) {
$group->setWebsite($website);
}
-
- $group->getResource()->save($group);
- $group->getResource()->addCommitCallback(function () use ($group) {
- $this->eventManager->dispatch('store_group_save', ['group' => $group]);
- });
+ $group->save();
}
}
diff --git a/app/code/Magento/Store/Model/Group.php b/app/code/Magento/Store/Model/Group.php
index 01f56fb9e0566..ccc3c65491422 100644
--- a/app/code/Magento/Store/Model/Group.php
+++ b/app/code/Magento/Store/Model/Group.php
@@ -95,6 +95,11 @@ class Group extends \Magento\Framework\Model\AbstractExtensibleModel implements
*/
protected $_storeManager;
+ /**
+ * @var \Magento\Framework\Event\ManagerInterface
+ */
+ private $eventManager;
+
/**
* @param \Magento\Framework\Model\Context $context
* @param \Magento\Framework\Registry $registry
@@ -106,6 +111,7 @@ class Group extends \Magento\Framework\Model\AbstractExtensibleModel implements
* @param \Magento\Framework\Model\ResourceModel\AbstractResource $resource
* @param \Magento\Framework\Data\Collection\AbstractDb $resourceCollection
* @param array $data
+ * @param \Magento\Framework\Event\ManagerInterface|null $eventManager
* @SuppressWarnings(PHPMD.ExcessiveParameterList)
*/
public function __construct(
@@ -118,11 +124,14 @@ public function __construct(
\Magento\Store\Model\StoreManagerInterface $storeManager,
\Magento\Framework\Model\ResourceModel\AbstractResource $resource = null,
\Magento\Framework\Data\Collection\AbstractDb $resourceCollection = null,
- array $data = []
+ array $data = [],
+ \Magento\Framework\Event\ManagerInterface $eventManager = null
) {
$this->_configDataResource = $configDataResource;
$this->_storeListFactory = $storeListFactory;
$this->_storeManager = $storeManager;
+ $this->eventManager = $eventManager ?: \Magento\Framework\App\ObjectManager::getInstance()
+ ->get(\Magento\Framework\Event\ManagerInterface::class);
parent::__construct(
$context,
$registry,
@@ -405,6 +414,11 @@ public function beforeDelete()
*/
public function afterDelete()
{
+ $group = $this;
+ $this->getResource()->addCommitCallback(function () use ($group) {
+ $this->_storeManager->reinitStores();
+ $this->eventManager->dispatch($this->_eventPrefix . '_delete', ['group' => $group]);
+ });
$result = parent::afterDelete();
if ($this->getId() === $this->getWebsite()->getDefaultGroupId()) {
@@ -421,6 +435,19 @@ public function afterDelete()
return $result;
}
+ /**
+ * @inheritdoc
+ */
+ public function afterSave()
+ {
+ $group = $this;
+ $this->getResource()->addCommitCallback(function () use ($group) {
+ $this->_storeManager->reinitStores();
+ $this->eventManager->dispatch($this->_eventPrefix . '_save', ['group' => $group]);
+ });
+ return parent::afterSave();
+ }
+
/**
* Get/Set isReadOnly flag
*
diff --git a/app/code/Magento/Store/Model/Indexer/WebsiteDimensionProvider.php b/app/code/Magento/Store/Model/Indexer/WebsiteDimensionProvider.php
new file mode 100644
index 0000000000000..302c2f828367a
--- /dev/null
+++ b/app/code/Magento/Store/Model/Indexer/WebsiteDimensionProvider.php
@@ -0,0 +1,72 @@
+dimensionFactory = $dimensionFactory;
+ $this->collectionFactory = $collectionFactory;
+ }
+
+ /**
+ * @return Dimension[]|\Traversable
+ */
+ public function getIterator(): \Traversable
+ {
+ foreach ($this->getWebsites() as $website) {
+ yield $this->dimensionFactory->create(self::DIMENSION_NAME, (string)$website);
+ }
+ }
+
+ /**
+ * @return array
+ */
+ private function getWebsites(): array
+ {
+ if ($this->websitesDataIterator === null) {
+ $websites = $this->collectionFactory->create()
+ ->addFieldToFilter('code', ['neq' => Store::ADMIN_CODE])
+ ->getAllIds();
+ $this->websitesDataIterator = is_array($websites) ? $websites : [];
+ }
+
+ return $this->websitesDataIterator;
+ }
+}
diff --git a/app/code/Magento/Store/Model/PathConfig.php b/app/code/Magento/Store/Model/PathConfig.php
index dfe4eee31f9a2..6eeb93d7475fa 100644
--- a/app/code/Magento/Store/Model/PathConfig.php
+++ b/app/code/Magento/Store/Model/PathConfig.php
@@ -83,6 +83,8 @@ public function shouldBeSecure($path)
*/
public function getDefaultPath()
{
- return $this->scopeConfig->getValue('web/default/front', ScopeInterface::SCOPE_STORE);
+ $store = $this->storeManager->getStore();
+ $value = $this->scopeConfig->getValue('web/default/front', ScopeInterface::SCOPE_STORE, $store);
+ return $value;
}
}
diff --git a/app/code/Magento/Store/Model/Plugin/StoreCookie.php b/app/code/Magento/Store/Model/Plugin/StoreCookie.php
index 612d35e136d7e..9fca86ab71762 100644
--- a/app/code/Magento/Store/Model/Plugin/StoreCookie.php
+++ b/app/code/Magento/Store/Model/Plugin/StoreCookie.php
@@ -82,12 +82,5 @@ public function beforeDispatch(
$this->storeCookieManager->deleteStoreCookie($this->storeManager->getDefaultStoreView());
}
}
- if ($this->storeCookieManager->getStoreCodeFromCookie() === null
- || $request->getParam(StoreResolverInterface::PARAM_NAME) !== null
- ) {
- $storeId = $this->storeResolver->getCurrentStoreId();
- $store = $this->storeRepository->getActiveStoreById($storeId);
- $this->storeCookieManager->setStoreCookie($store);
- }
}
}
diff --git a/app/code/Magento/Store/Model/ResourceModel/Website/Collection.php b/app/code/Magento/Store/Model/ResourceModel/Website/Collection.php
index fb23e842a38e3..64b459fc96153 100644
--- a/app/code/Magento/Store/Model/ResourceModel/Website/Collection.php
+++ b/app/code/Magento/Store/Model/ResourceModel/Website/Collection.php
@@ -150,8 +150,7 @@ public function joinGroupAndStore()
\Magento\Framework\DB\Select::SQL_ASC
) // view is admin
->addOrder('store_table.sort_order', \Magento\Framework\DB\Select::SQL_ASC) // view sort order
- ->addOrder('store_table.name', \Magento\Framework\DB\Select::SQL_ASC) // view name
- ;
+ ->addOrder('store_table.name', \Magento\Framework\DB\Select::SQL_ASC); // view name
}
return $this;
}
diff --git a/app/code/Magento/Store/Model/Store.php b/app/code/Magento/Store/Model/Store.php
index 0802f17aeba5b..9875e700d0afd 100644
--- a/app/code/Magento/Store/Model/Store.php
+++ b/app/code/Magento/Store/Model/Store.php
@@ -319,6 +319,11 @@ class Store extends AbstractExtensibleModel implements
*/
private $urlModifier;
+ /**
+ * @var \Magento\Framework\Event\ManagerInterface
+ */
+ private $eventManager;
+
/**
* @param \Magento\Framework\Model\Context $context
* @param \Magento\Framework\Registry $registry
@@ -344,6 +349,7 @@ class Store extends AbstractExtensibleModel implements
* @param \Magento\Framework\Data\Collection\AbstractDb $resourceCollection
* @param bool $isCustomEntryPoint
* @param array $data optional generic object data
+ * @param \Magento\Framework\Event\ManagerInterface|null $eventManager
*
* @SuppressWarnings(PHPMD.ExcessiveParameterList)
*/
@@ -371,7 +377,8 @@ public function __construct(
\Magento\Store\Api\WebsiteRepositoryInterface $websiteRepository,
\Magento\Framework\Data\Collection\AbstractDb $resourceCollection = null,
$isCustomEntryPoint = false,
- array $data = []
+ array $data = [],
+ \Magento\Framework\Event\ManagerInterface $eventManager = null
) {
$this->_coreFileStorageDatabase = $coreFileStorageDatabase;
$this->_config = $config;
@@ -390,6 +397,8 @@ public function __construct(
$this->_currencyInstalled = $currencyInstalled;
$this->groupRepository = $groupRepository;
$this->websiteRepository = $websiteRepository;
+ $this->eventManager = $eventManager ?: \Magento\Framework\App\ObjectManager::getInstance()
+ ->get(\Magento\Framework\Event\ManagerInterface::class);
parent::__construct(
$context,
$registry,
@@ -1048,6 +1057,15 @@ public function getWebsiteId()
public function afterSave()
{
$this->_storeManager->reinitStores();
+ if ($this->isObjectNew()) {
+ $event = $this->_eventPrefix . '_add';
+ } else {
+ $event = $this->_eventPrefix . '_edit';
+ }
+ $store = $this;
+ $this->getResource()->addCommitCallback(function () use ($event, $store) {
+ $this->eventManager->dispatch($event, ['store' => $store]);
+ });
return parent::afterSave();
}
@@ -1128,7 +1146,7 @@ public function isDefault()
/**
* Retrieve current url for store
*
- * @param bool|string $fromStore
+ * @param bool $fromStore
* @return string
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
* @SuppressWarnings(PHPMD.NPathComplexity)
@@ -1195,7 +1213,7 @@ public function getCurrentUrl($fromStore = true)
. (isset($storeParsedUrl['port']) ? ':' . $storeParsedUrl['port'] : '')
. $storeParsedUrl['path']
. $requestStringPath
- . ($currentUrlQueryParams ? '?' . http_build_query($currentUrlQueryParams, '', '&') : '');
+ . ($currentUrlQueryParams ? '?' . http_build_query($currentUrlQueryParams) : '');
return $currentUrl;
}
@@ -1228,6 +1246,11 @@ public function beforeDelete()
*/
public function afterDelete()
{
+ $store = $this;
+ $this->getResource()->addCommitCallback(function () use ($store) {
+ $this->_storeManager->reinitStores();
+ $this->eventManager->dispatch($this->_eventPrefix . '_delete', ['store' => $store]);
+ });
parent::afterDelete();
$this->_configCacheType->clean();
@@ -1242,6 +1265,7 @@ public function afterDelete()
$this->getGroup()->setDefaultStoreId($defaultId);
$this->getGroup()->save();
}
+
return $this;
}
diff --git a/app/code/Magento/Store/Model/StoreSwitcher.php b/app/code/Magento/Store/Model/StoreSwitcher.php
new file mode 100644
index 0000000000000..476196ad84f8a
--- /dev/null
+++ b/app/code/Magento/Store/Model/StoreSwitcher.php
@@ -0,0 +1,57 @@
+ $switcherInstance) {
+ if (!$switcherInstance instanceof StoreSwitcherInterface) {
+ throw new \InvalidArgumentException(
+ "Store switcher '{$switcherName}' is expected to implement interface "
+ . StoreSwitcherInterface::class
+ );
+ }
+ }
+ $this->storeSwitchers = $storeSwitchers;
+ }
+
+ /**
+ * @param StoreInterface $fromStore store where we came from
+ * @param StoreInterface $targetStore store where to go to
+ * @param string $redirectUrl original url requested for redirect after switching
+ * @return string url to be redirected after switching
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
+ * @throws CannotSwitchStoreException
+ */
+ public function switch(StoreInterface $fromStore, StoreInterface $targetStore, string $redirectUrl): string
+ {
+ $targetUrl = $redirectUrl;
+
+ foreach ($this->storeSwitchers as $storeSwitcher) {
+ $targetUrl = $storeSwitcher->switch($fromStore, $targetStore, $targetUrl);
+ }
+
+ return $targetUrl;
+ }
+}
diff --git a/app/code/Magento/Store/Model/StoreSwitcher/CannotSwitchStoreException.php b/app/code/Magento/Store/Model/StoreSwitcher/CannotSwitchStoreException.php
new file mode 100644
index 0000000000000..b19ae419e2f07
--- /dev/null
+++ b/app/code/Magento/Store/Model/StoreSwitcher/CannotSwitchStoreException.php
@@ -0,0 +1,26 @@
+urlHelper = $urlHelper;
+ $this->session = $session;
+ $this->sidResolver = $sidResolver;
+ }
+
+ /**
+ * @param StoreInterface $fromStore store where we came from
+ * @param StoreInterface $targetStore store where to go to
+ * @param string $redirectUrl original url requested for redirect after switching
+ * @return string redirect url
+ */
+ public function switch(StoreInterface $fromStore, StoreInterface $targetStore, string $redirectUrl): string
+ {
+ $targetUrl = $redirectUrl;
+ $sidName = $this->sidResolver->getSessionIdQueryParam($this->session);
+ $targetUrl = $this->urlHelper->removeRequestParam($targetUrl, $sidName);
+ $targetUrl = $this->urlHelper->removeRequestParam($targetUrl, '___from_store');
+ $targetUrl = $this->urlHelper->removeRequestParam($targetUrl, StoreResolverInterface::PARAM_NAME);
+
+ return $targetUrl;
+ }
+}
diff --git a/app/code/Magento/Store/Model/StoreSwitcher/ManagePrivateContent.php b/app/code/Magento/Store/Model/StoreSwitcher/ManagePrivateContent.php
new file mode 100644
index 0000000000000..4ef5aad5d7988
--- /dev/null
+++ b/app/code/Magento/Store/Model/StoreSwitcher/ManagePrivateContent.php
@@ -0,0 +1,65 @@
+cookieMetadataFactory = $cookieMetadataFactory;
+ $this->cookieManager = $cookieManager;
+ }
+
+ /**
+ * @param StoreInterface $fromStore store where we came from
+ * @param StoreInterface $targetStore store where to go to
+ * @param string $redirectUrl original url requested for redirect after switching
+ * @return string redirect url
+ * @throws CannotSwitchStoreException
+ */
+ public function switch(StoreInterface $fromStore, StoreInterface $targetStore, string $redirectUrl): string
+ {
+ try {
+ $publicCookieMetadata = $this->cookieMetadataFactory->createPublicCookieMetadata()
+ ->setDurationOneYear()
+ ->setPath('/')
+ ->setSecure(false)
+ ->setHttpOnly(false);
+ $this->cookieManager->setPublicCookie(
+ \Magento\Framework\App\PageCache\Version::COOKIE_NAME,
+ 'should_be_updated',
+ $publicCookieMetadata
+ );
+ } catch (\Exception $e) {
+ throw new CannotSwitchStoreException($e);
+ }
+
+ return $redirectUrl;
+ }
+}
diff --git a/app/code/Magento/Store/Model/StoreSwitcher/ManageStoreCookie.php b/app/code/Magento/Store/Model/StoreSwitcher/ManageStoreCookie.php
new file mode 100644
index 0000000000000..23fda163e9662
--- /dev/null
+++ b/app/code/Magento/Store/Model/StoreSwitcher/ManageStoreCookie.php
@@ -0,0 +1,71 @@
+storeCookieManager = $storeCookieManager;
+ $this->httpContext = $httpContext;
+ $this->storeManager = $storeManager;
+ }
+
+ /**
+ * @param StoreInterface $fromStore store where we came from
+ * @param StoreInterface $targetStore store where to go to
+ * @param string $redirectUrl original url requested for redirect after switching
+ * @return string redirect url
+ */
+ public function switch(StoreInterface $fromStore, StoreInterface $targetStore, string $redirectUrl): string
+ {
+ $defaultStoreView = $this->storeManager->getDefaultStoreView();
+ if ($defaultStoreView !== null) {
+ if ($defaultStoreView->getId() === $targetStore->getId()) {
+ $this->storeCookieManager->deleteStoreCookie($targetStore);
+ } else {
+ $this->httpContext->setValue(Store::ENTITY, $targetStore->getCode(), $defaultStoreView->getCode());
+ $this->storeCookieManager->setStoreCookie($targetStore);
+ }
+ }
+
+ return $redirectUrl;
+ }
+}
diff --git a/app/code/Magento/Store/Model/StoreSwitcherInterface.php b/app/code/Magento/Store/Model/StoreSwitcherInterface.php
new file mode 100644
index 0000000000000..b6c5c38d23ef6
--- /dev/null
+++ b/app/code/Magento/Store/Model/StoreSwitcherInterface.php
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Store/ActionGroup/AdminCreateStoreViewActionGroup.xml b/app/code/Magento/Store/Test/Mftf/ActionGroup/AdminCreateStoreViewActionGroup.xml
similarity index 89%
rename from dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Store/ActionGroup/AdminCreateStoreViewActionGroup.xml
rename to app/code/Magento/Store/Test/Mftf/ActionGroup/AdminCreateStoreViewActionGroup.xml
index ec174c00fa46b..6fdfb2566fee9 100644
--- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Store/ActionGroup/AdminCreateStoreViewActionGroup.xml
+++ b/app/code/Magento/Store/Test/Mftf/ActionGroup/AdminCreateStoreViewActionGroup.xml
@@ -7,7 +7,7 @@
-->
+ xsi:noNamespaceSchemaLocation="../../../../../../../dev/tests/acceptance/vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/actionGroupSchema.xsd">
diff --git a/app/code/Magento/Store/Test/Mftf/ActionGroup/AdminCreateWebsiteActionGroup.xml b/app/code/Magento/Store/Test/Mftf/ActionGroup/AdminCreateWebsiteActionGroup.xml
new file mode 100644
index 0000000000000..24c1a79a6959c
--- /dev/null
+++ b/app/code/Magento/Store/Test/Mftf/ActionGroup/AdminCreateWebsiteActionGroup.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Store/ActionGroup/AdminDeleteStoreViewActionGroup.xml b/app/code/Magento/Store/Test/Mftf/ActionGroup/AdminDeleteStoreViewActionGroup.xml
similarity index 88%
rename from dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Store/ActionGroup/AdminDeleteStoreViewActionGroup.xml
rename to app/code/Magento/Store/Test/Mftf/ActionGroup/AdminDeleteStoreViewActionGroup.xml
index 78ddf51f36880..c32953540a77a 100644
--- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Store/ActionGroup/AdminDeleteStoreViewActionGroup.xml
+++ b/app/code/Magento/Store/Test/Mftf/ActionGroup/AdminDeleteStoreViewActionGroup.xml
@@ -7,7 +7,7 @@
-->
+ xsi:noNamespaceSchemaLocation="../../../../../../../dev/tests/acceptance/vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/actionGroupSchema.xsd">
diff --git a/app/code/Magento/Store/Test/Mftf/ActionGroup/AdminDeleteWebsiteActionGroup.xml b/app/code/Magento/Store/Test/Mftf/ActionGroup/AdminDeleteWebsiteActionGroup.xml
new file mode 100644
index 0000000000000..558205bbc8071
--- /dev/null
+++ b/app/code/Magento/Store/Test/Mftf/ActionGroup/AdminDeleteWebsiteActionGroup.xml
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Store/ActionGroup/CreateCustomStoreViewActionGroup.xml b/app/code/Magento/Store/Test/Mftf/ActionGroup/CreateCustomStoreViewActionGroup.xml
similarity index 88%
rename from dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Store/ActionGroup/CreateCustomStoreViewActionGroup.xml
rename to app/code/Magento/Store/Test/Mftf/ActionGroup/CreateCustomStoreViewActionGroup.xml
index 1ed6c1ca10cf0..805958909f7fa 100644
--- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Store/ActionGroup/CreateCustomStoreViewActionGroup.xml
+++ b/app/code/Magento/Store/Test/Mftf/ActionGroup/CreateCustomStoreViewActionGroup.xml
@@ -7,7 +7,7 @@
-->
+ xsi:noNamespaceSchemaLocation="../../../../../../../dev/tests/acceptance/vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/actionGroupSchema.xsd">
diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Store/ActionGroup/DeleteCustomStoreActionGroup.xml b/app/code/Magento/Store/Test/Mftf/ActionGroup/DeleteCustomStoreActionGroup.xml
similarity index 88%
rename from dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Store/ActionGroup/DeleteCustomStoreActionGroup.xml
rename to app/code/Magento/Store/Test/Mftf/ActionGroup/DeleteCustomStoreActionGroup.xml
index 84d84d5d3828d..7c18ca5375c93 100644
--- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Store/ActionGroup/DeleteCustomStoreActionGroup.xml
+++ b/app/code/Magento/Store/Test/Mftf/ActionGroup/DeleteCustomStoreActionGroup.xml
@@ -7,7 +7,7 @@
-->
+ xsi:noNamespaceSchemaLocation="../../../../../../../dev/tests/acceptance/vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/actionGroupSchema.xsd">
diff --git a/app/code/Magento/Store/Test/Mftf/Data/StoreData.xml b/app/code/Magento/Store/Test/Mftf/Data/StoreData.xml
new file mode 100644
index 0000000000000..3e38d9aa53c9f
--- /dev/null
+++ b/app/code/Magento/Store/Test/Mftf/Data/StoreData.xml
@@ -0,0 +1,60 @@
+
+
+
+
+ Default Store View
+ default
+ 1
+
+
+
+ store
+ store
+ 1
+ null
+ add
+ store
+ customStoreGroup
+
+
+ EN
+ en
+ 1
+ null
+ add
+ store
+ customStoreGroup
+
+
+ FR
+ fr
+ 1
+ null
+ add
+ store
+ customStoreGroup
+
+
+ Second Store View
+ second_store_view
+ 1
+ null
+ add
+ store
+ secondStoreGroup
+
+
+ Second Store View
+ store123
+ 1
+ null
+ add
+ group
+ customStoreGroup
+
+
diff --git a/app/code/Magento/Store/Test/Mftf/Data/StoreGroupData.xml b/app/code/Magento/Store/Test/Mftf/Data/StoreGroupData.xml
new file mode 100644
index 0000000000000..30dfbd9dbedf2
--- /dev/null
+++ b/app/code/Magento/Store/Test/Mftf/Data/StoreGroupData.xml
@@ -0,0 +1,38 @@
+
+
+
+
+ Main Website Store
+ main_website_store
+ 2
+ 1
+
+
+ null
+ store
+ store
+
+ 1
+ add
+ group
+
+
+ null
+ Second Store
+ second_store
+
+ add
+ group
+
+
+ NewStore
+ Base12
+ 2
+ 1
+
+
diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Store/LICENSE.txt b/app/code/Magento/Store/Test/Mftf/LICENSE.txt
similarity index 100%
rename from dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Store/LICENSE.txt
rename to app/code/Magento/Store/Test/Mftf/LICENSE.txt
diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Store/LICENSE_AFL.txt b/app/code/Magento/Store/Test/Mftf/LICENSE_AFL.txt
similarity index 100%
rename from dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Store/LICENSE_AFL.txt
rename to app/code/Magento/Store/Test/Mftf/LICENSE_AFL.txt
diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Store/Metadata/store-meta.xml b/app/code/Magento/Store/Test/Mftf/Metadata/store-meta.xml
similarity index 80%
rename from dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Store/Metadata/store-meta.xml
rename to app/code/Magento/Store/Test/Mftf/Metadata/store-meta.xml
index 8b1ada521da66..e0263b2c88869 100644
--- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Store/Metadata/store-meta.xml
+++ b/app/code/Magento/Store/Test/Mftf/Metadata/store-meta.xml
@@ -6,7 +6,7 @@
*/
-->
+ xsi:noNamespaceSchemaLocation="../../../../../../../dev/tests/acceptance/vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/DataGenerator/etc/dataOperation.xsd">
diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Store/Metadata/store_group-meta.xml b/app/code/Magento/Store/Test/Mftf/Metadata/store_group-meta.xml
similarity index 81%
rename from dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Store/Metadata/store_group-meta.xml
rename to app/code/Magento/Store/Test/Mftf/Metadata/store_group-meta.xml
index d2d085e60328e..bc117756a542b 100644
--- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Store/Metadata/store_group-meta.xml
+++ b/app/code/Magento/Store/Test/Mftf/Metadata/store_group-meta.xml
@@ -6,7 +6,7 @@
*/
-->
+ xsi:noNamespaceSchemaLocation="../../../../../../../dev/tests/acceptance/vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/DataGenerator/etc/dataOperation.xsd">
application/x-www-form-urlencoded
diff --git a/app/code/Magento/Store/Test/Mftf/Page/AdminNewSystemStorePage.xml b/app/code/Magento/Store/Test/Mftf/Page/AdminNewSystemStorePage.xml
new file mode 100644
index 0000000000000..6011aec9f33b0
--- /dev/null
+++ b/app/code/Magento/Store/Test/Mftf/Page/AdminNewSystemStorePage.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
diff --git a/app/code/Magento/Store/Test/Mftf/Page/AdminSystemStoreDeletePage.xml b/app/code/Magento/Store/Test/Mftf/Page/AdminSystemStoreDeletePage.xml
new file mode 100644
index 0000000000000..3ec22d3135137
--- /dev/null
+++ b/app/code/Magento/Store/Test/Mftf/Page/AdminSystemStoreDeletePage.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
diff --git a/app/code/Magento/Store/Test/Mftf/Page/AdminSystemStoreEditPage.xml b/app/code/Magento/Store/Test/Mftf/Page/AdminSystemStoreEditPage.xml
new file mode 100644
index 0000000000000..fe7cc22318e0d
--- /dev/null
+++ b/app/code/Magento/Store/Test/Mftf/Page/AdminSystemStoreEditPage.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
diff --git a/app/code/Magento/Store/Test/Mftf/Page/AdminSystemStoreGroupEditPage.xml b/app/code/Magento/Store/Test/Mftf/Page/AdminSystemStoreGroupEditPage.xml
new file mode 100644
index 0000000000000..634ee6d651af1
--- /dev/null
+++ b/app/code/Magento/Store/Test/Mftf/Page/AdminSystemStoreGroupEditPage.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
diff --git a/app/code/Magento/Store/Test/Mftf/Page/AdminSystemStoreGroupPage.xml b/app/code/Magento/Store/Test/Mftf/Page/AdminSystemStoreGroupPage.xml
new file mode 100644
index 0000000000000..478166361d8f6
--- /dev/null
+++ b/app/code/Magento/Store/Test/Mftf/Page/AdminSystemStoreGroupPage.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
diff --git a/app/code/Magento/Store/Test/Mftf/Page/AdminSystemStorePage.xml b/app/code/Magento/Store/Test/Mftf/Page/AdminSystemStorePage.xml
new file mode 100644
index 0000000000000..9eed4f6557a59
--- /dev/null
+++ b/app/code/Magento/Store/Test/Mftf/Page/AdminSystemStorePage.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
diff --git a/app/code/Magento/Store/Test/Mftf/Page/AdminSystemStoreViewPage.xml b/app/code/Magento/Store/Test/Mftf/Page/AdminSystemStoreViewPage.xml
new file mode 100644
index 0000000000000..15ed31c19f996
--- /dev/null
+++ b/app/code/Magento/Store/Test/Mftf/Page/AdminSystemStoreViewPage.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
diff --git a/app/code/Magento/Store/Test/Mftf/Page/AdminSystemStoreWebsitePage.xml b/app/code/Magento/Store/Test/Mftf/Page/AdminSystemStoreWebsitePage.xml
new file mode 100644
index 0000000000000..61ade61552054
--- /dev/null
+++ b/app/code/Magento/Store/Test/Mftf/Page/AdminSystemStoreWebsitePage.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
diff --git a/app/code/Magento/Store/Test/Mftf/README.md b/app/code/Magento/Store/Test/Mftf/README.md
new file mode 100644
index 0000000000000..18b37aad6d8ef
--- /dev/null
+++ b/app/code/Magento/Store/Test/Mftf/README.md
@@ -0,0 +1,3 @@
+# Store Functional Tests
+
+The Functional Test Module for **Magento Store** module.
diff --git a/app/code/Magento/Store/Test/Mftf/Section/AdminMainActionsSection.xml b/app/code/Magento/Store/Test/Mftf/Section/AdminMainActionsSection.xml
new file mode 100644
index 0000000000000..14429c298b5e5
--- /dev/null
+++ b/app/code/Magento/Store/Test/Mftf/Section/AdminMainActionsSection.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
diff --git a/app/code/Magento/Store/Test/Mftf/Section/AdminNewStoreGroupSection.xml b/app/code/Magento/Store/Test/Mftf/Section/AdminNewStoreGroupSection.xml
new file mode 100644
index 0000000000000..106a0f4de5e8b
--- /dev/null
+++ b/app/code/Magento/Store/Test/Mftf/Section/AdminNewStoreGroupSection.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Store/Section/AdminNewStoreSection.xml b/app/code/Magento/Store/Test/Mftf/Section/AdminNewStoreSection.xml
similarity index 80%
rename from dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Store/Section/AdminNewStoreSection.xml
rename to app/code/Magento/Store/Test/Mftf/Section/AdminNewStoreSection.xml
index 6ff8f6765de8f..cec7a1f4f81e1 100644
--- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Store/Section/AdminNewStoreSection.xml
+++ b/app/code/Magento/Store/Test/Mftf/Section/AdminNewStoreSection.xml
@@ -5,7 +5,7 @@
* See COPYING.txt for license details.
*/
-->
-
+
diff --git a/app/code/Magento/Store/Test/Mftf/Section/AdminNewStoreViewActionsSection.xml b/app/code/Magento/Store/Test/Mftf/Section/AdminNewStoreViewActionsSection.xml
new file mode 100644
index 0000000000000..a3b5d1e616319
--- /dev/null
+++ b/app/code/Magento/Store/Test/Mftf/Section/AdminNewStoreViewActionsSection.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
diff --git a/app/code/Magento/Store/Test/Mftf/Section/AdminNewWebsiteActionsSection.xml b/app/code/Magento/Store/Test/Mftf/Section/AdminNewWebsiteActionsSection.xml
new file mode 100644
index 0000000000000..1f02de731f9a0
--- /dev/null
+++ b/app/code/Magento/Store/Test/Mftf/Section/AdminNewWebsiteActionsSection.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
diff --git a/app/code/Magento/Store/Test/Mftf/Section/AdminNewWebsiteSection.xml b/app/code/Magento/Store/Test/Mftf/Section/AdminNewWebsiteSection.xml
new file mode 100644
index 0000000000000..21dee5f6b6e0d
--- /dev/null
+++ b/app/code/Magento/Store/Test/Mftf/Section/AdminNewWebsiteSection.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
diff --git a/app/code/Magento/Store/Test/Mftf/Section/AdminStoreBackupOptionsSection.xml b/app/code/Magento/Store/Test/Mftf/Section/AdminStoreBackupOptionsSection.xml
new file mode 100644
index 0000000000000..5472eab6ae88e
--- /dev/null
+++ b/app/code/Magento/Store/Test/Mftf/Section/AdminStoreBackupOptionsSection.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
diff --git a/app/code/Magento/Store/Test/Mftf/Section/AdminStoreGroupActionsSection.xml b/app/code/Magento/Store/Test/Mftf/Section/AdminStoreGroupActionsSection.xml
new file mode 100644
index 0000000000000..6dc766c0c02da
--- /dev/null
+++ b/app/code/Magento/Store/Test/Mftf/Section/AdminStoreGroupActionsSection.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
diff --git a/app/code/Magento/Store/Test/Mftf/Section/AdminStoresDeleteStoreGroupSection.xml b/app/code/Magento/Store/Test/Mftf/Section/AdminStoresDeleteStoreGroupSection.xml
new file mode 100644
index 0000000000000..ba3d9660b44b3
--- /dev/null
+++ b/app/code/Magento/Store/Test/Mftf/Section/AdminStoresDeleteStoreGroupSection.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Store/Section/AdminStoresGridSection.xml b/app/code/Magento/Store/Test/Mftf/Section/AdminStoresGridSection.xml
similarity index 84%
rename from dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Store/Section/AdminStoresGridSection.xml
rename to app/code/Magento/Store/Test/Mftf/Section/AdminStoresGridSection.xml
index eb283ed17b354..d0a67b18f6cd5 100644
--- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Store/Section/AdminStoresGridSection.xml
+++ b/app/code/Magento/Store/Test/Mftf/Section/AdminStoresGridSection.xml
@@ -5,7 +5,7 @@
* See COPYING.txt for license details.
*/
-->
-
+
diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Store/Section/AdminStoresMainActionsSection.xml b/app/code/Magento/Store/Test/Mftf/Section/AdminStoresMainActionsSection.xml
similarity index 79%
rename from dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Store/Section/AdminStoresMainActionsSection.xml
rename to app/code/Magento/Store/Test/Mftf/Section/AdminStoresMainActionsSection.xml
index 24c1d72f90f16..5fb45f6dee3c2 100644
--- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Store/Section/AdminStoresMainActionsSection.xml
+++ b/app/code/Magento/Store/Test/Mftf/Section/AdminStoresMainActionsSection.xml
@@ -5,7 +5,7 @@
* See COPYING.txt for license details.
*/
-->
-
+
diff --git a/app/code/Magento/Store/Test/Mftf/Section/StorefrontHeaderSection.xml b/app/code/Magento/Store/Test/Mftf/Section/StorefrontHeaderSection.xml
new file mode 100644
index 0000000000000..56cda5376ca4e
--- /dev/null
+++ b/app/code/Magento/Store/Test/Mftf/Section/StorefrontHeaderSection.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Store/Test/AdminCreateStoreGroupTest.xml b/app/code/Magento/Store/Test/Mftf/Test/AdminCreateStoreGroupTest.xml
similarity index 94%
rename from dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Store/Test/AdminCreateStoreGroupTest.xml
rename to app/code/Magento/Store/Test/Mftf/Test/AdminCreateStoreGroupTest.xml
index 35d3d82f26569..860fb4a6a9327 100644
--- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Store/Test/AdminCreateStoreGroupTest.xml
+++ b/app/code/Magento/Store/Test/Mftf/Test/AdminCreateStoreGroupTest.xml
@@ -6,7 +6,7 @@
*/
-->
-
+
diff --git a/app/code/Magento/Store/Test/Mftf/composer.json b/app/code/Magento/Store/Test/Mftf/composer.json
new file mode 100644
index 0000000000000..cf00d3bff3b18
--- /dev/null
+++ b/app/code/Magento/Store/Test/Mftf/composer.json
@@ -0,0 +1,24 @@
+{
+ "name": "magento/functional-test-module-store",
+ "description": "N/A",
+ "config": {
+ "sort-packages": true
+ },
+ "require": {
+ "php": "~7.0.13|~7.1.0",
+ "magento/functional-test-module-catalog": "100.0.0-dev",
+ "magento/functional-test-module-directory": "100.0.0-dev",
+ "magento/functional-test-module-ui": "100.0.0-dev",
+ "magento/functional-test-module-config": "100.0.0-dev",
+ "magento/functional-test-module-media-storage": "100.0.0-dev",
+ "magento/magento2-functional-testing-framework": "2.2.0"
+ },
+ "suggest": {
+ "magento/functional-test-module-deploy": "100.0.0-dev"
+ },
+ "type": "magento2-test",
+ "license": [
+ "OSL-3.0",
+ "AFL-3.0"
+ ]
+}
diff --git a/app/code/Magento/Store/Test/Unit/App/Action/Plugin/ContextTest.php b/app/code/Magento/Store/Test/Unit/App/Action/Plugin/ContextTest.php
index 615542a852e34..3b8aad834b691 100644
--- a/app/code/Magento/Store/Test/Unit/App/Action/Plugin/ContextTest.php
+++ b/app/code/Magento/Store/Test/Unit/App/Action/Plugin/ContextTest.php
@@ -52,7 +52,7 @@ class ContextTest extends \PHPUnit\Framework\TestCase
/**
* @var \Magento\Store\Model\Store|\PHPUnit_Framework_MockObject_MockObject
*/
- protected $storeMock;
+ protected $store;
/**
* @var \Magento\Store\Model\Store|\PHPUnit_Framework_MockObject_MockObject
@@ -62,7 +62,7 @@ class ContextTest extends \PHPUnit\Framework\TestCase
/**
* @var \Magento\Store\Model\Website|\PHPUnit_Framework_MockObject_MockObject
*/
- protected $websiteMock;
+ protected $website;
/**
* @var AbstractAction|\PHPUnit_Framework_MockObject_MockObject
@@ -87,9 +87,9 @@ protected function setUp()
->willReturn(null);
$this->storeManager = $this->createMock(\Magento\Store\Model\StoreManagerInterface::class);
$this->storeCookieManager = $this->createMock(\Magento\Store\Api\StoreCookieManagerInterface::class);
- $this->storeMock = $this->createMock(\Magento\Store\Model\Store::class);
+ $this->store = $this->createMock(\Magento\Store\Model\Store::class);
$this->currentStoreMock = $this->createMock(\Magento\Store\Model\Store::class);
- $this->websiteMock = $this->createPartialMock(
+ $this->website = $this->createPartialMock(
\Magento\Store\Model\Website::class,
['getDefaultStore', '__wakeup']
);
@@ -108,8 +108,6 @@ protected function setUp()
]
);
- $this->storeManager->method('getDefaultStoreView')
- ->willReturn($this->storeMock);
$this->storeCookieManager->expects($this->once())
->method('getStoreCodeFromCookie')
->will($this->returnValue('storeCookie'));
@@ -122,16 +120,16 @@ public function testBeforeDispatchCurrencyFromSession()
{
$this->storeManager->expects($this->once())
->method('getWebsite')
- ->will($this->returnValue($this->websiteMock));
- $this->websiteMock->expects($this->once())
+ ->will($this->returnValue($this->website));
+ $this->website->expects($this->once())
->method('getDefaultStore')
- ->will($this->returnValue($this->storeMock));
+ ->will($this->returnValue($this->store));
- $this->storeMock->expects($this->once())
+ $this->store->expects($this->once())
->method('getDefaultCurrencyCode')
->will($this->returnValue(self::CURRENCY_DEFAULT));
- $this->storeMock->expects($this->once())
+ $this->store->expects($this->once())
->method('getCode')
->willReturn('default');
$this->currentStoreMock->expects($this->once())
@@ -173,41 +171,39 @@ public function testBeforeDispatchCurrencyFromSession()
);
}
- public function testDispatchCurrentStoreCurrency()
+ public function testDispatchCurrentStoreAndCurrency()
{
- $this->storeManager->expects($this->once())
- ->method('getWebsite')
- ->will($this->returnValue($this->websiteMock));
- $this->websiteMock->expects($this->once())
- ->method('getDefaultStore')
- ->will($this->returnValue($this->storeMock));
+ $defaultStoreCode = 'default_store';
+ $customStoreCode = 'custom_store';
- $this->storeMock->expects($this->once())
- ->method('getDefaultCurrencyCode')
- ->will($this->returnValue(self::CURRENCY_DEFAULT));
+ $this->storeManager->method('getWebsite')
+ ->willReturn($this->website);
+ $this->website->method('getDefaultStore')
+ ->willReturn($this->store);
- $this->storeMock->expects($this->once())
- ->method('getCode')
- ->willReturn('default');
- $this->currentStoreMock->expects($this->once())
- ->method('getCode')
- ->willReturn('custom_store');
+ $this->store->method('getDefaultCurrencyCode')
+ ->willReturn(self::CURRENCY_DEFAULT);
+
+ $this->store->method('getCode')
+ ->willReturn($defaultStoreCode);
+ $this->currentStoreMock->method('getCode')
+ ->willReturn($customStoreCode);
$this->requestMock->expects($this->once())
->method('getParam')
->with($this->equalTo('___store'))
- ->will($this->returnValue('default'));
+ ->willReturn($defaultStoreCode);
$this->storeManager->method('getStore')
- ->with('default')
+ ->with($defaultStoreCode)
->willReturn($this->currentStoreMock);
$this->httpContextMock->expects($this->at(1))
->method('setValue')
->with(
StoreManagerInterface::CONTEXT_STORE,
- 'custom_store',
- 'default'
+ $customStoreCode,
+ $defaultStoreCode
);
// Make sure that current currency is taken from current store
//if no value is provided in session.
@@ -229,16 +225,16 @@ public function testDispatchStoreParameterIsArray()
{
$this->storeManager->expects($this->once())
->method('getWebsite')
- ->will($this->returnValue($this->websiteMock));
- $this->websiteMock->expects($this->once())
+ ->will($this->returnValue($this->website));
+ $this->website->expects($this->once())
->method('getDefaultStore')
- ->will($this->returnValue($this->storeMock));
+ ->will($this->returnValue($this->store));
- $this->storeMock->expects($this->once())
+ $this->store->expects($this->once())
->method('getDefaultCurrencyCode')
->will($this->returnValue(self::CURRENCY_DEFAULT));
- $this->storeMock->expects($this->once())
+ $this->store->expects($this->once())
->method('getCode')
->willReturn('default');
$this->currentStoreMock->expects($this->once())
@@ -291,15 +287,15 @@ public function testDispatchStoreParameterIsInvalidArray()
{
$this->storeManager->expects($this->once())
->method('getWebsite')
- ->will($this->returnValue($this->websiteMock));
- $this->websiteMock->expects($this->once())
+ ->will($this->returnValue($this->website));
+ $this->website->expects($this->once())
->method('getDefaultStore')
- ->will($this->returnValue($this->storeMock));
- $this->storeMock->expects($this->exactly(2))
+ ->will($this->returnValue($this->store));
+ $this->store->expects($this->exactly(2))
->method('getDefaultCurrencyCode')
->will($this->returnValue(self::CURRENCY_DEFAULT));
- $this->storeMock->expects($this->exactly(2))
+ $this->store->expects($this->exactly(2))
->method('getCode')
->willReturn('default');
$this->currentStoreMock->expects($this->never())
@@ -319,7 +315,7 @@ public function testDispatchStoreParameterIsInvalidArray()
$this->storeManager->expects($this->once())
->method('getStore')
->with()
- ->willReturn($this->storeMock);
+ ->willReturn($this->store);
$this->plugin->beforeDispatch(
$this->subjectMock,
$this->requestMock
@@ -343,18 +339,18 @@ public function testDispatchNonExistingStore()
$this->storeManager->expects($this->at(1))
->method('getStore')
->with()
- ->willReturn($this->storeMock);
+ ->willReturn($this->store);
$this->storeManager->expects($this->once())
->method('getWebsite')
- ->will($this->returnValue($this->websiteMock));
- $this->websiteMock->expects($this->once())
+ ->will($this->returnValue($this->website));
+ $this->website->expects($this->once())
->method('getDefaultStore')
- ->will($this->returnValue($this->storeMock));
- $this->storeMock->expects($this->exactly(2))
+ ->will($this->returnValue($this->store));
+ $this->store->expects($this->exactly(2))
->method('getDefaultCurrencyCode')
->will($this->returnValue(self::CURRENCY_DEFAULT));
- $this->storeMock->expects($this->exactly(2))
+ $this->store->expects($this->exactly(2))
->method('getCode')
->willReturn('default');
$this->currentStoreMock->expects($this->never())
diff --git a/app/code/Magento/Store/Test/Unit/Block/SwitcherTest.php b/app/code/Magento/Store/Test/Unit/Block/SwitcherTest.php
index 8b4799d2b3437..57cb63e7c2744 100644
--- a/app/code/Magento/Store/Test/Unit/Block/SwitcherTest.php
+++ b/app/code/Magento/Store/Test/Unit/Block/SwitcherTest.php
@@ -25,6 +25,9 @@ class SwitcherTest extends \PHPUnit\Framework\TestCase
/** @var \Magento\Framework\UrlInterface|\PHPUnit_Framework_MockObject_MockObject */
protected $urlBuilder;
+ /** @var \Magento\Store\Api\Data\StoreInterface|\PHPUnit_Framework_MockObject_MockObject */
+ private $store;
+
protected function setUp()
{
$this->storeManager = $this->getMockBuilder(\Magento\Store\Model\StoreManagerInterface::class)->getMock();
@@ -33,6 +36,9 @@ protected function setUp()
$this->context->expects($this->any())->method('getStoreManager')->will($this->returnValue($this->storeManager));
$this->context->expects($this->any())->method('getUrlBuilder')->will($this->returnValue($this->urlBuilder));
$this->corePostDataHelper = $this->createMock(\Magento\Framework\Data\Helper\PostHelper::class);
+ $this->store = $this->getMockBuilder(\Magento\Store\Api\Data\StoreInterface::class)
+ ->disableOriginalConstructor()
+ ->getMockForAbstractClass();
$this->switcher = (new ObjectManager($this))->getObject(
\Magento\Store\Block\Switcher::class,
[
@@ -50,14 +56,23 @@ public function testGetTargetStorePostData()
$store->expects($this->any())
->method('getCode')
->willReturn('new-store');
- $storeSwitchUrl = 'http://domain.com/stores/store/switch';
+ $storeSwitchUrl = 'http://domain.com/stores/store/redirect';
$store->expects($this->atLeastOnce())
->method('getCurrentUrl')
- ->with(true)
+ ->with(false)
+ ->willReturn($storeSwitchUrl);
+ $this->storeManager->expects($this->once())
+ ->method('getStore')
+ ->willReturn($this->store);
+ $this->store->expects($this->once())
+ ->method('getCode')
+ ->willReturn('old-store');
+ $this->urlBuilder->expects($this->once())
+ ->method('getUrl')
->willReturn($storeSwitchUrl);
$this->corePostDataHelper->expects($this->any())
->method('getPostData')
- ->with($storeSwitchUrl, ['___store' => 'new-store']);
+ ->with($storeSwitchUrl, ['___store' => 'new-store', 'uenc' => null, '___from_store' => 'old-store']);
$this->switcher->getTargetStorePostData($store);
}
diff --git a/app/code/Magento/Store/Test/Unit/Controller/Store/SwitchActionTest.php b/app/code/Magento/Store/Test/Unit/Controller/Store/SwitchActionTest.php
index 1e7b2691a0084..fa7c696bf53cd 100644
--- a/app/code/Magento/Store/Test/Unit/Controller/Store/SwitchActionTest.php
+++ b/app/code/Magento/Store/Test/Unit/Controller/Store/SwitchActionTest.php
@@ -8,13 +8,15 @@
use Magento\Framework\App\Http\Context as HttpContext;
use Magento\Store\Api\StoreCookieManagerInterface;
use Magento\Store\Api\StoreRepositoryInterface;
-use Magento\Store\Model\Store;
-use Magento\Store\Model\StoreResolver;
use Magento\Store\Model\StoreManagerInterface;
use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
+use Magento\Store\Model\StoreResolver;
+use Magento\Store\Model\StoreSwitcher;
+use Magento\Store\Model\StoreSwitcherInterface;
/**
* Test class for \Magento\Store\Controller\Store\SwitchAction
+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
*/
class SwitchActionTest extends \PHPUnit\Framework\TestCase
{
@@ -58,6 +60,9 @@ class SwitchActionTest extends \PHPUnit\Framework\TestCase
*/
private $redirectMock;
+ /** @var StoreSwitcherInterface|\PHPUnit_Framework_MockObject_MockObject */
+ private $storeSwitcher;
+
protected function setUp()
{
$this->storeManagerMock = $this->getMockBuilder(\Magento\Store\Model\StoreManagerInterface::class)->getMock();
@@ -73,6 +78,10 @@ protected function setUp()
->getMockForAbstractClass();
$this->redirectMock =
$this->getMockBuilder(\Magento\Framework\App\Response\RedirectInterface::class)->getMock();
+ $this->storeSwitcher = $this->getMockBuilder(StoreSwitcher::class)
+ ->disableOriginalConstructor()
+ ->setMethods(['switch'])
+ ->getMock();
$this->model = (new ObjectManager($this))->getObject(
\Magento\Store\Controller\Store\SwitchAction::class,
@@ -83,81 +92,45 @@ protected function setUp()
'storeManager' => $this->storeManagerMock,
'_request' => $this->requestMock,
'_response' => $this->responseMock,
- '_redirect' => $this->redirectMock
+ '_redirect' => $this->redirectMock,
+ 'storeSwitcher' => $this->storeSwitcher
]
);
}
- public function testExecuteSuccessWithoutUseStoreInUrl()
+ public function testExecute()
{
$storeToSwitchToCode = 'sv2';
$defaultStoreViewCode = 'default';
$expectedRedirectUrl = "magento.com/{$storeToSwitchToCode}";
- $currentActiveStoreMock = $this->getMockBuilder(\Magento\Store\Api\Data\StoreInterface::class)->getMock();
$defaultStoreViewMock = $this->getMockBuilder(\Magento\Store\Api\Data\StoreInterface::class)->getMock();
$storeToSwitchToMock = $this->getMockBuilder(\Magento\Store\Api\Data\StoreInterface::class)
->disableOriginalConstructor()
->setMethods(['isUseStoreInUrl'])
->getMockForAbstractClass();
- $this->storeManagerMock->expects($this->once())->method('getStore')->willReturn($currentActiveStoreMock);
- $this->requestMock->expects($this->once())->method('getParam')->willReturn($storeToSwitchToCode);
+ $this->requestMock->expects($this->any())->method('getParam')->willReturnMap(
+ [
+ [StoreResolver::PARAM_NAME, null, $storeToSwitchToCode],
+ ['___from_store', null, $defaultStoreViewCode]
+ ]
+ );
$this->storeRepositoryMock
->expects($this->once())
- ->method('getActiveStoreByCode')
- ->willReturn($storeToSwitchToMock);
- $this->storeManagerMock
- ->expects($this->once())
- ->method('getDefaultStoreView')
+ ->method('get')
+ ->with($defaultStoreViewCode)
->willReturn($defaultStoreViewMock);
- $defaultStoreViewMock->expects($this->once())->method('getId')->willReturn($defaultStoreViewCode);
- $storeToSwitchToMock->expects($this->once())->method('getId')->willReturn($storeToSwitchToCode);
- $storeToSwitchToMock->expects($this->once())->method('isUseStoreInUrl')->willReturn(false);
- $this->redirectMock->expects($this->once())->method('getRedirectUrl')->willReturn($expectedRedirectUrl);
- $this->responseMock->expects($this->once())->method('setRedirect')->with($expectedRedirectUrl);
-
- $this->model->execute();
- }
-
- public function testExecuteSuccessWithUseStoreInUrl()
- {
- $currentActiveStoreCode = 'sv1';
- $storeToSwitchToCode = 'sv2';
- $defaultStoreViewCode = 'default';
- $originalRedirectUrl = "magento.com/{$currentActiveStoreCode}/test-page/test-sub-page";
- $expectedRedirectUrl = "magento.com/{$storeToSwitchToCode}/test-page/test-sub-page";
- $currentActiveStoreMock = $this->getMockBuilder(\Magento\Store\Api\Data\StoreInterface::class)
- ->disableOriginalConstructor()
- ->setMethods(['isUseStoreInUrl', 'getBaseUrl'])
- ->getMockForAbstractClass();
- $defaultStoreViewMock = $this->getMockBuilder(\Magento\Store\Api\Data\StoreInterface::class)->getMock();
- $storeToSwitchToMock = $this->getMockBuilder(\Magento\Store\Api\Data\StoreInterface::class)
- ->disableOriginalConstructor()
- ->setMethods(['isUseStoreInUrl', 'getBaseUrl'])
- ->getMockForAbstractClass();
-
- $this->storeManagerMock->expects($this->once())->method('getStore')->willReturn($currentActiveStoreMock);
- $this->requestMock->expects($this->once())->method('getParam')->willReturn($storeToSwitchToCode);
$this->storeRepositoryMock
->expects($this->once())
->method('getActiveStoreByCode')
+ ->with($storeToSwitchToCode)
->willReturn($storeToSwitchToMock);
- $this->storeManagerMock
- ->expects($this->once())
- ->method('getDefaultStoreView')
- ->willReturn($defaultStoreViewMock);
- $defaultStoreViewMock->expects($this->once())->method('getId')->willReturn($defaultStoreViewCode);
- $storeToSwitchToMock->expects($this->once())->method('getId')->willReturn($storeToSwitchToCode);
- $storeToSwitchToMock->expects($this->once())->method('isUseStoreInUrl')->willReturn(true);
- $this->redirectMock->expects($this->any())->method('getRedirectUrl')->willReturn($originalRedirectUrl);
- $currentActiveStoreMock
- ->expects($this->any())
- ->method('getBaseUrl')
- ->willReturn("magento.com/{$currentActiveStoreCode}");
- $storeToSwitchToMock
- ->expects($this->once())
- ->method('getBaseUrl')
- ->willReturn("magento.com/{$storeToSwitchToCode}");
+ $this->storeSwitcher->expects($this->once())
+ ->method('switch')
+ ->with($defaultStoreViewMock, $storeToSwitchToMock, $expectedRedirectUrl)
+ ->willReturn($expectedRedirectUrl);
+
+ $this->redirectMock->expects($this->once())->method('getRedirectUrl')->willReturn($expectedRedirectUrl);
$this->responseMock->expects($this->once())->method('setRedirect')->with($expectedRedirectUrl);
$this->model->execute();
diff --git a/app/code/Magento/Store/Test/Unit/Model/Config/Importer/Processor/CreateTest.php b/app/code/Magento/Store/Test/Unit/Model/Config/Importer/Processor/CreateTest.php
index 9c7cc648cf8af..2c2b0b00aec43 100644
--- a/app/code/Magento/Store/Test/Unit/Model/Config/Importer/Processor/CreateTest.php
+++ b/app/code/Magento/Store/Test/Unit/Model/Config/Importer/Processor/CreateTest.php
@@ -325,10 +325,6 @@ public function testRunGroup()
return $function();
});
- $this->eventManagerMock->expects($this->once())
- ->method('dispatch')
- ->with('store_group_save', ['group' => $this->groupMock]);
-
$this->processor->run($this->data);
}
@@ -382,10 +378,6 @@ public function testRunStore()
return $function();
});
- $this->eventManagerMock->expects($this->once())
- ->method('dispatch')
- ->with('store_add', ['store' => $this->storeMock]);
-
$this->processor->run($this->data);
}
diff --git a/app/code/Magento/Store/Test/Unit/Model/Config/Importer/Processor/DeleteTest.php b/app/code/Magento/Store/Test/Unit/Model/Config/Importer/Processor/DeleteTest.php
index d16a4a70b00aa..c373643fa03ac 100644
--- a/app/code/Magento/Store/Test/Unit/Model/Config/Importer/Processor/DeleteTest.php
+++ b/app/code/Magento/Store/Test/Unit/Model/Config/Importer/Processor/DeleteTest.php
@@ -244,8 +244,6 @@ public function testRun()
->method('get')
->with('test')
->willReturn($this->storeMock);
- $this->storeResourceMock->expects($this->once())
- ->method('addCommitCallback');
$this->registryMock->expects($this->once())
->method('unregister')
diff --git a/app/code/Magento/Store/Test/Unit/Model/Config/Importer/Processor/UpdateTest.php b/app/code/Magento/Store/Test/Unit/Model/Config/Importer/Processor/UpdateTest.php
index 3b0b932e31d46..e98ad08d46a68 100644
--- a/app/code/Magento/Store/Test/Unit/Model/Config/Importer/Processor/UpdateTest.php
+++ b/app/code/Magento/Store/Test/Unit/Model/Config/Importer/Processor/UpdateTest.php
@@ -175,7 +175,7 @@ public function testRun()
$updateData[ScopeInterface::SCOPE_STORES],
],
]);
- $this->websiteMock->expects($this->exactly(4))
+ $this->websiteMock->expects($this->atLeastOnce())
->method('getResource')
->willReturn($this->websiteResourceMock);
$this->websiteMock->expects($this->once())
@@ -203,7 +203,7 @@ public function testRun()
$this->groupFactoryMock->expects($this->exactly(3))
->method('create')
->willReturn($this->groupMock);
- $this->groupMock->expects($this->exactly(5))
+ $this->groupMock->expects($this->atLeastOnce())
->method('getResource')
->willReturn($this->groupResourceMock);
$this->groupMock->expects($this->once())
@@ -227,7 +227,7 @@ public function testRun()
$this->storeFactoryMock->expects($this->exactly(2))
->method('create')
->willReturn($this->storeMock);
- $this->storeMock->expects($this->exactly(4))
+ $this->storeMock->expects($this->atLeastOnce())
->method('getResource')
->willReturn($this->storeResourceMock);
$this->storeMock->expects($this->once())
@@ -244,15 +244,16 @@ public function testRun()
$this->storeMock->expects($this->once())
->method('setData')
->with($updateData[ScopeInterface::SCOPE_STORES]['test']);
- $this->storeResourceMock->expects($this->once())
+ $this->storeMock->expects($this->once())
->method('save')
- ->with($this->storeMock);
- $this->storeResourceMock->expects($this->once())
- ->method('addCommitCallback');
+ ->willReturnSelf();
$this->model->run($data);
}
+ /**
+ * @return array
+ */
private function getData()
{
return [
diff --git a/app/code/Magento/Store/Test/Unit/Model/Plugin/StoreCookieTest.php b/app/code/Magento/Store/Test/Unit/Model/Plugin/StoreCookieTest.php
index e56b5c7fcaa19..7aa992064f794 100644
--- a/app/code/Magento/Store/Test/Unit/Model/Plugin/StoreCookieTest.php
+++ b/app/code/Magento/Store/Test/Unit/Model/Plugin/StoreCookieTest.php
@@ -125,10 +125,6 @@ public function testBeforeDispatchNoSuchEntity()
$this->storeCookieManagerMock->expects($this->once())
->method('deleteStoreCookie')
->with($this->storeMock);
- $this->requestMock->expects($this->atLeastOnce())
- ->method('getParam')
- ->with(StoreResolverInterface::PARAM_NAME)
- ->willReturn(null);
$this->plugin->beforeDispatch($this->subjectMock, $this->requestMock);
}
@@ -148,10 +144,6 @@ public function testBeforeDispatchStoreIsInactive()
$this->storeCookieManagerMock->expects($this->once())
->method('deleteStoreCookie')
->with($this->storeMock);
- $this->requestMock->expects($this->atLeastOnce())
- ->method('getParam')
- ->with(StoreResolverInterface::PARAM_NAME)
- ->willReturn(null);
$this->plugin->beforeDispatch($this->subjectMock, $this->requestMock);
}
@@ -171,10 +163,6 @@ public function testBeforeDispatchInvalidArgument()
$this->storeCookieManagerMock->expects($this->once())
->method('deleteStoreCookie')
->with($this->storeMock);
- $this->requestMock->expects($this->atLeastOnce())
- ->method('getParam')
- ->with(StoreResolverInterface::PARAM_NAME)
- ->willReturn(null);
$this->plugin->beforeDispatch($this->subjectMock, $this->requestMock);
}
@@ -194,18 +182,6 @@ public function testBeforeDispatchNoStoreCookie()
->method('deleteStoreCookie')
->with($this->storeMock);
- $this->storeResolverMock->expects($this->atLeastOnce())
- ->method('getCurrentStoreId')
- ->willReturn(1);
-
- $this->storeRepositoryMock->expects($this->atLeastOnce())
- ->method('getActiveStoreById')
- ->willReturn($this->storeMock);
-
- $this->storeCookieManagerMock->expects($this->atLeastOnce())
- ->method('setStoreCookie')
- ->with($this->storeMock);
-
$this->plugin->beforeDispatch($this->subjectMock, $this->requestMock);
}
@@ -222,23 +198,6 @@ public function testBeforeDispatchWithStoreRequestParam()
->method('deleteStoreCookie')
->with($this->storeMock);
- $this->requestMock->expects($this->atLeastOnce())
- ->method('getParam')
- ->with(StoreResolverInterface::PARAM_NAME)
- ->willReturn($storeCode);
-
- $this->storeResolverMock->expects($this->atLeastOnce())
- ->method('getCurrentStoreId')
- ->willReturn(1);
-
- $this->storeRepositoryMock->expects($this->atLeastOnce())
- ->method('getActiveStoreById')
- ->willReturn($this->storeMock);
-
- $this->storeCookieManagerMock->expects($this->atLeastOnce())
- ->method('setStoreCookie')
- ->with($this->storeMock);
-
$this->plugin->beforeDispatch($this->subjectMock, $this->requestMock);
}
}
diff --git a/app/code/Magento/Store/Test/Unit/Model/Resolver/GroupTest.php b/app/code/Magento/Store/Test/Unit/Model/Resolver/GroupTest.php
index 9817bd532c18a..6fade2de934e4 100644
--- a/app/code/Magento/Store/Test/Unit/Model/Resolver/GroupTest.php
+++ b/app/code/Magento/Store/Test/Unit/Model/Resolver/GroupTest.php
@@ -53,7 +53,7 @@ public function testGetScope()
*/
public function testGetScopeWithInvalidScope()
{
- $scopeMock = new \StdClass();
+ $scopeMock = new \stdClass();
$this->storeManagerMock
->expects($this->once())
->method('getGroup')
diff --git a/app/code/Magento/Store/Test/Unit/Model/Resolver/StoreTest.php b/app/code/Magento/Store/Test/Unit/Model/Resolver/StoreTest.php
index 958cfdea37bab..50a043f45bc16 100644
--- a/app/code/Magento/Store/Test/Unit/Model/Resolver/StoreTest.php
+++ b/app/code/Magento/Store/Test/Unit/Model/Resolver/StoreTest.php
@@ -52,7 +52,7 @@ public function testGetScope()
*/
public function testGetScopeWithInvalidScope()
{
- $scopeMock = new \StdClass();
+ $scopeMock = new \stdClass();
$this->_storeManagerMock
->expects($this->once())
->method('getStore')
diff --git a/app/code/Magento/Store/Test/Unit/Model/Resolver/WebsiteTest.php b/app/code/Magento/Store/Test/Unit/Model/Resolver/WebsiteTest.php
index c5b3dbaff99be..5c33090f28eeb 100644
--- a/app/code/Magento/Store/Test/Unit/Model/Resolver/WebsiteTest.php
+++ b/app/code/Magento/Store/Test/Unit/Model/Resolver/WebsiteTest.php
@@ -52,7 +52,7 @@ public function testGetScope()
*/
public function testGetScopeWithInvalidScope()
{
- $scopeMock = new \StdClass();
+ $scopeMock = new \stdClass();
$this->_storeManagerMock
->expects($this->once())
->method('getWebsite')
diff --git a/app/code/Magento/Store/Test/Unit/Model/Service/StoreConfigManagerTest.php b/app/code/Magento/Store/Test/Unit/Model/Service/StoreConfigManagerTest.php
index 702f4eee8db99..72ee0c196b090 100644
--- a/app/code/Magento/Store/Test/Unit/Model/Service/StoreConfigManagerTest.php
+++ b/app/code/Magento/Store/Test/Unit/Model/Service/StoreConfigManagerTest.php
@@ -55,6 +55,11 @@ protected function setUp()
);
}
+ /**
+ * @param array $storeConfig
+ *
+ * @return \PHPUnit_Framework_MockObject_MockObject
+ */
protected function getStoreMock(array $storeConfig)
{
$storeMock = $this->getMockBuilder(\Magento\Store\Model\Store::class)
@@ -88,6 +93,9 @@ protected function getStoreMock(array $storeConfig)
return $storeMock;
}
+ /**
+ * @return \Magento\Store\Model\Data\StoreConfig
+ */
protected function createStoreConfigDataObject()
{
/** @var \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactoryMock */
diff --git a/app/code/Magento/Store/Test/Unit/Model/StoreManagerTest.php b/app/code/Magento/Store/Test/Unit/Model/StoreManagerTest.php
index ad3b927258717..a48804f02adc0 100644
--- a/app/code/Magento/Store/Test/Unit/Model/StoreManagerTest.php
+++ b/app/code/Magento/Store/Test/Unit/Model/StoreManagerTest.php
@@ -97,6 +97,9 @@ public function testGetStores($storesList, $withDefault, $codeKey, $expectedStor
$this->assertEquals($expectedStores, $this->model->getStores($withDefault, $codeKey));
}
+ /**
+ * @return array
+ */
public function getStoresDataProvider()
{
$defaultStoreMock = $this->getMockBuilder(\Magento\Store\Api\Data\StoreInterface::class)
diff --git a/app/code/Magento/Store/Test/Unit/Model/StoreTest.php b/app/code/Magento/Store/Test/Unit/Model/StoreTest.php
index c05584c2d8bcb..955f781a3d1ef 100644
--- a/app/code/Magento/Store/Test/Unit/Model/StoreTest.php
+++ b/app/code/Magento/Store/Test/Unit/Model/StoreTest.php
@@ -93,6 +93,9 @@ public function testLoad($key, $field)
$model->load($key);
}
+ /**
+ * @return array
+ */
public function loadDataProvider()
{
return [
@@ -264,6 +267,9 @@ function ($path, $scope, $scopeCode) use ($secure, $expectedPath) {
$this->assertEquals($expectedBaseUrl, $model->getBaseUrl($type, $secure));
}
+ /**
+ * @return array
+ */
public function getBaseUrlDataProvider()
{
return [
@@ -438,26 +444,26 @@ public function getCurrentUrlDataProvider()
[
true,
'http://test/url',
- 'http://test/url?SID=sid&___store=scope_code',
+ 'http://test/url?SID=sid&___store=scope_code',
false
],
[
true,
'http://test/url?SID=sid1&___store=scope',
- 'http://test/url?SID=sid&___store=scope_code',
+ 'http://test/url?SID=sid&___store=scope_code',
false
],
[
false,
'https://test/url',
- 'https://test/url?SID=sid&___store=scope_code',
+ 'https://test/url?SID=sid&___store=scope_code',
false
],
[
true,
'http://test/u/u.2?__store=scope_code',
'http://test/u/u.2?'
- . 'SID=sid&___store=scope_code&___from_store=old-store',
+ . 'SID=sid&___store=scope_code&___from_store=old-store',
'old-store'
]
];
@@ -602,6 +608,9 @@ public function testIsCurrentlySecure(
}
}
+ /**
+ * @return array
+ */
public function isCurrentlySecureDataProvider()
{
return [
diff --git a/app/code/Magento/Store/Test/Unit/Model/System/StoreTest.php b/app/code/Magento/Store/Test/Unit/Model/System/StoreTest.php
index d70da2ee1ddc6..9cc4bb6ac8e5b 100644
--- a/app/code/Magento/Store/Test/Unit/Model/System/StoreTest.php
+++ b/app/code/Magento/Store/Test/Unit/Model/System/StoreTest.php
@@ -104,6 +104,9 @@ public function testGetStoresStructure(
);
}
+ /**
+ * @return array
+ */
public function getStoresStructureDataProvider()
{
$websiteName = 'website';
@@ -207,6 +210,9 @@ public function testGetStoreValuesForForm(
);
}
+ /**
+ * @return array
+ */
public function getStoreValuesForFormDataProvider()
{
$websiteName = 'website';
diff --git a/app/code/Magento/Store/Test/Unit/Setup/UpgradeDataTest.php b/app/code/Magento/Store/Test/Unit/Setup/UpgradeDataTest.php
index 0dc7de4224c43..210e187b78b47 100644
--- a/app/code/Magento/Store/Test/Unit/Setup/UpgradeDataTest.php
+++ b/app/code/Magento/Store/Test/Unit/Setup/UpgradeDataTest.php
@@ -102,6 +102,9 @@ public function testUpgradeToVersion210(array $groupList, array $expectedCodes)
$this->model->upgrade($this->setupMock, $this->contextMock);
}
+ /**
+ * @return array
+ */
public function upgradeDataProvider()
{
return [
diff --git a/app/code/Magento/Store/Test/Unit/Url/Plugin/RouteParamsResolverTest.php b/app/code/Magento/Store/Test/Unit/Url/Plugin/RouteParamsResolverTest.php
index ed9ac7ebe438a..f31acd40a2e69 100644
--- a/app/code/Magento/Store/Test/Unit/Url/Plugin/RouteParamsResolverTest.php
+++ b/app/code/Magento/Store/Test/Unit/Url/Plugin/RouteParamsResolverTest.php
@@ -22,6 +22,11 @@ class RouteParamsResolverTest extends \PHPUnit\Framework\TestCase
*/
protected $queryParamsResolverMock;
+ /**
+ * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Store\Model\Store
+ */
+ protected $storeMock;
+
/**
* @var \Magento\Store\Url\Plugin\RouteParamsResolver
*/
@@ -30,7 +35,19 @@ class RouteParamsResolverTest extends \PHPUnit\Framework\TestCase
protected function setUp()
{
$this->scopeConfigMock = $this->createMock(\Magento\Framework\App\Config\ScopeConfigInterface::class);
+
+ $this->storeMock = $this->getMockBuilder(\Magento\Store\Model\Store::class)
+ ->setMethods(['getCode'])
+ ->disableOriginalConstructor()
+ ->getMock();
+ $this->storeMock->expects($this->any())->method('getCode')->willReturn('custom_store');
+
$this->storeManagerMock = $this->createMock(\Magento\Store\Model\StoreManagerInterface::class);
+ $this->storeManagerMock
+ ->expects($this->once())
+ ->method('getStore')
+ ->willReturn($this->storeMock);
+
$this->queryParamsResolverMock = $this->createMock(\Magento\Framework\Url\QueryParamsResolverInterface::class);
$this->model = new \Magento\Store\Url\Plugin\RouteParamsResolver(
$this->scopeConfigMock,
@@ -42,6 +59,8 @@ protected function setUp()
public function testBeforeSetRouteParamsScopeInParams()
{
$storeCode = 'custom_store';
+ $data = ['_scope' => $storeCode, '_scope_to_url' => true];
+
$this->scopeConfigMock
->expects($this->once())
->method('getValue')
@@ -52,7 +71,7 @@ public function testBeforeSetRouteParamsScopeInParams()
)
->will($this->returnValue(false));
$this->storeManagerMock->expects($this->any())->method('hasSingleStore')->willReturn(false);
- $data = ['_scope' => $storeCode, '_scope_to_url' => true];
+
/** @var \PHPUnit_Framework_MockObject_MockObject $routeParamsResolverMock */
$routeParamsResolverMock = $this->getMockBuilder(\Magento\Framework\Url\RouteParamsResolver::class)
->setMethods(['setScope', 'getScope'])
@@ -61,7 +80,7 @@ public function testBeforeSetRouteParamsScopeInParams()
$routeParamsResolverMock->expects($this->once())->method('setScope')->with($storeCode);
$routeParamsResolverMock->expects($this->once())->method('getScope')->willReturn($storeCode);
- $this->queryParamsResolverMock->expects($this->once())->method('setQueryParam')->with('___store', $storeCode);
+ $this->queryParamsResolverMock->expects($this->never())->method('setQueryParam');
$this->model->beforeSetRouteParams(
$routeParamsResolverMock,
@@ -72,6 +91,8 @@ public function testBeforeSetRouteParamsScopeInParams()
public function testBeforeSetRouteParamsScopeUseStoreInUrl()
{
$storeCode = 'custom_store';
+ $data = ['_scope' => $storeCode, '_scope_to_url' => true];
+
$this->scopeConfigMock
->expects($this->once())
->method('getValue')
@@ -81,8 +102,9 @@ public function testBeforeSetRouteParamsScopeUseStoreInUrl()
$storeCode
)
->will($this->returnValue(true));
+
$this->storeManagerMock->expects($this->any())->method('hasSingleStore')->willReturn(false);
- $data = ['_scope' => $storeCode, '_scope_to_url' => true];
+
/** @var \PHPUnit_Framework_MockObject_MockObject $routeParamsResolverMock */
$routeParamsResolverMock = $this->getMockBuilder(\Magento\Framework\Url\RouteParamsResolver::class)
->setMethods(['setScope', 'getScope'])
@@ -91,7 +113,7 @@ public function testBeforeSetRouteParamsScopeUseStoreInUrl()
$routeParamsResolverMock->expects($this->once())->method('setScope')->with($storeCode);
$routeParamsResolverMock->expects($this->once())->method('getScope')->willReturn($storeCode);
- $this->queryParamsResolverMock->expects($this->never())->method('setQueryParam');
+ $this->queryParamsResolverMock->expects($this->once())->method('setQueryParam')->with('___store', $storeCode);
$this->model->beforeSetRouteParams(
$routeParamsResolverMock,
@@ -102,6 +124,8 @@ public function testBeforeSetRouteParamsScopeUseStoreInUrl()
public function testBeforeSetRouteParamsSingleStore()
{
$storeCode = 'custom_store';
+ $data = ['_scope' => $storeCode, '_scope_to_url' => true];
+
$this->scopeConfigMock
->expects($this->once())
->method('getValue')
@@ -112,7 +136,7 @@ public function testBeforeSetRouteParamsSingleStore()
)
->will($this->returnValue(false));
$this->storeManagerMock->expects($this->any())->method('hasSingleStore')->willReturn(true);
- $data = ['_scope' => $storeCode, '_scope_to_url' => true];
+
/** @var \PHPUnit_Framework_MockObject_MockObject $routeParamsResolverMock */
$routeParamsResolverMock = $this->getMockBuilder(\Magento\Framework\Url\RouteParamsResolver::class)
->setMethods(['setScope', 'getScope'])
@@ -132,6 +156,8 @@ public function testBeforeSetRouteParamsSingleStore()
public function testBeforeSetRouteParamsNoScopeInParams()
{
$storeCode = 'custom_store';
+ $data = ['_scope_to_url' => true];
+
$this->scopeConfigMock
->expects($this->once())
->method('getValue')
@@ -140,17 +166,10 @@ public function testBeforeSetRouteParamsNoScopeInParams()
\Magento\Store\Model\ScopeInterface::SCOPE_STORE,
$storeCode
)
- ->will($this->returnValue(false));
+ ->will($this->returnValue(true));
+
$this->storeManagerMock->expects($this->any())->method('hasSingleStore')->willReturn(false);
- /** @var \PHPUnit_Framework_MockObject_MockObject| $routeParamsResolverMock */
- $storeMock = $this->getMockBuilder(\Magento\Store\Model\Store::class)
- ->setMethods(['getCode'])
- ->disableOriginalConstructor()
- ->getMock();
- $storeMock->expects($this->any())->method('getCode')->willReturn($storeCode);
- $this->storeManagerMock->expects($this->any())->method('getStore')->willReturn($storeMock);
- $data = ['_scope_to_url' => true];
/** @var \PHPUnit_Framework_MockObject_MockObject $routeParamsResolverMock */
$routeParamsResolverMock = $this->getMockBuilder(\Magento\Framework\Url\RouteParamsResolver::class)
->setMethods(['setScope', 'getScope'])
diff --git a/app/code/Magento/Store/Url/Plugin/RouteParamsResolver.php b/app/code/Magento/Store/Url/Plugin/RouteParamsResolver.php
index c4f8a31430963..468352af78cbc 100644
--- a/app/code/Magento/Store/Url/Plugin/RouteParamsResolver.php
+++ b/app/code/Magento/Store/Url/Plugin/RouteParamsResolver.php
@@ -6,6 +6,7 @@
namespace Magento\Store\Url\Plugin;
use \Magento\Store\Model\Store;
+use \Magento\Store\Api\Data\StoreInterface;
use \Magento\Store\Model\ScopeInterface as StoreScopeInterface;
/**
@@ -51,6 +52,8 @@ public function __construct(
* @param \Magento\Framework\Url\RouteParamsResolver $subject
* @param array $data
* @param bool $unsetOldParams
+ * @throws \Magento\Framework\Exception\NoSuchEntityException
+ *
* @return array
*/
public function beforeSetRouteParams(
@@ -63,13 +66,19 @@ public function beforeSetRouteParams(
unset($data['_scope']);
}
if (isset($data['_scope_to_url']) && (bool)$data['_scope_to_url'] === true) {
- $storeCode = $subject->getScope() ?: $this->storeManager->getStore()->getCode();
+ /** @var StoreInterface $currentScope */
+ $currentScope = $subject->getScope();
+ $storeCode = $currentScope && $currentScope instanceof StoreInterface ?
+ $currentScope->getCode() :
+ $this->storeManager->getStore()->getCode();
+
$useStoreInUrl = $this->scopeConfig->getValue(
Store::XML_PATH_STORE_IN_URL,
StoreScopeInterface::SCOPE_STORE,
$storeCode
);
- if (!$useStoreInUrl && !$this->storeManager->hasSingleStore()) {
+
+ if ($useStoreInUrl && !$this->storeManager->hasSingleStore()) {
$this->queryParamsResolver->setQueryParam('___store', $storeCode);
}
}
diff --git a/app/code/Magento/Store/composer.json b/app/code/Magento/Store/composer.json
index 3bdd93a042a96..875b4bb03d454 100644
--- a/app/code/Magento/Store/composer.json
+++ b/app/code/Magento/Store/composer.json
@@ -14,7 +14,7 @@
"magento/module-deploy": "100.2.*"
},
"type": "magento2-module",
- "version": "100.2.3",
+ "version": "100.2.4",
"license": [
"OSL-3.0",
"AFL-3.0"
diff --git a/app/code/Magento/Store/etc/di.xml b/app/code/Magento/Store/etc/di.xml
index 27133de270e2f..3d740bfee2093 100644
--- a/app/code/Magento/Store/etc/di.xml
+++ b/app/code/Magento/Store/etc/di.xml
@@ -25,6 +25,14 @@
+
+
+
+
+ - 0
+
+
+
@@ -57,7 +65,7 @@
-
+
@@ -417,4 +425,13 @@
+
+
+
+ - Magento\Store\Model\StoreSwitcher\CleanTargetUrl
+ - Magento\Store\Model\StoreSwitcher\ManageStoreCookie
+ - Magento\Store\Model\StoreSwitcher\ManagePrivateContent
+
+
+
diff --git a/app/code/Magento/Swagger/Api/Data/SchemaTypeInterface.php b/app/code/Magento/Swagger/Api/Data/SchemaTypeInterface.php
new file mode 100644
index 0000000000000..f1bc6fcc105dc
--- /dev/null
+++ b/app/code/Magento/Swagger/Api/Data/SchemaTypeInterface.php
@@ -0,0 +1,34 @@
+hasSchemaTypes()) {
+ return null;
+ }
+
+ $schemaTypeCode = $this->getRequest()->getParam(
+ 'type',
+ $this->getDefaultSchemaTypeCode()
+ );
+
+ if (!array_key_exists($schemaTypeCode, $this->getSchemaTypes())) {
+ throw new \UnexpectedValueException(
+ new Phrase('Unknown schema type supplied')
+ );
+ }
+
+ return $this->getSchemaTypes()[$schemaTypeCode];
+ }
+
+ /**
+ * @return string|null
*/
public function getSchemaUrl()
{
- return rtrim($this->getBaseUrl(), '/') . '/rest/' . $this->getParamStore() . '/schema?services=all';
+ if ($this->getSchemaType() === null) {
+ return null;
+ }
+
+ return rtrim($this->getBaseUrl(), '/') .
+ $this->getSchemaType()->getSchemaUrlPath($this->getParamStore());
}
}
diff --git a/app/code/Magento/Swagger/Controller/Index/Index.php b/app/code/Magento/Swagger/Controller/Index/Index.php
index e10a9235c4181..162367aaf81f9 100644
--- a/app/code/Magento/Swagger/Controller/Index/Index.php
+++ b/app/code/Magento/Swagger/Controller/Index/Index.php
@@ -7,6 +7,7 @@
/**
* Class Index
+ *
* @package Magento\Swagger\Controller\Index
*/
class Index extends \Magento\Framework\App\Action\Action
diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Swagger/LICENSE.txt b/app/code/Magento/Swagger/Test/Mftf/LICENSE.txt
similarity index 100%
rename from dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Swagger/LICENSE.txt
rename to app/code/Magento/Swagger/Test/Mftf/LICENSE.txt
diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Swagger/LICENSE_AFL.txt b/app/code/Magento/Swagger/Test/Mftf/LICENSE_AFL.txt
similarity index 100%
rename from dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Swagger/LICENSE_AFL.txt
rename to app/code/Magento/Swagger/Test/Mftf/LICENSE_AFL.txt
diff --git a/app/code/Magento/Swagger/Test/Mftf/README.md b/app/code/Magento/Swagger/Test/Mftf/README.md
new file mode 100644
index 0000000000000..0ec1c02814c6e
--- /dev/null
+++ b/app/code/Magento/Swagger/Test/Mftf/README.md
@@ -0,0 +1,3 @@
+# Swagger Functional Tests
+
+The Functional Test Module for **Magento Swagger** module.
diff --git a/app/code/Magento/Swagger/Test/Mftf/composer.json b/app/code/Magento/Swagger/Test/Mftf/composer.json
new file mode 100644
index 0000000000000..31cd460b41d56
--- /dev/null
+++ b/app/code/Magento/Swagger/Test/Mftf/composer.json
@@ -0,0 +1,16 @@
+{
+ "name": "magento/functional-test-module-swagger",
+ "description": "N/A",
+ "config": {
+ "sort-packages": true
+ },
+ "require": {
+ "php": "~7.0.13|~7.1.0",
+ "magento/magento2-functional-testing-framework": "2.2.0"
+ },
+ "type": "magento2-test",
+ "license": [
+ "OSL-3.0",
+ "AFL-3.0"
+ ]
+}
diff --git a/app/code/Magento/Swagger/Test/Unit/Block/IndexTest.php b/app/code/Magento/Swagger/Test/Unit/Block/IndexTest.php
new file mode 100644
index 0000000000000..df35e0807a6ab
--- /dev/null
+++ b/app/code/Magento/Swagger/Test/Unit/Block/IndexTest.php
@@ -0,0 +1,100 @@
+requestMock = $this->getMockBuilder(RequestInterface::class)->getMock();
+ $this->schemaTypeMock = $this->getMockBuilder(SchemaTypeInterface::class)->getMock();
+
+ $this->index = (new ObjectManager($this))->getObject(
+ Index::class,
+ [
+ 'context' => (new ObjectManager($this))->getObject(
+ Context::class,
+ [
+ 'request' => $this->requestMock,
+ ]
+ ),
+ 'data' => [
+ 'schema_types' => [
+ 'test' => $this->schemaTypeMock
+ ]
+ ]
+ ]
+ );
+ }
+
+ /**
+ * Test that the passed URL parameter is used when it is a valid schema type.
+ *
+ * @covers \Magento\Swagger\Block\Index::getSchemaUrl()
+ */
+ public function testGetSchemaUrlValidType()
+ {
+ $this->requestMock->expects($this->atLeastOnce())
+ ->method('getParam')
+ ->willReturn('test');
+
+ $this->schemaTypeMock->expects($this->any())
+ ->method('getCode')->willReturn('test');
+
+ $this->schemaTypeMock->expects($this->once())
+ ->method('getSchemaUrlPath')
+ ->willReturn('/test');
+
+ $this->assertEquals('/test', $this->index->getSchemaUrl());
+ }
+
+ /**
+ * Test that Swagger UI throws an exception if an invalid schema type is supplied.
+ *
+ * @covers \Magento\Swagger\Block\Index::getSchemaUrl()
+ */
+ public function testGetSchemaUrlInvalidType()
+ {
+ $this->requestMock->expects($this->atLeastOnce())
+ ->method('getParam')
+ ->willReturn('invalid');
+
+ $this->schemaTypeMock->expects($this->any())
+ ->method('getCode')->willReturn('test');
+
+ $this->expectException(\UnexpectedValueException::class);
+
+ $this->index->getSchemaUrl();
+ }
+}
diff --git a/app/code/Magento/Swagger/Test/Unit/Controller/Index/IndexTest.php b/app/code/Magento/Swagger/Test/Unit/Controller/Index/IndexTest.php
index 6931979b52f98..c409cd6ca7504 100644
--- a/app/code/Magento/Swagger/Test/Unit/Controller/Index/IndexTest.php
+++ b/app/code/Magento/Swagger/Test/Unit/Controller/Index/IndexTest.php
@@ -4,6 +4,8 @@
* See COPYING.txt for license details.
*/
+declare(strict_types=1);
+
namespace Magento\Swagger\Test\Unit\Controller\Index;
class IndexTest extends \PHPUnit\Framework\TestCase
diff --git a/app/code/Magento/Swagger/composer.json b/app/code/Magento/Swagger/composer.json
index d9f05ff961dae..b30ea4cfe46b6 100644
--- a/app/code/Magento/Swagger/composer.json
+++ b/app/code/Magento/Swagger/composer.json
@@ -6,7 +6,7 @@
"magento/framework": "101.0.*"
},
"type": "magento2-module",
- "version": "100.2.2",
+ "version": "100.2.3",
"license": [
"OSL-3.0",
"AFL-3.0"
diff --git a/app/code/Magento/Swagger/etc/module.xml b/app/code/Magento/Swagger/etc/module.xml
index 8f1086057b57e..b825e359db6dd 100644
--- a/app/code/Magento/Swagger/etc/module.xml
+++ b/app/code/Magento/Swagger/etc/module.xml
@@ -6,5 +6,9 @@
*/
-->
-
+
+
+
+
+
diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Swatches/LICENSE.txt b/app/code/Magento/SwaggerWebapi/LICENSE.txt
similarity index 100%
rename from dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Swatches/LICENSE.txt
rename to app/code/Magento/SwaggerWebapi/LICENSE.txt
diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Swatches/LICENSE_AFL.txt b/app/code/Magento/SwaggerWebapi/LICENSE_AFL.txt
similarity index 100%
rename from dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Swatches/LICENSE_AFL.txt
rename to app/code/Magento/SwaggerWebapi/LICENSE_AFL.txt
diff --git a/app/code/Magento/SwaggerWebapi/Model/SchemaType/Rest.php b/app/code/Magento/SwaggerWebapi/Model/SchemaType/Rest.php
new file mode 100644
index 0000000000000..d5a8206a324e7
--- /dev/null
+++ b/app/code/Magento/SwaggerWebapi/Model/SchemaType/Rest.php
@@ -0,0 +1,51 @@
+code = $code;
+ }
+
+ /**
+ * @return string
+ */
+ public function getCode()
+ {
+ return $this->code;
+ }
+
+ /**
+ * @param string|null $store
+ * @return string
+ */
+ public function getSchemaUrlPath($store = null)
+ {
+ $store = $store ?? 'all';
+
+ return '/' . $this->code . '/' . $store . '/schema?services=all';
+ }
+}
diff --git a/app/code/Magento/SwaggerWebapi/README.md b/app/code/Magento/SwaggerWebapi/README.md
new file mode 100644
index 0000000000000..3529848949d77
--- /dev/null
+++ b/app/code/Magento/SwaggerWebapi/README.md
@@ -0,0 +1 @@
+The Magento_SwaggerWebapi module provides the implementation of the REST Webapi module with Magento_Swagger.
\ No newline at end of file
diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SwatchesLayeredNavigation/LICENSE.txt b/app/code/Magento/SwaggerWebapi/Test/Mftf/LICENSE.txt
similarity index 100%
rename from dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SwatchesLayeredNavigation/LICENSE.txt
rename to app/code/Magento/SwaggerWebapi/Test/Mftf/LICENSE.txt
diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SwatchesLayeredNavigation/LICENSE_AFL.txt b/app/code/Magento/SwaggerWebapi/Test/Mftf/LICENSE_AFL.txt
similarity index 100%
rename from dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SwatchesLayeredNavigation/LICENSE_AFL.txt
rename to app/code/Magento/SwaggerWebapi/Test/Mftf/LICENSE_AFL.txt
diff --git a/app/code/Magento/SwaggerWebapi/Test/Mftf/README.md b/app/code/Magento/SwaggerWebapi/Test/Mftf/README.md
new file mode 100644
index 0000000000000..91d7c1522aa74
--- /dev/null
+++ b/app/code/Magento/SwaggerWebapi/Test/Mftf/README.md
@@ -0,0 +1,3 @@
+# Swagger Webapi Functional Tests
+
+The Functional Test Module for **Magento Swagger Webapi** module.
diff --git a/app/code/Magento/SwaggerWebapi/Test/Mftf/composer.json b/app/code/Magento/SwaggerWebapi/Test/Mftf/composer.json
new file mode 100644
index 0000000000000..6a2e227cd31b2
--- /dev/null
+++ b/app/code/Magento/SwaggerWebapi/Test/Mftf/composer.json
@@ -0,0 +1,17 @@
+{
+ "name": "magento/functional-test-module-swagger-webapi",
+ "description": "N/A",
+ "config": {
+ "sort-packages": true
+ },
+ "require": {
+ "php": "~7.0.13|~7.1.0",
+ "magento/magento2-functional-testing-framework": "2.2.0",
+ "magento/functional-test-module-swagger": "100.0.0-dev"
+ },
+ "type": "magento2-test",
+ "license": [
+ "OSL-3.0",
+ "AFL-3.0"
+ ]
+}
diff --git a/app/code/Magento/SwaggerWebapi/Test/Unit/Model/SchemaType/RestTest.php b/app/code/Magento/SwaggerWebapi/Test/Unit/Model/SchemaType/RestTest.php
new file mode 100644
index 0000000000000..776dd29b6832d
--- /dev/null
+++ b/app/code/Magento/SwaggerWebapi/Test/Unit/Model/SchemaType/RestTest.php
@@ -0,0 +1,66 @@
+rest = new Rest('rest');
+ }
+
+ /**
+ * @covers \Magento\SwaggerWebapi\Model\SchemaType\Rest::getSchemaUrlPath
+ *
+ * @param $expected
+ * @param null|string $store
+ *
+ * @dataProvider getSchemaUrlPathProvider
+ */
+ public function testGetSchemaUrlPath($expected, $store = null)
+ {
+ $this->assertEquals($expected, $this->rest->getSchemaUrlPath($store));
+ }
+
+ /**
+ * @covers \Magento\SwaggerWebapi\Model\SchemaType\Rest::getCode()
+ */
+ public function testGetCode()
+ {
+ $this->assertEquals('rest', $this->rest->getCode());
+ }
+
+ /**
+ * @return array
+ */
+ public function getSchemaUrlPathProvider()
+ {
+ return [
+ [
+ '/rest/all/schema?services=all',
+ null
+ ],
+ [
+ '/rest/test/schema?services=all',
+ 'test'
+ ]
+ ];
+ }
+}
diff --git a/app/code/Magento/SwaggerWebapi/composer.json b/app/code/Magento/SwaggerWebapi/composer.json
new file mode 100644
index 0000000000000..7f9b2f258d6f8
--- /dev/null
+++ b/app/code/Magento/SwaggerWebapi/composer.json
@@ -0,0 +1,23 @@
+{
+ "name": "magento/module-swagger-webapi",
+ "description": "N/A",
+ "require": {
+ "php": "~7.0.13|~7.1.0",
+ "magento/framework": "101.0.*",
+ "magento/module-swagger": "*"
+ },
+ "type": "magento2-module",
+ "version": "100.0.0",
+ "license": [
+ "OSL-3.0",
+ "AFL-3.0"
+ ],
+ "autoload": {
+ "files": [
+ "registration.php"
+ ],
+ "psr-4": {
+ "Magento\\SwaggerWebapi\\": ""
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/code/Magento/SwaggerWebapi/etc/frontend/di.xml b/app/code/Magento/SwaggerWebapi/etc/frontend/di.xml
new file mode 100644
index 0000000000000..5b54eee0faa79
--- /dev/null
+++ b/app/code/Magento/SwaggerWebapi/etc/frontend/di.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+ rest
+
+
+
\ No newline at end of file
diff --git a/app/code/Magento/SwaggerWebapi/etc/module.xml b/app/code/Magento/SwaggerWebapi/etc/module.xml
new file mode 100644
index 0000000000000..d4e319eedd296
--- /dev/null
+++ b/app/code/Magento/SwaggerWebapi/etc/module.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
diff --git a/app/code/Magento/SwaggerWebapi/registration.php b/app/code/Magento/SwaggerWebapi/registration.php
new file mode 100644
index 0000000000000..595497df7cfeb
--- /dev/null
+++ b/app/code/Magento/SwaggerWebapi/registration.php
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+ - Magento\SwaggerWebapi\Model\SchemaType\Rest
+
+ rest
+
+
+
+
diff --git a/app/code/Magento/Swatches/Controller/Adminhtml/Product/Attribute/Plugin/Save.php b/app/code/Magento/Swatches/Controller/Adminhtml/Product/Attribute/Plugin/Save.php
index dfda76372df1f..383c97a166d34 100644
--- a/app/code/Magento/Swatches/Controller/Adminhtml/Product/Attribute/Plugin/Save.php
+++ b/app/code/Magento/Swatches/Controller/Adminhtml/Product/Attribute/Plugin/Save.php
@@ -11,7 +11,7 @@
use Magento\Swatches\Model\Swatch;
/**
- * Class Save
+ * Plugin for product attribute save controller.
*/
class Save
{
@@ -24,7 +24,17 @@ class Save
public function beforeDispatch(Attribute\Save $subject, RequestInterface $request)
{
$data = $request->getPostValue();
+
if (isset($data['frontend_input'])) {
+ //Data is serialized to overcome issues caused by max_input_vars value if it's modification is unavailable.
+ //See subject controller code and comments for more info.
+ if (isset($data['serialized_swatch_values'])
+ && in_array($data['frontend_input'], ['swatch_visual', 'swatch_text'])
+ ) {
+ $data['serialized_options'] = $data['serialized_swatch_values'];
+ unset($data['serialized_swatch_values']);
+ }
+
switch ($data['frontend_input']) {
case 'swatch_visual':
$data[Swatch::SWATCH_INPUT_TYPE_KEY] = Swatch::SWATCH_INPUT_TYPE_VISUAL;
diff --git a/app/code/Magento/Swatches/Model/Plugin/EavAttribute.php b/app/code/Magento/Swatches/Model/Plugin/EavAttribute.php
index d3904f058dc2d..76bf5782d3922 100644
--- a/app/code/Magento/Swatches/Model/Plugin/EavAttribute.php
+++ b/app/code/Magento/Swatches/Model/Plugin/EavAttribute.php
@@ -10,6 +10,7 @@
use Magento\Framework\Exception\InputException;
use Magento\Framework\Serialize\Serializer\Json;
use Magento\Swatches\Model\Swatch;
+use Magento\Swatches\Model\ResourceModel\Swatch as SwatchResource;
/**
* Plugin model for Catalog Resource Attribute
@@ -18,6 +19,11 @@ class EavAttribute
{
const DEFAULT_STORE_ID = 0;
+ /**
+ * @var SwatchResource
+ */
+ private $swatchResource;
+
/**
* Base option title used for string operations to detect is option already exists or new
*/
@@ -64,17 +70,20 @@ class EavAttribute
* @param \Magento\Swatches\Model\SwatchFactory $swatchFactory
* @param \Magento\Swatches\Helper\Data $swatchHelper
* @param Json|null $serializer
+ * @param SwatchResource|null $swatchResource
*/
public function __construct(
\Magento\Swatches\Model\ResourceModel\Swatch\CollectionFactory $collectionFactory,
\Magento\Swatches\Model\SwatchFactory $swatchFactory,
\Magento\Swatches\Helper\Data $swatchHelper,
- Json $serializer = null
+ Json $serializer = null,
+ SwatchResource $swatchResource = null
) {
$this->swatchCollectionFactory = $collectionFactory;
$this->swatchFactory = $swatchFactory;
$this->swatchHelper = $swatchHelper;
$this->serializer = $serializer ?: ObjectManager::getInstance()->create(Json::class);
+ $this->swatchResource = $swatchResource ?: ObjectManager::getInstance()->create(SwatchResource::class);
}
/**
@@ -148,6 +157,7 @@ protected function setProperOptionsArray(Attribute $attribute)
* Prepare attribute for conversion from any swatch type to dropdown
*
* @param Attribute $attribute
+ * @throws \Magento\Framework\Exception\LocalizedException
* @return void
*/
protected function convertSwatchToDropdown(Attribute $attribute)
@@ -157,6 +167,7 @@ protected function convertSwatchToDropdown(Attribute $attribute)
if (!empty($additionalData)) {
$additionalData = $this->serializer->unserialize($additionalData);
if (is_array($additionalData) && isset($additionalData[Swatch::SWATCH_INPUT_TYPE_KEY])) {
+ $this->cleanEavAttributeOptionSwatchValues($attribute->getOption());
unset($additionalData[Swatch::SWATCH_INPUT_TYPE_KEY]);
$attribute->setData('additional_data', $this->serializer->serialize($additionalData));
}
@@ -235,6 +246,7 @@ protected function saveSwatchParams(Attribute $attribute)
{
if ($this->swatchHelper->isVisualSwatch($attribute)) {
$this->processVisualSwatch($attribute);
+ $this->cleanTextSwatchValuesAfterSwitch($attribute->getOptiontext());
} elseif ($this->swatchHelper->isTextSwatch($attribute)) {
$this->processTextualSwatch($attribute);
}
@@ -267,6 +279,33 @@ protected function processVisualSwatch(Attribute $attribute)
}
}
+ /**
+ * Clean swatch option values after switching to the dropdown type.
+ *
+ * @param array $attributeOptions
+ * @param null $swatchType
+ * @throws \Magento\Framework\Exception\LocalizedException
+ */
+ private function cleanEavAttributeOptionSwatchValues($attributeOptions, $swatchType = null)
+ {
+ if (count($attributeOptions) && isset($attributeOptions['value'])) {
+ $optionsIDs = array_keys($attributeOptions['value']);
+
+ $this->swatchResource->clearSwatchOptionByOptionIdAndType($optionsIDs, $swatchType);
+ }
+ }
+
+ /**
+ * Cleaning the text type of swatch option values after switching.
+ *
+ * @param array $attributeOptions
+ * @throws \Magento\Framework\Exception\LocalizedException
+ */
+ private function cleanTextSwatchValuesAfterSwitch($attributeOptions)
+ {
+ $this->cleanEavAttributeOptionSwatchValues($attributeOptions, Swatch::SWATCH_TYPE_TEXTUAL);
+ }
+
/**
* @param string $value
* @return int
diff --git a/app/code/Magento/Swatches/Model/ResourceModel/Swatch.php b/app/code/Magento/Swatches/Model/ResourceModel/Swatch.php
index 22eb1d4c7eef9..8ca694725511d 100644
--- a/app/code/Magento/Swatches/Model/ResourceModel/Swatch.php
+++ b/app/code/Magento/Swatches/Model/ResourceModel/Swatch.php
@@ -37,4 +37,24 @@ public function saveDefaultSwatchOption($id, $defaultValue)
$this->getConnection()->update($this->getTable('eav_attribute'), $bind, $where);
}
}
+
+ /**
+ * Cleaned swatch option values when switching to dropdown input type
+ *
+ * @param $optionIDs
+ * @param $type
+ * @throws \Magento\Framework\Exception\LocalizedException
+ */
+ public function clearSwatchOptionByOptionIdAndType($optionIDs, $type = null)
+ {
+ if (count($optionIDs)) {
+ foreach ($optionIDs as $optionId) {
+ $where = ['option_id' => $optionId];
+ if ($type !== null) {
+ $where['type = ?'] = $type;
+ }
+ $this->getConnection()->delete($this->getMainTable(), $where);
+ }
+ }
+ }
}
diff --git a/app/code/Magento/Swatches/Model/SwatchAttributesProvider.php b/app/code/Magento/Swatches/Model/SwatchAttributesProvider.php
index 820d8bf107d5d..2dc00fcf9a428 100644
--- a/app/code/Magento/Swatches/Model/SwatchAttributesProvider.php
+++ b/app/code/Magento/Swatches/Model/SwatchAttributesProvider.php
@@ -39,6 +39,8 @@ class SwatchAttributesProvider
private $swatchTypeChecker;
/**
+ * SwatchAttributesProvider constructor.
+ *
* @param Configurable $typeConfigurable
* @param SwatchAttributeCodes $swatchAttributeCodes
* @param SwatchAttributeType|null $swatchTypeChecker
diff --git a/app/code/Magento/Swatches/Test/Mftf/ActionGroup/CreateConfigurationsWithVisualSwatchActionGroup.xml b/app/code/Magento/Swatches/Test/Mftf/ActionGroup/CreateConfigurationsWithVisualSwatchActionGroup.xml
new file mode 100644
index 0000000000000..4eb4ca0b1327b
--- /dev/null
+++ b/app/code/Magento/Swatches/Test/Mftf/ActionGroup/CreateConfigurationsWithVisualSwatchActionGroup.xml
@@ -0,0 +1,62 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/code/Magento/Swatches/Test/Mftf/Data/SwatchAttributeData.xml b/app/code/Magento/Swatches/Test/Mftf/Data/SwatchAttributeData.xml
new file mode 100644
index 0000000000000..7822120337e1d
--- /dev/null
+++ b/app/code/Magento/Swatches/Test/Mftf/Data/SwatchAttributeData.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+ VisualSwatchAttr
+ Visual Swatch
+
+
diff --git a/app/code/Magento/Swatches/Test/Mftf/Data/SwatchOptionData.xml b/app/code/Magento/Swatches/Test/Mftf/Data/SwatchOptionData.xml
new file mode 100644
index 0000000000000..d6228512c807c
--- /dev/null
+++ b/app/code/Magento/Swatches/Test/Mftf/Data/SwatchOptionData.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+ VisualOpt1
+ VisualOpt1
+
+
+
+ VisualOpt2
+ VisualOpt2
+
+
diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Tax/LICENSE.txt b/app/code/Magento/Swatches/Test/Mftf/LICENSE.txt
similarity index 100%
rename from dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Tax/LICENSE.txt
rename to app/code/Magento/Swatches/Test/Mftf/LICENSE.txt
diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Tax/LICENSE_AFL.txt b/app/code/Magento/Swatches/Test/Mftf/LICENSE_AFL.txt
similarity index 100%
rename from dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Tax/LICENSE_AFL.txt
rename to app/code/Magento/Swatches/Test/Mftf/LICENSE_AFL.txt
diff --git a/app/code/Magento/Swatches/Test/Mftf/Page/AdminProductCreatePage.xml b/app/code/Magento/Swatches/Test/Mftf/Page/AdminProductCreatePage.xml
new file mode 100644
index 0000000000000..bce9c170899a3
--- /dev/null
+++ b/app/code/Magento/Swatches/Test/Mftf/Page/AdminProductCreatePage.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
diff --git a/app/code/Magento/Swatches/Test/Mftf/README.md b/app/code/Magento/Swatches/Test/Mftf/README.md
new file mode 100644
index 0000000000000..1bb664cc52d7a
--- /dev/null
+++ b/app/code/Magento/Swatches/Test/Mftf/README.md
@@ -0,0 +1,3 @@
+# Swatches Functional Tests
+
+The Functional Test Module for **Magento Swatches** module.
diff --git a/app/code/Magento/Swatches/Test/Mftf/Section/AdminNewAttributePanelSection.xml b/app/code/Magento/Swatches/Test/Mftf/Section/AdminNewAttributePanelSection.xml
new file mode 100644
index 0000000000000..664d318c6e831
--- /dev/null
+++ b/app/code/Magento/Swatches/Test/Mftf/Section/AdminNewAttributePanelSection.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
diff --git a/app/code/Magento/Swatches/Test/Mftf/Section/StorefrontProductInfoMainSection.xml b/app/code/Magento/Swatches/Test/Mftf/Section/StorefrontProductInfoMainSection.xml
new file mode 100644
index 0000000000000..d547d8c95d4b0
--- /dev/null
+++ b/app/code/Magento/Swatches/Test/Mftf/Section/StorefrontProductInfoMainSection.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
diff --git a/app/code/Magento/Swatches/Test/Mftf/Test/StorefrontSwatchProductWithFileCustomOptionTest.xml b/app/code/Magento/Swatches/Test/Mftf/Test/StorefrontSwatchProductWithFileCustomOptionTest.xml
new file mode 100644
index 0000000000000..1786b9bad236d
--- /dev/null
+++ b/app/code/Magento/Swatches/Test/Mftf/Test/StorefrontSwatchProductWithFileCustomOptionTest.xml
@@ -0,0 +1,94 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/code/Magento/Swatches/Test/Mftf/composer.json b/app/code/Magento/Swatches/Test/Mftf/composer.json
new file mode 100644
index 0000000000000..6c55c78bc4e53
--- /dev/null
+++ b/app/code/Magento/Swatches/Test/Mftf/composer.json
@@ -0,0 +1,28 @@
+{
+ "name": "magento/functional-test-module-swatches",
+ "description": "Add Swatches to Products",
+ "config": {
+ "sort-packages": true
+ },
+ "require": {
+ "php": "~7.0.13|~7.1.0",
+ "magento/functional-test-module-catalog": "100.0.0-dev",
+ "magento/functional-test-module-configurable-product": "100.0.0-dev",
+ "magento/functional-test-module-eav": "100.0.0-dev",
+ "magento/functional-test-module-customer": "100.0.0-dev",
+ "magento/functional-test-module-store": "100.0.0-dev",
+ "magento/functional-test-module-backend": "100.0.0-dev",
+ "magento/functional-test-module-media-storage": "100.0.0-dev",
+ "magento/functional-test-module-config": "100.0.0-dev",
+ "magento/functional-test-module-theme": "100.0.0-dev",
+ "magento/magento2-functional-testing-framework": "2.2.0"
+ },
+ "suggest": {
+ "magento/functional-test-module-layered-navigation": "100.0.0-dev",
+ "magento/functional-test-module-swatches-sample-data": "100.0.0-dev"
+ },
+ "type": "magento2-test",
+ "license": [
+ "proprietary"
+ ]
+}
diff --git a/app/code/Magento/Swatches/Test/Unit/Block/Adminhtml/Attribute/Edit/Options/AbstractSwatchTest.php b/app/code/Magento/Swatches/Test/Unit/Block/Adminhtml/Attribute/Edit/Options/AbstractSwatchTest.php
index a86c745c7c810..0d0444ddda38b 100644
--- a/app/code/Magento/Swatches/Test/Unit/Block/Adminhtml/Attribute/Edit/Options/AbstractSwatchTest.php
+++ b/app/code/Magento/Swatches/Test/Unit/Block/Adminhtml/Attribute/Edit/Options/AbstractSwatchTest.php
@@ -160,6 +160,9 @@ public function testGetStoreOptionValues($values)
$this->assertEquals($result, $values);
}
+ /**
+ * @return array
+ */
public function dataForGetStoreOptionValues()
{
return [
diff --git a/app/code/Magento/Swatches/Test/Unit/Block/Adminhtml/Product/Attribute/Edit/FormTest.php b/app/code/Magento/Swatches/Test/Unit/Block/Adminhtml/Product/Attribute/Edit/FormTest.php
index aad8741735813..168a682961bc6 100644
--- a/app/code/Magento/Swatches/Test/Unit/Block/Adminhtml/Product/Attribute/Edit/FormTest.php
+++ b/app/code/Magento/Swatches/Test/Unit/Block/Adminhtml/Product/Attribute/Edit/FormTest.php
@@ -21,6 +21,9 @@ public function testAddValues($values)
$this->assertEquals($block, $result);
}
+ /**
+ * @return array
+ */
public function dataForAddValues()
{
$additionalData = [
diff --git a/app/code/Magento/Swatches/Test/Unit/Controller/Adminhtml/Iframe/ShowTest.php b/app/code/Magento/Swatches/Test/Unit/Controller/Adminhtml/Iframe/ShowTest.php
index 19a05dad151c4..a28f3db8fb392 100644
--- a/app/code/Magento/Swatches/Test/Unit/Controller/Adminhtml/Iframe/ShowTest.php
+++ b/app/code/Magento/Swatches/Test/Unit/Controller/Adminhtml/Iframe/ShowTest.php
@@ -130,6 +130,9 @@ public function testExecute($fileResult, $expectedResult)
$this->controller->execute();
}
+ /**
+ * @return array
+ */
public function dataForExecute()
{
return [
diff --git a/app/code/Magento/Swatches/Test/Unit/Controller/Adminhtml/Product/Attribute/Plugin/SaveTest.php b/app/code/Magento/Swatches/Test/Unit/Controller/Adminhtml/Product/Attribute/Plugin/SaveTest.php
index 66f0d484c9e83..c9c826b3a7831 100644
--- a/app/code/Magento/Swatches/Test/Unit/Controller/Adminhtml/Product/Attribute/Plugin/SaveTest.php
+++ b/app/code/Magento/Swatches/Test/Unit/Controller/Adminhtml/Product/Attribute/Plugin/SaveTest.php
@@ -39,6 +39,9 @@ public function testBeforeDispatch($dataRequest, $runTimes)
$controller->beforeDispatch($subject, $request);
}
+ /**
+ * @return array
+ */
public function dataRequest()
{
return [
diff --git a/app/code/Magento/Swatches/Test/Unit/Helper/DataTest.php b/app/code/Magento/Swatches/Test/Unit/Helper/DataTest.php
index 751375813a83a..5732018f7615f 100644
--- a/app/code/Magento/Swatches/Test/Unit/Helper/DataTest.php
+++ b/app/code/Magento/Swatches/Test/Unit/Helper/DataTest.php
@@ -141,6 +141,9 @@ protected function setUp()
);
}
+ /**
+ * @return array
+ */
public function dataForAdditionalData()
{
$additionalData = [
@@ -192,6 +195,9 @@ public function testAssembleAdditionalDataEavAttribute($dataFromDb, $attributeDa
$this->swatchHelperObject->assembleAdditionalDataEavAttribute($this->attributeMock);
}
+ /**
+ * @return array
+ */
public function dataForAssembleEavAttribute()
{
$additionalData = [
@@ -236,6 +242,9 @@ public function testLoadFirstVariationWithSwatchImage($imageTypes, $expected, $r
}
}
+ /**
+ * @return array
+ */
public function dataForVariationWithSwatchImage()
{
return [
@@ -299,6 +308,9 @@ public function testLoadFirstVariationWithImage($imageTypes, $expected, $require
}
}
+ /**
+ * @return array
+ */
public function dataForVariationWithImage()
{
return [
@@ -405,6 +417,9 @@ public function testGetProductMediaGallery($mediaGallery, $image)
}
}
+ /**
+ * @return array
+ */
public function dataForMediaGallery()
{
return [
@@ -442,6 +457,10 @@ protected function getSwatchAttributes()
->willReturn($returnFromProvideMethod);
}
+ /**
+ * @param array $attributes
+ * @param array $imageTypes
+ */
protected function getUsedProducts(array $attributes, array $imageTypes)
{
$this->productMock
@@ -535,6 +554,9 @@ protected function addfilterByParent()
$zendDbSelectMock->method('where')->willReturn($zendDbSelectMock);
}
+ /**
+ * @return array
+ */
public function dataForCreateSwatchProduct()
{
$productMock = $this->createMock(\Magento\Catalog\Model\Product::class);
@@ -571,6 +593,9 @@ public function dataForCreateSwatchProduct()
];
}
+ /**
+ * @return array
+ */
public function dataForCreateSwatchProductByFallback()
{
$productMock = $this->createMock(\Magento\Catalog\Model\Product::class);
@@ -612,6 +637,9 @@ public function testGetSwatchAttributesAsArray($optionsArray, $attributeData, $e
$this->assertEquals($result, $expected);
}
+ /**
+ * @return array
+ */
public function dataForGettingSwatchAsArray()
{
return [
diff --git a/app/code/Magento/Swatches/Test/Unit/Helper/MediaTest.php b/app/code/Magento/Swatches/Test/Unit/Helper/MediaTest.php
index ca267278291e3..aed9c1da41289 100644
--- a/app/code/Magento/Swatches/Test/Unit/Helper/MediaTest.php
+++ b/app/code/Magento/Swatches/Test/Unit/Helper/MediaTest.php
@@ -114,6 +114,9 @@ public function testGetSwatchAttributeImage($swatchType, $expectedResult)
$this->assertEquals($result, $expectedResult);
}
+ /**
+ * @return array
+ */
public function dataForFullPath()
{
return [
@@ -202,6 +205,9 @@ public function testGetFolderNameSize($swatchType, $imageConfig, $expectedResult
$this->assertEquals($expectedResult, $result);
}
+ /**
+ * @return array
+ */
public function dataForFolderName()
{
return [
@@ -293,6 +299,9 @@ public function testGetSwatchCachePath($swatchType, $expectedResult)
$this->assertEquals($expectedResult, $this->mediaHelperObject->getSwatchCachePath($swatchType));
}
+ /**
+ * @return array
+ */
public function getSwatchTypes()
{
return [
diff --git a/app/code/Magento/Swatches/Test/Unit/Model/Plugin/EavAttributeTest.php b/app/code/Magento/Swatches/Test/Unit/Model/Plugin/EavAttributeTest.php
index 31a45ddb2847c..317ea77107222 100644
--- a/app/code/Magento/Swatches/Test/Unit/Model/Plugin/EavAttributeTest.php
+++ b/app/code/Magento/Swatches/Test/Unit/Model/Plugin/EavAttributeTest.php
@@ -310,6 +310,9 @@ public function testBeforeSaveNotSwatch()
$this->eavAttribute->beforeBeforeSave($this->attribute);
}
+ /**
+ * @return array
+ */
public function visualSwatchProvider()
{
return [
diff --git a/app/code/Magento/Swatches/Test/Unit/Model/Plugin/ProductImageTest.php b/app/code/Magento/Swatches/Test/Unit/Model/Plugin/ProductImageTest.php
index abec4569c81dc..3f98519ac1806 100644
--- a/app/code/Magento/Swatches/Test/Unit/Model/Plugin/ProductImageTest.php
+++ b/app/code/Magento/Swatches/Test/Unit/Model/Plugin/ProductImageTest.php
@@ -98,6 +98,9 @@ public function testBeforeGetImage($expected)
$this->assertEquals([$this->productMock, $expected['page_handle'], []], $result);
}
+ /**
+ * @param $expected
+ */
protected function canReplaceImageWithSwatch($expected)
{
$this->swatchesHelperMock
diff --git a/app/code/Magento/Swatches/Test/Unit/Model/Plugin/ProductTest.php b/app/code/Magento/Swatches/Test/Unit/Model/Plugin/ProductTest.php
index 791ba83b374c6..d7422786aec67 100644
--- a/app/code/Magento/Swatches/Test/Unit/Model/Plugin/ProductTest.php
+++ b/app/code/Magento/Swatches/Test/Unit/Model/Plugin/ProductTest.php
@@ -39,6 +39,9 @@ public function testAfterGetMediaAttributes($productType, $hasKey)
}
}
+ /**
+ * @return array
+ */
public function dataRoles()
{
return [
diff --git a/app/code/Magento/Swatches/Test/Unit/Model/SwatchAttributesProviderTest.php b/app/code/Magento/Swatches/Test/Unit/Model/SwatchAttributesProviderTest.php
index 1f69c6d5f2fa3..ec52d759ebafa 100644
--- a/app/code/Magento/Swatches/Test/Unit/Model/SwatchAttributesProviderTest.php
+++ b/app/code/Magento/Swatches/Test/Unit/Model/SwatchAttributesProviderTest.php
@@ -44,7 +44,7 @@ protected function setUp()
{
$this->typeConfigurable = $this->createPartialMock(
Configurable::class,
- ['getConfigurableAttributes', 'getCodes']
+ ['getConfigurableAttributes', 'getCodes', 'getProductAttribute']
);
$this->swatchAttributeCodes = $this->createMock(SwatchAttributeCodes::class);
@@ -65,8 +65,9 @@ public function testProvide()
$this->productMock->method('getTypeId')
->willReturn(Configurable::TYPE_CODE);
- $productAttributeMock = $this->getMockBuilder(Attribute::class)
+ $attributeMock = $this->getMockBuilder(\Magento\Catalog\Model\ResourceModel\Eav\Attribute::class)
->disableOriginalConstructor()
+ ->setMethods(['setStoreId', 'getData', 'setData', 'getSource', 'hasData'])
->getMock();
$configAttributeMock = $this->createPartialMock(
@@ -79,7 +80,7 @@ public function testProvide()
$configAttributeMock
->method('getProductAttribute')
- ->willReturn($productAttributeMock);
+ ->willReturn($attributeMock);
$this->typeConfigurable
->method('getConfigurableAttributes')
@@ -92,8 +93,9 @@ public function testProvide()
->willReturn($swatchAttributes);
$this->swatchTypeChecker->expects($this->once())->method('isSwatchAttribute')->willReturn(true);
+
$result = $this->swatchAttributeProvider->provide($this->productMock);
- $this->assertEquals([1 => $productAttributeMock], $result);
+ $this->assertEquals([1 => $attributeMock], $result);
}
}
diff --git a/app/code/Magento/Swatches/Test/Unit/Observer/AddFieldsToAttributeObserverTest.php b/app/code/Magento/Swatches/Test/Unit/Observer/AddFieldsToAttributeObserverTest.php
index 8292e0c2ed1bb..45c680366264b 100644
--- a/app/code/Magento/Swatches/Test/Unit/Observer/AddFieldsToAttributeObserverTest.php
+++ b/app/code/Magento/Swatches/Test/Unit/Observer/AddFieldsToAttributeObserverTest.php
@@ -73,6 +73,9 @@ public function testAddFields($expected)
$this->observerMock->execute($this->eventObserverMock);
}
+ /**
+ * @return array
+ */
public function dataAddFields()
{
return [
diff --git a/app/code/Magento/Swatches/Test/Unit/Observer/AddSwatchAttributeTypeObserverTest.php b/app/code/Magento/Swatches/Test/Unit/Observer/AddSwatchAttributeTypeObserverTest.php
index c24dd820e0144..f78797d93cb0d 100644
--- a/app/code/Magento/Swatches/Test/Unit/Observer/AddSwatchAttributeTypeObserverTest.php
+++ b/app/code/Magento/Swatches/Test/Unit/Observer/AddSwatchAttributeTypeObserverTest.php
@@ -66,6 +66,9 @@ public function testAddSwatchAttributeType($exp)
$this->observerMock->execute($this->eventObserverMock);
}
+ /**
+ * @return array
+ */
public function dataAddSwatch()
{
return [
diff --git a/app/code/Magento/Swatches/composer.json b/app/code/Magento/Swatches/composer.json
index 1d28fc1fcd3b9..4949931f4db2d 100644
--- a/app/code/Magento/Swatches/composer.json
+++ b/app/code/Magento/Swatches/composer.json
@@ -19,7 +19,7 @@
"magento/module-swatches-sample-data": "Sample Data version:100.2.*"
},
"type": "magento2-module",
- "version": "100.2.2",
+ "version": "100.2.3",
"license": [
"proprietary"
],
diff --git a/app/code/Magento/Swatches/etc/adminhtml/system.xml b/app/code/Magento/Swatches/etc/adminhtml/system.xml
index 7c61c240f9965..ef4c2601f2d8d 100644
--- a/app/code/Magento/Swatches/etc/adminhtml/system.xml
+++ b/app/code/Magento/Swatches/etc/adminhtml/system.xml
@@ -7,12 +7,12 @@
-->
-
-
-
+
+
+
Swatches per Product
-
+
Show Swatches in Product List
Magento\Config\Model\Config\Source\Yesno
diff --git a/app/code/Magento/Swatches/view/adminhtml/web/js/product-attributes.js b/app/code/Magento/Swatches/view/adminhtml/web/js/product-attributes.js
index ec24c11ef854d..1a58e4b6f2e7a 100644
--- a/app/code/Magento/Swatches/view/adminhtml/web/js/product-attributes.js
+++ b/app/code/Magento/Swatches/view/adminhtml/web/js/product-attributes.js
@@ -413,6 +413,8 @@ define([
};
$(function () {
+ var editForm = $('#edit_form');
+
$('#frontend_input').bind('change', function () {
swatchProductAttributes.bindAttributeInputType();
});
@@ -426,6 +428,32 @@ define([
$('.attribute-popup .collapse, [data-role="advanced_fieldset-content"]')
.collapsable()
.collapse('hide');
+
+ editForm.on('submit', function () {
+ var activePanel,
+ swatchValues = [],
+ swatchVisualPanel = $('#swatch-visual-options-panel'),
+ swatchTextPanel = $('#swatch-text-options-panel');
+
+ activePanel = swatchTextPanel.is(':visible') ? swatchTextPanel : swatchVisualPanel;
+
+ activePanel.find('table input')
+ .each(function () {
+ swatchValues.push(this.name + '=' + $(this).val());
+ });
+
+ $(' ').attr({
+ type: 'hidden',
+ name: 'serialized_swatch_values'
+ })
+ .val(JSON.stringify(swatchValues))
+ .prependTo(editForm);
+
+ [swatchVisualPanel, swatchTextPanel].forEach(function (el) {
+ $(el).find('table')
+ .replaceWith($('').text($.mage.__('Sending swatch values as package.')));
+ });
+ });
});
window.saveAttributeInNewSet = swatchProductAttributes.saveAttributeInNewSet;
diff --git a/app/code/Magento/Swatches/view/frontend/templates/product/view/renderer.phtml b/app/code/Magento/Swatches/view/frontend/templates/product/view/renderer.phtml
index ea166b9080f5c..fbd6ff15c006e 100644
--- a/app/code/Magento/Swatches/view/frontend/templates/product/view/renderer.phtml
+++ b/app/code/Magento/Swatches/view/frontend/templates/product/view/renderer.phtml
@@ -22,6 +22,9 @@
"Magento_Swatches/js/configurable-customer-data": {
"swatchOptions":
}
+ },
+ "*" : {
+ "Magento_Swatches/js/catalog-add-to-cart": {}
}
}
diff --git a/app/code/Magento/Swatches/view/frontend/web/js/catalog-add-to-cart.js b/app/code/Magento/Swatches/view/frontend/web/js/catalog-add-to-cart.js
index d699faae3a85f..ce4a364e97144 100644
--- a/app/code/Magento/Swatches/view/frontend/web/js/catalog-add-to-cart.js
+++ b/app/code/Magento/Swatches/view/frontend/web/js/catalog-add-to-cart.js
@@ -7,11 +7,22 @@ require([
], function ($) {
'use strict';
+ /**
+ * Add selected swatch attributes to redirect url
+ *
+ * @see Magento_Catalog/js/catalog-add-to-cart
+ */
$('body').on('catalogCategoryAddToCartRedirect', function (event, data) {
$(data.form).find('[name*="super"]').each(function (index, item) {
- var $item = $(item);
+ var $item = $(item),
+ attr;
- data.redirectParameters.push($item.attr('data-attr-name') + '=' + $item.val());
+ if ($item.attr('data-attr-name')) {
+ attr = $item.attr('data-attr-name');
+ } else {
+ attr = $item.parent().attr('attribute-code');
+ }
+ data.redirectParameters.push(attr + '=' + $item.val());
});
});
});
diff --git a/app/code/Magento/Swatches/view/frontend/web/js/swatch-renderer.js b/app/code/Magento/Swatches/view/frontend/web/js/swatch-renderer.js
index 2c4058e243efe..3060dfd316929 100644
--- a/app/code/Magento/Swatches/view/frontend/web/js/swatch-renderer.js
+++ b/app/code/Magento/Swatches/view/frontend/web/js/swatch-renderer.js
@@ -235,7 +235,7 @@ define([
controlLabelId: '',
// text for more button
- moreButtonText: 'More',
+ moreButtonText: $t('More'),
// Callback url for media
mediaCallback: '',
@@ -1240,8 +1240,20 @@ define([
*/
_EmulateSelected: function (selectedAttributes) {
$.each(selectedAttributes, $.proxy(function (attributeCode, optionId) {
- this.element.find('.' + this.options.classes.attributeClass +
- '[attribute-code="' + attributeCode + '"] [option-id="' + optionId + '"]').trigger('click');
+ var elem = this.element.find('.' + this.options.classes.attributeClass +
+ '[attribute-code="' + attributeCode + '"] [option-id="' + optionId + '"]'),
+ parentInput = elem.parent();
+
+ if (elem.hasClass('selected')) {
+ return;
+ }
+
+ if (parentInput.hasClass(this.options.classes.selectClass)) {
+ parentInput.val(optionId);
+ parentInput.trigger('change');
+ } else {
+ elem.trigger('click');
+ }
}, this));
},
diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/TaxImportExport/LICENSE.txt b/app/code/Magento/SwatchesLayeredNavigation/Test/Mftf/LICENSE.txt
similarity index 100%
rename from dev/tests/acceptance/tests/functional/Magento/FunctionalTest/TaxImportExport/LICENSE.txt
rename to app/code/Magento/SwatchesLayeredNavigation/Test/Mftf/LICENSE.txt
diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/TaxImportExport/LICENSE_AFL.txt b/app/code/Magento/SwatchesLayeredNavigation/Test/Mftf/LICENSE_AFL.txt
similarity index 100%
rename from dev/tests/acceptance/tests/functional/Magento/FunctionalTest/TaxImportExport/LICENSE_AFL.txt
rename to app/code/Magento/SwatchesLayeredNavigation/Test/Mftf/LICENSE_AFL.txt
diff --git a/app/code/Magento/SwatchesLayeredNavigation/Test/Mftf/README.md b/app/code/Magento/SwatchesLayeredNavigation/Test/Mftf/README.md
new file mode 100644
index 0000000000000..52402884b9f28
--- /dev/null
+++ b/app/code/Magento/SwatchesLayeredNavigation/Test/Mftf/README.md
@@ -0,0 +1,3 @@
+# Swatches Layered Navigation Functional Tests
+
+The Functional Test Module for **Magento Swatches Layered Navigation** module.
diff --git a/app/code/Magento/SwatchesLayeredNavigation/Test/Mftf/composer.json b/app/code/Magento/SwatchesLayeredNavigation/Test/Mftf/composer.json
new file mode 100644
index 0000000000000..2001b4a42691c
--- /dev/null
+++ b/app/code/Magento/SwatchesLayeredNavigation/Test/Mftf/composer.json
@@ -0,0 +1,17 @@
+{
+ "name": "magento/functional-test-module-swatches-layered-navigation",
+ "description": "N/A",
+ "config": {
+ "sort-packages": true
+ },
+ "require": {
+ "php": "~7.0.13|~7.1.0",
+ "magento/magento2-functional-testing-framework": "2.2.0",
+ "magento/magento-composer-installer": "100.0.0-dev"
+ },
+ "type": "magento2-test",
+ "license": [
+ "OSL-3.0",
+ "AFL-3.0"
+ ]
+}
diff --git a/app/code/Magento/SwatchesLayeredNavigation/composer.json b/app/code/Magento/SwatchesLayeredNavigation/composer.json
index c7bec15094136..b10747614cb90 100644
--- a/app/code/Magento/SwatchesLayeredNavigation/composer.json
+++ b/app/code/Magento/SwatchesLayeredNavigation/composer.json
@@ -7,7 +7,7 @@
"magento/magento-composer-installer": "*"
},
"type": "magento2-module",
- "version": "100.2.0",
+ "version": "100.2.1",
"license": [
"OSL-3.0",
"AFL-3.0"
diff --git a/app/code/Magento/Tax/Block/Adminhtml/Rate/Form.php b/app/code/Magento/Tax/Block/Adminhtml/Rate/Form.php
index bfc0a99de37a1..c4c4f28e8a7d1 100644
--- a/app/code/Magento/Tax/Block/Adminhtml/Rate/Form.php
+++ b/app/code/Magento/Tax/Block/Adminhtml/Rate/Form.php
@@ -33,7 +33,7 @@ class Form extends \Magento\Backend\Block\Widget\Form\Generic
/**
* @var string
*/
- protected $_template = 'rate/form.phtml';
+ protected $_template = 'Magento_Tax::rate/form.phtml';
/**
* Tax data
diff --git a/app/code/Magento/Tax/Block/Adminhtml/Rate/Title.php b/app/code/Magento/Tax/Block/Adminhtml/Rate/Title.php
index e1e866c06571b..9612b57f8d5d8 100644
--- a/app/code/Magento/Tax/Block/Adminhtml/Rate/Title.php
+++ b/app/code/Magento/Tax/Block/Adminhtml/Rate/Title.php
@@ -23,7 +23,7 @@ class Title extends \Magento\Framework\View\Element\Template
/**
* @var string
*/
- protected $_template = 'rate/title.phtml';
+ protected $_template = 'Magento_Tax::rate/title.phtml';
/**
* @var \Magento\Store\Model\StoreFactory
diff --git a/app/code/Magento/Tax/Block/Adminhtml/Rate/Toolbar/Add.php b/app/code/Magento/Tax/Block/Adminhtml/Rate/Toolbar/Add.php
index 9cf96bc21e962..16d828542c5b9 100644
--- a/app/code/Magento/Tax/Block/Adminhtml/Rate/Toolbar/Add.php
+++ b/app/code/Magento/Tax/Block/Adminhtml/Rate/Toolbar/Add.php
@@ -20,7 +20,7 @@ class Add extends \Magento\Backend\Block\Template implements \Magento\Backend\Bl
/**
* @var string
*/
- protected $_template = 'toolbar/rate/add.phtml';
+ protected $_template = 'Magento_Tax::toolbar/rate/add.phtml';
/**
* @var \Magento\Backend\Block\Widget\Button\ButtonList
diff --git a/app/code/Magento/Tax/Block/Adminhtml/Rate/Toolbar/Save.php b/app/code/Magento/Tax/Block/Adminhtml/Rate/Toolbar/Save.php
index 19c5fab72ac4b..4eaaa3be8a8f2 100644
--- a/app/code/Magento/Tax/Block/Adminhtml/Rate/Toolbar/Save.php
+++ b/app/code/Magento/Tax/Block/Adminhtml/Rate/Toolbar/Save.php
@@ -16,7 +16,7 @@ class Save extends \Magento\Backend\Block\Template implements \Magento\Backend\B
/**
* @var string
*/
- protected $_template = 'toolbar/rate/save.phtml';
+ protected $_template = 'Magento_Tax::toolbar/rate/save.phtml';
/**
* @var \Magento\Backend\Block\Widget\Button\ButtonList
diff --git a/app/code/Magento/Tax/Block/Checkout/Grandtotal.php b/app/code/Magento/Tax/Block/Checkout/Grandtotal.php
index 68de4cb24a487..77af1ad99ea2c 100644
--- a/app/code/Magento/Tax/Block/Checkout/Grandtotal.php
+++ b/app/code/Magento/Tax/Block/Checkout/Grandtotal.php
@@ -15,7 +15,7 @@ class Grandtotal extends \Magento\Checkout\Block\Total\DefaultTotal
*
* @var string
*/
- protected $_template = 'checkout/grandtotal.phtml';
+ protected $_template = 'Magento_Tax::checkout/grandtotal.phtml';
/**
* @var \Magento\Tax\Model\Config
diff --git a/app/code/Magento/Tax/Block/Checkout/Shipping.php b/app/code/Magento/Tax/Block/Checkout/Shipping.php
index e9098035053be..299c586fd224c 100644
--- a/app/code/Magento/Tax/Block/Checkout/Shipping.php
+++ b/app/code/Magento/Tax/Block/Checkout/Shipping.php
@@ -15,7 +15,7 @@ class Shipping extends \Magento\Checkout\Block\Total\DefaultTotal
*
* @var string
*/
- protected $_template = 'checkout/shipping.phtml';
+ protected $_template = 'Magento_Tax::checkout/shipping.phtml';
/**
* @var \Magento\Tax\Model\Config
diff --git a/app/code/Magento/Tax/Block/Checkout/Subtotal.php b/app/code/Magento/Tax/Block/Checkout/Subtotal.php
index 7a9059df08bab..22da07954159d 100644
--- a/app/code/Magento/Tax/Block/Checkout/Subtotal.php
+++ b/app/code/Magento/Tax/Block/Checkout/Subtotal.php
@@ -15,7 +15,7 @@ class Subtotal extends \Magento\Checkout\Block\Total\DefaultTotal
*
* @var string
*/
- protected $_template = 'checkout/subtotal.phtml';
+ protected $_template = 'Magento_Tax::checkout/subtotal.phtml';
/**
* @var \Magento\Tax\Model\Config
diff --git a/app/code/Magento/Tax/Block/Checkout/Tax.php b/app/code/Magento/Tax/Block/Checkout/Tax.php
index f741e64019de1..0a86c0312ab1c 100644
--- a/app/code/Magento/Tax/Block/Checkout/Tax.php
+++ b/app/code/Magento/Tax/Block/Checkout/Tax.php
@@ -14,5 +14,5 @@ class Tax extends \Magento\Checkout\Block\Total\DefaultTotal
/**
* @var string
*/
- protected $_template = 'checkout/tax.phtml';
+ protected $_template = 'Magento_Tax::checkout/tax.phtml';
}
diff --git a/app/code/Magento/Tax/Block/Sales/Order/Tax.php b/app/code/Magento/Tax/Block/Sales/Order/Tax.php
index 71eb629111344..4d48abbcb0982 100644
--- a/app/code/Magento/Tax/Block/Sales/Order/Tax.php
+++ b/app/code/Magento/Tax/Block/Sales/Order/Tax.php
@@ -264,12 +264,6 @@ protected function _initShipping()
*/
protected function _initDiscount()
{
- // $store = $this->getStore();
- // $parent = $this->getParentBlock();
- // if ($this->_config->displaySales) {
- //
- // } elseif ($this->_config->displaySales) {
- // }
}
/**
diff --git a/app/code/Magento/Tax/Helper/Data.php b/app/code/Magento/Tax/Helper/Data.php
index 9d31368106924..1426878d3f313 100644
--- a/app/code/Magento/Tax/Helper/Data.php
+++ b/app/code/Magento/Tax/Helper/Data.php
@@ -690,7 +690,7 @@ public function getDefaultProductTaxClass()
*/
public function isCrossBorderTradeEnabled($store = null)
{
- return (bool) $this->_config->crossBorderTradeEnabled($store);
+ return (bool)$this->_config->crossBorderTradeEnabled($store);
}
/**
@@ -733,7 +733,7 @@ protected function calculateTaxForItems(EntityInterface $order, EntityInterface
$orderItemId = $orderItem->getId();
$orderItemTax = $orderItem->getTaxAmount();
$itemTax = $item->getTaxAmount();
- if (!$itemTax || !floatval($orderItemTax)) {
+ if (!$itemTax || !(float)$orderItemTax) {
continue;
}
//An invoiced item or credit memo item can have a different qty than its order item qty
@@ -761,7 +761,7 @@ protected function calculateTaxForItems(EntityInterface $order, EntityInterface
$shippingTaxAmount = $salesItem->getShippingTaxAmount();
$originalShippingTaxAmount = $order->getShippingTaxAmount();
if ($shippingTaxAmount && $originalShippingTaxAmount &&
- $shippingTaxAmount != 0 && floatval($originalShippingTaxAmount)
+ $shippingTaxAmount != 0 && (float)$originalShippingTaxAmount
) {
//An invoice or credit memo can have a different qty than its order
$shippingRatio = $shippingTaxAmount / $originalShippingTaxAmount;
diff --git a/app/code/Magento/Tax/Model/Calculation/Rule.php b/app/code/Magento/Tax/Model/Calculation/Rule.php
index d8060590e849b..f5f7d2dc4d25a 100644
--- a/app/code/Magento/Tax/Model/Calculation/Rule.php
+++ b/app/code/Magento/Tax/Model/Calculation/Rule.php
@@ -214,7 +214,7 @@ public function getPosition()
*/
public function getCalculateSubtotal()
{
- return (bool) $this->getData(self::KEY_CALCULATE_SUBTOTAL);
+ return (bool)$this->getData(self::KEY_CALCULATE_SUBTOTAL);
}
/**
diff --git a/app/code/Magento/Tax/Model/Sales/Total/Quote/CommonTaxCollector.php b/app/code/Magento/Tax/Model/Sales/Total/Quote/CommonTaxCollector.php
index 7752911ceb22f..ff31aa4ba90cb 100644
--- a/app/code/Magento/Tax/Model/Sales/Total/Quote/CommonTaxCollector.php
+++ b/app/code/Magento/Tax/Model/Sales/Total/Quote/CommonTaxCollector.php
@@ -531,7 +531,7 @@ protected function processProductItems(
$total->setSubtotalInclTax($subtotalInclTax);
$total->setBaseSubtotalTotalInclTax($baseSubtotalInclTax);
$total->setBaseSubtotalInclTax($baseSubtotalInclTax);
- $shippingAssignment->getShipping()->getAddress()->setBaseSubtotalTotalInclTax($baseSubtotalInclTax);;
+ $shippingAssignment->getShipping()->getAddress()->setBaseSubtotalTotalInclTax($baseSubtotalInclTax);
return $this;
}
diff --git a/app/code/Magento/Tax/Model/Sales/Total/Quote/Shipping.php b/app/code/Magento/Tax/Model/Sales/Total/Quote/Shipping.php
index 16a55dbfac3e2..6e38e29decae5 100644
--- a/app/code/Magento/Tax/Model/Sales/Total/Quote/Shipping.php
+++ b/app/code/Magento/Tax/Model/Sales/Total/Quote/Shipping.php
@@ -39,16 +39,23 @@ public function collect(
$quoteDetails = $this->prepareQuoteDetails($shippingAssignment, [$shippingDataObject]);
$taxDetails = $this->taxCalculationService
->calculateTax($quoteDetails, $storeId);
+ $taxDetailsItems = $taxDetails->getItems()[self::ITEM_CODE_SHIPPING];
$baseQuoteDetails = $this->prepareQuoteDetails($shippingAssignment, [$baseShippingDataObject]);
$baseTaxDetails = $this->taxCalculationService
->calculateTax($baseQuoteDetails, $storeId);
+ $baseTaxDetailsItems = $baseTaxDetails->getItems()[self::ITEM_CODE_SHIPPING];
+
+ $quote->getShippingAddress()
+ ->setShippingAmount($taxDetailsItems->getRowTotal());
+ $quote->getShippingAddress()
+ ->setBaseShippingAmount($baseTaxDetailsItems->getRowTotal());
$this->processShippingTaxInfo(
$shippingAssignment,
$total,
- $taxDetails->getItems()[self::ITEM_CODE_SHIPPING],
- $baseTaxDetails->getItems()[self::ITEM_CODE_SHIPPING]
+ $taxDetailsItems,
+ $baseTaxDetailsItems
);
return $this;
@@ -58,6 +65,8 @@ public function collect(
* @param \Magento\Quote\Model\Quote $quote
* @param Address\Total $total
* @return array|null
+ *
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function fetch(\Magento\Quote\Model\Quote $quote, \Magento\Quote\Model\Quote\Address\Total $total)
{
diff --git a/app/code/Magento/Tax/Test/Mftf/Data/TaxConfigData.xml b/app/code/Magento/Tax/Test/Mftf/Data/TaxConfigData.xml
new file mode 100644
index 0000000000000..5edabc0826ddc
--- /dev/null
+++ b/app/code/Magento/Tax/Test/Mftf/Data/TaxConfigData.xml
@@ -0,0 +1,145 @@
+
+
+
+
+
+
+ TaxCalculationMethodBasedOn
+ TaxCalculationBasedOn
+ CatalogPrices
+ ShippingPrices
+ ApplyCustomerTax
+ ApplyDiscountOnPrices
+ ApplyTaxOn
+ EnableCrossBorderTrade
+
+ CountryUS
+ RegionCA
+ AllPostCode
+
+ DisplayPricesCart
+ DisplaySubtotalCart
+ DisplayShippingAmountCart
+ IncludeTaxInOrderTotalCart
+ DisplayFullTaxSummaryCart
+ DisplayZeroTaxSubtotalCart
+
+ DisplayPricesSales
+ DisplaySubtotalSales
+ DisplayShippingAmountSales
+ IncludeTaxInOrderTotalSales
+ DisplayFullTaxSummarySales
+ DisplayZeroTaxSubtotalSales
+
+
+
+ TOTAL_BASE_CALCULATION
+
+
+ shipping
+
+
+ 0
+
+
+ 0
+
+
+ 1
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+
+ US
+
+
+ 12
+
+
+ *
+
+
+
+ 1
+
+
+ 1
+
+
+ 1
+
+
+ 1
+
+
+ 1
+
+
+ 1
+
+
+
+ 1
+
+
+ 1
+
+
+ 1
+
+
+ 1
+
+
+ 1
+
+
+ 1
+
+
+
+ CountryUS
+ Region_CA
+ AllPostCode
+
+ IncludeTaxInOrderTotalCart
+ DisplayFullTaxSummaryCart
+ DisplayZeroTaxSubtotalCart
+
+
+
+
+ CountryUS
+ Region_NY
+ AllPostCode
+
+ IncludeTaxInOrderTotalCart
+ DisplayFullTaxSummaryCart
+ DisplayZeroTaxSubtotalCart
+
+
+
+ DefaultTotalFlagZero
+ EmptyField
+
+
+ 0
+
+
+
+
+
diff --git a/app/code/Magento/Tax/Test/Mftf/Data/TaxRegionData.xml b/app/code/Magento/Tax/Test/Mftf/Data/TaxRegionData.xml
new file mode 100644
index 0000000000000..c27225a339831
--- /dev/null
+++ b/app/code/Magento/Tax/Test/Mftf/Data/TaxRegionData.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+ 43
+
+
+ 12
+
+
diff --git a/app/code/Magento/Tax/Test/Mftf/Data/TaxRuleData.xml b/app/code/Magento/Tax/Test/Mftf/Data/TaxRuleData.xml
new file mode 100644
index 0000000000000..16c891745426d
--- /dev/null
+++ b/app/code/Magento/Tax/Test/Mftf/Data/TaxRuleData.xml
@@ -0,0 +1,26 @@
+
+
+
+
+ TaxRule
+ 0
+ 0
+
+ - 3
+
+
+ - 2
+
+
+ - 1
+ - 2
+
+ true
+
+
diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Theme/LICENSE.txt b/app/code/Magento/Tax/Test/Mftf/LICENSE.txt
similarity index 100%
rename from dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Theme/LICENSE.txt
rename to app/code/Magento/Tax/Test/Mftf/LICENSE.txt
diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Theme/LICENSE_AFL.txt b/app/code/Magento/Tax/Test/Mftf/LICENSE_AFL.txt
similarity index 100%
rename from dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Theme/LICENSE_AFL.txt
rename to app/code/Magento/Tax/Test/Mftf/LICENSE_AFL.txt
diff --git a/app/code/Magento/Tax/Test/Mftf/Metadata/tax_config-meta.xml b/app/code/Magento/Tax/Test/Mftf/Metadata/tax_config-meta.xml
new file mode 100644
index 0000000000000..af7c0dc5e16a7
--- /dev/null
+++ b/app/code/Magento/Tax/Test/Mftf/Metadata/tax_config-meta.xml
@@ -0,0 +1,230 @@
+
+
+
+
+
+
+
+
+ string
+
+
+ string
+
+
+ string
+
+
+ string
+
+
+ string
+
+
+ string
+
+
+ string
+
+
+ string
+
+
+
+
+
+
+ string
+
+
+ string
+
+
+ string
+
+
+
+
+
+
+ string
+
+
+ string
+
+
+ string
+
+
+ string
+
+
+ string
+
+
+ string
+
+
+
+
+
+
+ string
+
+
+ string
+
+
+ string
+
+
+ string
+
+
+ string
+
+
+ string
+
+
+
+
+
+
+
+
+
+
+
+ integer
+
+
+
+
+ integer
+
+
+
+
+ integer
+
+
+
+
+ integer
+
+
+
+
+ integer
+
+
+
+
+ integer
+
+
+
+
+ integer
+
+
+
+ integer
+
+
+
+
+
+
+
+ integer
+
+
+
+
+ integer
+
+
+
+ string
+
+
+
+
+
+
+
+ integer
+
+
+
+
+ integer
+
+
+
+
+ integer
+
+
+
+
+ integer
+
+
+
+
+ integer
+
+
+
+
+ integer
+
+
+
+
+
+
+
+
+ integer
+
+
+
+
+ integer
+
+
+
+
+ integer
+
+
+
+
+ integer
+
+
+
+
+ integer
+
+
+
+
+ integer
+
+
+
+
+
+
+
diff --git a/app/code/Magento/Tax/Test/Mftf/Metadata/tax_rule-meta.xml b/app/code/Magento/Tax/Test/Mftf/Metadata/tax_rule-meta.xml
new file mode 100644
index 0000000000000..f9886303fd3a3
--- /dev/null
+++ b/app/code/Magento/Tax/Test/Mftf/Metadata/tax_rule-meta.xml
@@ -0,0 +1,33 @@
+
+
+
+
+ application/json
+
+ integer
+ string
+ integer
+ integer
+
+ integer
+
+
+ integer
+
+
+ integer
+
+ boolean
+ empty_extension_attribute
+
+
+
+ application/json
+
+
diff --git a/app/code/Magento/Tax/Test/Mftf/Page/AdminTaxConfigurationPage.xml b/app/code/Magento/Tax/Test/Mftf/Page/AdminTaxConfigurationPage.xml
new file mode 100644
index 0000000000000..d18e300983b5f
--- /dev/null
+++ b/app/code/Magento/Tax/Test/Mftf/Page/AdminTaxConfigurationPage.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
diff --git a/app/code/Magento/Tax/Test/Mftf/Page/CheckoutPage.xml b/app/code/Magento/Tax/Test/Mftf/Page/CheckoutPage.xml
new file mode 100644
index 0000000000000..6f5b241ff9052
--- /dev/null
+++ b/app/code/Magento/Tax/Test/Mftf/Page/CheckoutPage.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
diff --git a/app/code/Magento/Tax/Test/Mftf/README.md b/app/code/Magento/Tax/Test/Mftf/README.md
new file mode 100644
index 0000000000000..43f3bace41c18
--- /dev/null
+++ b/app/code/Magento/Tax/Test/Mftf/README.md
@@ -0,0 +1,3 @@
+# Tax Functional Tests
+
+The Functional Test Module for **Magento Tax** module.
diff --git a/app/code/Magento/Tax/Test/Mftf/Section/AdminConfigureTaxSection.xml b/app/code/Magento/Tax/Test/Mftf/Section/AdminConfigureTaxSection.xml
new file mode 100644
index 0000000000000..28ae930d7681a
--- /dev/null
+++ b/app/code/Magento/Tax/Test/Mftf/Section/AdminConfigureTaxSection.xml
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/code/Magento/Tax/Test/Mftf/Section/CheckoutCartSummarySection.xml b/app/code/Magento/Tax/Test/Mftf/Section/CheckoutCartSummarySection.xml
new file mode 100644
index 0000000000000..e01afa52dc09a
--- /dev/null
+++ b/app/code/Magento/Tax/Test/Mftf/Section/CheckoutCartSummarySection.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
diff --git a/app/code/Magento/Tax/Test/Mftf/Section/CheckoutPaymentSection.xml b/app/code/Magento/Tax/Test/Mftf/Section/CheckoutPaymentSection.xml
new file mode 100644
index 0000000000000..8250fd5e8e39d
--- /dev/null
+++ b/app/code/Magento/Tax/Test/Mftf/Section/CheckoutPaymentSection.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
diff --git a/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxInformationInShoppingCartForCustomerPhysicalQuoteTest.xml b/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxInformationInShoppingCartForCustomerPhysicalQuoteTest.xml
new file mode 100644
index 0000000000000..1a92e6feaf705
--- /dev/null
+++ b/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxInformationInShoppingCartForCustomerPhysicalQuoteTest.xml
@@ -0,0 +1,119 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 10.00
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxInformationInShoppingCartForCustomerVirtualQuoteTest.xml b/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxInformationInShoppingCartForCustomerVirtualQuoteTest.xml
new file mode 100644
index 0000000000000..afe775fc372bc
--- /dev/null
+++ b/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxInformationInShoppingCartForCustomerVirtualQuoteTest.xml
@@ -0,0 +1,83 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 40.00
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxInformationInShoppingCartForGuestPhysicalQuoteTest.xml b/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxInformationInShoppingCartForGuestPhysicalQuoteTest.xml
new file mode 100644
index 0000000000000..893c740321314
--- /dev/null
+++ b/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxInformationInShoppingCartForGuestPhysicalQuoteTest.xml
@@ -0,0 +1,112 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 10.00
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxInformationInShoppingCartForGuestVirtualQuoteTest.xml b/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxInformationInShoppingCartForGuestVirtualQuoteTest.xml
new file mode 100644
index 0000000000000..37c1083722a25
--- /dev/null
+++ b/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxInformationInShoppingCartForGuestVirtualQuoteTest.xml
@@ -0,0 +1,76 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 40.00
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/code/Magento/Tax/Test/Mftf/composer.json b/app/code/Magento/Tax/Test/Mftf/composer.json
new file mode 100644
index 0000000000000..9701eedd15c0d
--- /dev/null
+++ b/app/code/Magento/Tax/Test/Mftf/composer.json
@@ -0,0 +1,32 @@
+{
+ "name": "magento/functional-test-module-tax",
+ "description": "N/A",
+ "config": {
+ "sort-packages": true
+ },
+ "require": {
+ "php": "~7.0.13|~7.1.0",
+ "magento/functional-test-module-config": "100.0.0-dev",
+ "magento/functional-test-module-store": "100.0.0-dev",
+ "magento/functional-test-module-catalog": "100.0.0-dev",
+ "magento/functional-test-module-customer": "100.0.0-dev",
+ "magento/functional-test-module-backend": "100.0.0-dev",
+ "magento/functional-test-module-directory": "100.0.0-dev",
+ "magento/functional-test-module-checkout": "100.0.0-dev",
+ "magento/functional-test-module-shipping": "100.0.0-dev",
+ "magento/functional-test-module-eav": "100.0.0-dev",
+ "magento/functional-test-module-sales": "100.0.0-dev",
+ "magento/functional-test-module-reports": "100.0.0-dev",
+ "magento/functional-test-module-page-cache": "100.0.0-dev",
+ "magento/functional-test-module-quote": "100.0.0-dev",
+ "magento/magento2-functional-testing-framework": "2.2.0"
+ },
+ "suggest": {
+ "magento/functional-test-module-tax-sample-data": "100.0.0-dev"
+ },
+ "type": "magento2-test",
+ "license": [
+ "OSL-3.0",
+ "AFL-3.0"
+ ]
+}
diff --git a/app/code/Magento/Tax/Test/Unit/Block/Checkout/ShippingTest.php b/app/code/Magento/Tax/Test/Unit/Block/Checkout/ShippingTest.php
index c1aa2b0c9900d..e7a11ec45ad3f 100644
--- a/app/code/Magento/Tax/Test/Unit/Block/Checkout/ShippingTest.php
+++ b/app/code/Magento/Tax/Test/Unit/Block/Checkout/ShippingTest.php
@@ -44,6 +44,9 @@ public function testDisplayShipping($shippingMethod, $expectedResult)
$this->assertEquals($expectedResult, $this->model->displayShipping());
}
+ /**
+ * @return array
+ */
public function displayShippingDataProvider()
{
return [
diff --git a/app/code/Magento/Tax/Test/Unit/Block/Item/Price/RendererTest.php b/app/code/Magento/Tax/Test/Unit/Block/Item/Price/RendererTest.php
index 1a16e69724479..90f0f09215889 100644
--- a/app/code/Magento/Tax/Test/Unit/Block/Item/Price/RendererTest.php
+++ b/app/code/Magento/Tax/Test/Unit/Block/Item/Price/RendererTest.php
@@ -96,6 +96,9 @@ public function testDisplayPriceInclTax($zone, $methodName)
$this->assertEquals($flag, $this->renderer->displayPriceInclTax());
}
+ /**
+ * @return array
+ */
public function displayPriceInclTaxDataProvider()
{
$data = [
@@ -143,6 +146,9 @@ public function testDisplayPriceExclTax($zone, $methodName)
$this->assertEquals($flag, $this->renderer->displayPriceExclTax());
}
+ /**
+ * @return array
+ */
public function displayPriceExclTaxDataProvider()
{
$data = [
@@ -190,6 +196,9 @@ public function testDisplayBothPrices($zone, $methodName)
$this->assertEquals($flag, $this->renderer->displayBothPrices());
}
+ /**
+ * @return array
+ */
public function displayBothPricesDataProvider()
{
$data = [
diff --git a/app/code/Magento/Tax/Test/Unit/Model/Calculation/RateRepositoryTest.php b/app/code/Magento/Tax/Test/Unit/Model/Calculation/RateRepositoryTest.php
index e6a29177301dd..47ec0d8732d81 100644
--- a/app/code/Magento/Tax/Test/Unit/Model/Calculation/RateRepositoryTest.php
+++ b/app/code/Magento/Tax/Test/Unit/Model/Calculation/RateRepositoryTest.php
@@ -312,6 +312,9 @@ public function testSaveThrowsExceptionIfCannotSaveTitles($expectedException, $e
$this->model->save($rateMock);
}
+ /**
+ * @return array
+ */
public function saveThrowsExceptionIfCannotSaveTitlesDataProvider()
{
return [
diff --git a/app/code/Magento/Tax/Test/Unit/Model/Plugin/OrderSaveTest.php b/app/code/Magento/Tax/Test/Unit/Model/Plugin/OrderSaveTest.php
index 912f42af0d3cd..82a473b42a82e 100644
--- a/app/code/Magento/Tax/Test/Unit/Model/Plugin/OrderSaveTest.php
+++ b/app/code/Magento/Tax/Test/Unit/Model/Plugin/OrderSaveTest.php
@@ -63,6 +63,9 @@ protected function setUp()
);
}
+ /**
+ * @return \PHPUnit_Framework_MockObject_MockObject
+ */
protected function setupOrderMock()
{
$orderMock = $this->getMockBuilder(\Magento\Sales\Model\Order::class)
@@ -80,6 +83,9 @@ protected function setupOrderMock()
return $orderMock;
}
+ /**
+ * @return \PHPUnit_Framework_MockObject_MockObject
+ */
protected function setupExtensionAttributeMock()
{
$orderExtensionAttributeMock = $this->getMockBuilder(\Magento\Sales\Api\Data\OrderExtensionInterface::class)
@@ -95,6 +101,9 @@ protected function setupExtensionAttributeMock()
return $orderExtensionAttributeMock;
}
+ /**
+ * @param $expectedTaxes
+ */
protected function verifyOrderTaxes($expectedTaxes)
{
$index = 0;
@@ -125,6 +134,9 @@ protected function verifyOrderTaxes($expectedTaxes)
}
}
+ /**
+ * @param $expectedItemTaxes
+ */
public function verifyItemTaxes($expectedItemTaxes)
{
$index = 0;
diff --git a/app/code/Magento/Tax/Test/Unit/Model/Quote/GrandTotalDetailsPluginTest.php b/app/code/Magento/Tax/Test/Unit/Model/Quote/GrandTotalDetailsPluginTest.php
index e5bd728e180f6..5e806bf36fc53 100644
--- a/app/code/Magento/Tax/Test/Unit/Model/Quote/GrandTotalDetailsPluginTest.php
+++ b/app/code/Magento/Tax/Test/Unit/Model/Quote/GrandTotalDetailsPluginTest.php
@@ -108,6 +108,11 @@ function ($value) {
);
}
+ /**
+ * @param array $data
+ *
+ * @return \PHPUnit_Framework_MockObject_MockObject
+ */
protected function setupTaxTotal(array $data)
{
$taxTotalMock = $this->getMockBuilder(\Magento\Quote\Model\Quote\Address\Total::class)
@@ -121,6 +126,11 @@ protected function setupTaxTotal(array $data)
return $taxTotalMock;
}
+ /**
+ * @param array $taxRate
+ *
+ * @return \PHPUnit_Framework_MockObject_MockObject
+ */
protected function setupTaxRateFactoryMock(array $taxRate)
{
$taxRateMock = $this->getMockBuilder(\Magento\Tax\Api\Data\GrandTotalRatesInterface::class)
@@ -142,6 +152,11 @@ protected function setupTaxRateFactoryMock(array $taxRate)
return $taxRateMock;
}
+ /**
+ * @param array $taxDetails
+ *
+ * @return \PHPUnit_Framework_MockObject_MockObject
+ */
protected function setupTaxDetails(array $taxDetails)
{
$taxDetailsMock = $this->getMockBuilder(\Magento\Tax\Api\Data\GrandTotalDetailsInterface::class)
diff --git a/app/code/Magento/Tax/Test/Unit/Model/Quote/ToOrderConverterTest.php b/app/code/Magento/Tax/Test/Unit/Model/Quote/ToOrderConverterTest.php
index 23ce032764a8f..09f82b32137b3 100644
--- a/app/code/Magento/Tax/Test/Unit/Model/Quote/ToOrderConverterTest.php
+++ b/app/code/Magento/Tax/Test/Unit/Model/Quote/ToOrderConverterTest.php
@@ -64,6 +64,9 @@ protected function setUp()
);
}
+ /**
+ * @return \PHPUnit_Framework_MockObject_MockObject
+ */
protected function setupOrderExtensionAttributeMock()
{
$orderExtensionAttributeMock = $this->getMockBuilder(\Magento\Sales\Api\Data\OrderExtensionInterface::class)
diff --git a/app/code/Magento/Tax/Test/Unit/Model/Sales/Total/Quote/CommonTaxCollectorTest.php b/app/code/Magento/Tax/Test/Unit/Model/Sales/Total/Quote/CommonTaxCollectorTest.php
index 6440751961796..9b963434e321d 100644
--- a/app/code/Magento/Tax/Test/Unit/Model/Sales/Total/Quote/CommonTaxCollectorTest.php
+++ b/app/code/Magento/Tax/Test/Unit/Model/Sales/Total/Quote/CommonTaxCollectorTest.php
@@ -183,6 +183,9 @@ public function testGetShippingDataObject(
}
}
+ /**
+ * @return array
+ */
public function getShippingDataObjectDataProvider()
{
$data = [
diff --git a/app/code/Magento/Tax/Test/Unit/Model/Sales/Total/Quote/TaxTest.php b/app/code/Magento/Tax/Test/Unit/Model/Sales/Total/Quote/TaxTest.php
index feee41c342069..3523d2828948c 100644
--- a/app/code/Magento/Tax/Test/Unit/Model/Sales/Total/Quote/TaxTest.php
+++ b/app/code/Magento/Tax/Test/Unit/Model/Sales/Total/Quote/TaxTest.php
@@ -552,6 +552,9 @@ public function testMapQuoteExtraTaxables($itemData, $addressData)
/*
* @return array
*/
+ /**
+ * @return array
+ */
public function dataProviderMapQuoteExtraTaxablesArray()
{
$data = [
diff --git a/app/code/Magento/Tax/Test/Unit/Model/System/Message/Notification/ApplyDiscountOnPricesTest.php b/app/code/Magento/Tax/Test/Unit/Model/System/Message/Notification/ApplyDiscountOnPricesTest.php
index f8cd3fce693a6..6902a59a2dab4 100644
--- a/app/code/Magento/Tax/Test/Unit/Model/System/Message/Notification/ApplyDiscountOnPricesTest.php
+++ b/app/code/Magento/Tax/Test/Unit/Model/System/Message/Notification/ApplyDiscountOnPricesTest.php
@@ -95,6 +95,9 @@ public function testIsDisplayed(
$this->assertEquals($expectedResult, $this->applyDiscountOnPricesNotification->isDisplayed());
}
+ /**
+ * @return array
+ */
public function dataProviderIsDisplayed()
{
return [
diff --git a/app/code/Magento/Tax/Test/Unit/Model/System/Message/NotificationsTest.php b/app/code/Magento/Tax/Test/Unit/Model/System/Message/NotificationsTest.php
index 3cf1421ebcf37..3fda67669fe86 100644
--- a/app/code/Magento/Tax/Test/Unit/Model/System/Message/NotificationsTest.php
+++ b/app/code/Magento/Tax/Test/Unit/Model/System/Message/NotificationsTest.php
@@ -73,6 +73,9 @@ public function testIsDisplayed(
$this->assertEquals($expectedResult, $this->notifications->isDisplayed());
}
+ /**
+ * @return array
+ */
public function dataProviderIsDisplayed()
{
return [
diff --git a/app/code/Magento/Tax/Test/Unit/Model/TaxAddressManagerTest.php b/app/code/Magento/Tax/Test/Unit/Model/TaxAddressManagerTest.php
index ec640b74f8985..493eebf9e1123 100644
--- a/app/code/Magento/Tax/Test/Unit/Model/TaxAddressManagerTest.php
+++ b/app/code/Magento/Tax/Test/Unit/Model/TaxAddressManagerTest.php
@@ -109,6 +109,9 @@ public function testSetDefaultAddressAfterSave(
$this->manager->setDefaultAddressAfterSave($address);
}
+ /**
+ * @return array
+ */
public function setAddressCustomerSessionAddressSaveDataProvider()
{
return [
@@ -151,6 +154,9 @@ public function testSetDefaultAddressAfterLogIn(
$this->manager->setDefaultAddressAfterLogIn([$address]);
}
+ /**
+ * @return array
+ */
public function setAddressCustomerSessionLogInDataProvider()
{
return [
diff --git a/app/code/Magento/Tax/Test/Unit/Model/TaxClass/FactoryTest.php b/app/code/Magento/Tax/Test/Unit/Model/TaxClass/FactoryTest.php
index eb107c248880b..d46c9996c390c 100644
--- a/app/code/Magento/Tax/Test/Unit/Model/TaxClass/FactoryTest.php
+++ b/app/code/Magento/Tax/Test/Unit/Model/TaxClass/FactoryTest.php
@@ -39,6 +39,9 @@ public function testCreate($classType, $className, $classTypeMock)
$this->assertEquals($classTypeMock, $taxClassFactory->create($classMock));
}
+ /**
+ * @return array
+ */
public function createDataProvider()
{
$customerClassMock = $this->createMock(\Magento\Tax\Model\TaxClass\Type\Customer::class);
diff --git a/app/code/Magento/Tax/Test/Unit/Model/TaxClass/Type/CustomerTest.php b/app/code/Magento/Tax/Test/Unit/Model/TaxClass/Type/CustomerTest.php
index fc27e68c8e55b..707b999c5e467 100644
--- a/app/code/Magento/Tax/Test/Unit/Model/TaxClass/Type/CustomerTest.php
+++ b/app/code/Magento/Tax/Test/Unit/Model/TaxClass/Type/CustomerTest.php
@@ -26,9 +26,9 @@ public function testIsAssignedToObjects()
$filterBuilder->expects($this->once())->method('setField')->with(
\Magento\Customer\Api\Data\GroupInterface::TAX_CLASS_ID
- )->willReturnself();
- $filterBuilder->expects($this->once())->method('setValue')->willReturnself();
- $filterBuilder->expects($this->once())->method('create')->willReturnself();
+ )->willReturnSelf();
+ $filterBuilder->expects($this->once())->method('setValue')->willReturnSelf();
+ $filterBuilder->expects($this->once())->method('create')->willReturnSelf();
$filterGroupBuilder = $this->createMock(\Magento\Framework\Api\Search\FilterGroupBuilder::class);
$searchCriteriaBuilder = $this->getMockBuilder(\Magento\Framework\Api\SearchCriteriaBuilder::class)
diff --git a/app/code/Magento/Tax/Test/Unit/Model/TaxRuleRepositoryTest.php b/app/code/Magento/Tax/Test/Unit/Model/TaxRuleRepositoryTest.php
index f4151cd18ba66..3fddd5da47611 100644
--- a/app/code/Magento/Tax/Test/Unit/Model/TaxRuleRepositoryTest.php
+++ b/app/code/Magento/Tax/Test/Unit/Model/TaxRuleRepositoryTest.php
@@ -168,6 +168,9 @@ public function testSaveWithExceptions($exceptionObject, $exceptionName, $except
$this->model->save($rule);
}
+ /**
+ * @return array
+ */
public function saveExceptionsDataProvider()
{
return [
diff --git a/app/code/Magento/Tax/Test/Unit/Observer/AfterAddressSaveObserverTest.php b/app/code/Magento/Tax/Test/Unit/Observer/AfterAddressSaveObserverTest.php
index 14d678d02366b..96b4b81ae2817 100644
--- a/app/code/Magento/Tax/Test/Unit/Observer/AfterAddressSaveObserverTest.php
+++ b/app/code/Magento/Tax/Test/Unit/Observer/AfterAddressSaveObserverTest.php
@@ -138,6 +138,9 @@ public function testExecute(
$this->session->execute($this->observerMock);
}
+ /**
+ * @return array
+ */
public function getExecuteDataProvider()
{
return [
diff --git a/app/code/Magento/Tax/Test/Unit/Pricing/AdjustmentTest.php b/app/code/Magento/Tax/Test/Unit/Pricing/AdjustmentTest.php
index a92aa6a0d05eb..e7557e2164ca0 100644
--- a/app/code/Magento/Tax/Test/Unit/Pricing/AdjustmentTest.php
+++ b/app/code/Magento/Tax/Test/Unit/Pricing/AdjustmentTest.php
@@ -56,6 +56,9 @@ public function testIsIncludedInBasePrice($expectedResult)
$this->assertEquals($expectedResult, $this->adjustment->isIncludedInBasePrice());
}
+ /**
+ * @return array
+ */
public function isIncludedInBasePriceDataProvider()
{
return [[true], [false]];
@@ -113,6 +116,9 @@ public function testExtractAdjustment($isPriceIncludesTax, $amount, $price, $exp
$this->assertEquals($expectedResult, $this->adjustment->extractAdjustment($amount, $object));
}
+ /**
+ * @return array
+ */
public function extractAdjustmentDataProvider()
{
return [
@@ -164,6 +170,9 @@ public function testIsExcludedWith($adjustmentCode, $expectedResult)
$this->assertEquals($expectedResult, $this->adjustment->isExcludedWith($adjustmentCode));
}
+ /**
+ * @return array
+ */
public function isExcludedWithDataProvider()
{
return [
diff --git a/app/code/Magento/Tax/composer.json b/app/code/Magento/Tax/composer.json
index 1e0fc3be38b0f..6ac542c04e3d4 100644
--- a/app/code/Magento/Tax/composer.json
+++ b/app/code/Magento/Tax/composer.json
@@ -22,7 +22,7 @@
"magento/module-tax-sample-data": "Sample Data version:100.2.*"
},
"type": "magento2-module",
- "version": "100.2.4",
+ "version": "100.2.5",
"license": [
"OSL-3.0",
"AFL-3.0"
diff --git a/app/code/Magento/Tax/etc/adminhtml/system.xml b/app/code/Magento/Tax/etc/adminhtml/system.xml
index c03a8aa44bf7b..7fc1744b8e27e 100644
--- a/app/code/Magento/Tax/etc/adminhtml/system.xml
+++ b/app/code/Magento/Tax/etc/adminhtml/system.xml
@@ -62,7 +62,7 @@
Magento\Tax\Model\Config\Notification
Warning: To apply the discount on prices including tax and apply the tax after discount, set Catalog Prices to “Including Tax”.
-
+
Apply Tax On
Magento\Tax\Model\Config\Source\Apply\On
diff --git a/app/code/Magento/TaxImportExport/Block/Adminhtml/Rate/ImportExport.php b/app/code/Magento/TaxImportExport/Block/Adminhtml/Rate/ImportExport.php
index a42877b3ecf8a..ab64567f4fe28 100644
--- a/app/code/Magento/TaxImportExport/Block/Adminhtml/Rate/ImportExport.php
+++ b/app/code/Magento/TaxImportExport/Block/Adminhtml/Rate/ImportExport.php
@@ -14,7 +14,7 @@ class ImportExport extends \Magento\Backend\Block\Widget
/**
* @var string
*/
- protected $_template = 'importExport.phtml';
+ protected $_template = 'Magento_TaxImportExport::importExport.phtml';
/**
* @param \Magento\Backend\Block\Template\Context $context
diff --git a/app/code/Magento/TaxImportExport/Block/Adminhtml/Rate/ImportExportHeader.php b/app/code/Magento/TaxImportExport/Block/Adminhtml/Rate/ImportExportHeader.php
index 8897e9b2083e9..e223adc3adb1a 100644
--- a/app/code/Magento/TaxImportExport/Block/Adminhtml/Rate/ImportExportHeader.php
+++ b/app/code/Magento/TaxImportExport/Block/Adminhtml/Rate/ImportExportHeader.php
@@ -16,5 +16,5 @@ class ImportExportHeader extends \Magento\Backend\Block\Widget
*
* @var string
*/
- protected $_template = 'importExportHeader.phtml';
+ protected $_template = 'Magento_TaxImportExport::importExportHeader.phtml';
}
diff --git a/app/code/Magento/TaxImportExport/Model/Rate/CsvImportHandler.php b/app/code/Magento/TaxImportExport/Model/Rate/CsvImportHandler.php
index 8ec871a182ab4..c8cba30c9cd25 100644
--- a/app/code/Magento/TaxImportExport/Model/Rate/CsvImportHandler.php
+++ b/app/code/Magento/TaxImportExport/Model/Rate/CsvImportHandler.php
@@ -237,7 +237,7 @@ protected function _importRate(array $rateData, array $regionsCache, array $stor
$countryCode = $rateData[1];
$country = $this->_countryFactory->create()->loadByCode($countryCode, 'iso2_code');
if (!$country->getId()) {
- throw new \Magento\Framework\Exception\LocalizedException(__('One of the countries has invalid code.'));
+ throw new \Magento\Framework\Exception\LocalizedException(__('Country code is invalid: %1', $countryCode));
}
$regionsCache = $this->_addCountryRegionsToCache($countryCode, $regionsCache);
diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Translation/LICENSE.txt b/app/code/Magento/TaxImportExport/Test/Mftf/LICENSE.txt
similarity index 100%
rename from dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Translation/LICENSE.txt
rename to app/code/Magento/TaxImportExport/Test/Mftf/LICENSE.txt
diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Translation/LICENSE_AFL.txt b/app/code/Magento/TaxImportExport/Test/Mftf/LICENSE_AFL.txt
similarity index 100%
rename from dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Translation/LICENSE_AFL.txt
rename to app/code/Magento/TaxImportExport/Test/Mftf/LICENSE_AFL.txt
diff --git a/app/code/Magento/TaxImportExport/Test/Mftf/README.md b/app/code/Magento/TaxImportExport/Test/Mftf/README.md
new file mode 100644
index 0000000000000..e53dd041cb34a
--- /dev/null
+++ b/app/code/Magento/TaxImportExport/Test/Mftf/README.md
@@ -0,0 +1,3 @@
+# Tax Import Export Functional Tests
+
+The Functional Test Module for **Magento Tax Import Export** module.
diff --git a/app/code/Magento/TaxImportExport/Test/Mftf/composer.json b/app/code/Magento/TaxImportExport/Test/Mftf/composer.json
new file mode 100644
index 0000000000000..00dec78135e89
--- /dev/null
+++ b/app/code/Magento/TaxImportExport/Test/Mftf/composer.json
@@ -0,0 +1,20 @@
+{
+ "name": "magento/functional-test-module-tax-import-export",
+ "description": "N/A",
+ "config": {
+ "sort-packages": true
+ },
+ "require": {
+ "php": "~7.0.13|~7.1.0",
+ "magento/functional-test-module-tax": "100.0.0-dev",
+ "magento/functional-test-module-backend": "100.0.0-dev",
+ "magento/functional-test-module-directory": "100.0.0-dev",
+ "magento/functional-test-module-store": "100.0.0-dev",
+ "magento/magento2-functional-testing-framework": "2.2.0"
+ },
+ "type": "magento2-test",
+ "license": [
+ "OSL-3.0",
+ "AFL-3.0"
+ ]
+}
diff --git a/app/code/Magento/TaxImportExport/composer.json b/app/code/Magento/TaxImportExport/composer.json
index 3cb9f7dfce09b..9be5e65dd6364 100644
--- a/app/code/Magento/TaxImportExport/composer.json
+++ b/app/code/Magento/TaxImportExport/composer.json
@@ -10,7 +10,7 @@
"magento/framework": "101.0.*"
},
"type": "magento2-module",
- "version": "100.2.0",
+ "version": "100.2.1",
"license": [
"OSL-3.0",
"AFL-3.0"
diff --git a/app/code/Magento/TaxImportExport/i18n/en_US.csv b/app/code/Magento/TaxImportExport/i18n/en_US.csv
index cadecc39a391c..40db8846b54cb 100644
--- a/app/code/Magento/TaxImportExport/i18n/en_US.csv
+++ b/app/code/Magento/TaxImportExport/i18n/en_US.csv
@@ -12,7 +12,7 @@ Rate,Rate
"Invalid file upload attempt","Invalid file upload attempt"
"Invalid file upload attempt.","Invalid file upload attempt."
"Invalid file format.","Invalid file format."
-"One of the countries has invalid code.","One of the countries has invalid code."
+"Country code is invalid: %1","Country code is invalid: %1"
"Import Tax Rates","Import Tax Rates"
"Export Tax Rates","Export Tax Rates"
CSV,CSV
diff --git a/app/code/Magento/Theme/Block/Adminhtml/Wysiwyg/Files/Content/Uploader.php b/app/code/Magento/Theme/Block/Adminhtml/Wysiwyg/Files/Content/Uploader.php
index 8e7f4c9cc680c..5281da40b0543 100644
--- a/app/code/Magento/Theme/Block/Adminhtml/Wysiwyg/Files/Content/Uploader.php
+++ b/app/code/Magento/Theme/Block/Adminhtml/Wysiwyg/Files/Content/Uploader.php
@@ -3,6 +3,8 @@
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
+declare(strict_types=1);
+
namespace Magento\Theme\Block\Adminhtml\Wysiwyg\Files\Content;
/**
@@ -19,7 +21,7 @@ class Uploader extends \Magento\Backend\Block\Media\Uploader
*
* @var string
*/
- protected $_template = 'browser/content/uploader.phtml';
+ protected $_template = 'Magento_Theme::browser/content/uploader.phtml';
/**
* @var \Magento\Theme\Helper\Storage
@@ -39,6 +41,7 @@ public function __construct(
array $data = []
) {
$this->_storageHelper = $storageHelper;
+
parent::__construct($context, $fileSize, $data);
}
diff --git a/app/code/Magento/Theme/Block/Html/Breadcrumbs.php b/app/code/Magento/Theme/Block/Html/Breadcrumbs.php
index c1f8ea620ef41..cff87fc8726bd 100644
--- a/app/code/Magento/Theme/Block/Html/Breadcrumbs.php
+++ b/app/code/Magento/Theme/Block/Html/Breadcrumbs.php
@@ -21,7 +21,7 @@ class Breadcrumbs extends \Magento\Framework\View\Element\Template
*
* @var string
*/
- protected $_template = 'html/breadcrumbs.phtml';
+ protected $_template = 'Magento_Theme::html/breadcrumbs.phtml';
/**
* List of available breadcrumb properties
diff --git a/app/code/Magento/Theme/Block/Html/Header.php b/app/code/Magento/Theme/Block/Html/Header.php
index f597b4034da92..2663a4da15011 100644
--- a/app/code/Magento/Theme/Block/Html/Header.php
+++ b/app/code/Magento/Theme/Block/Html/Header.php
@@ -19,7 +19,7 @@ class Header extends \Magento\Framework\View\Element\Template
*
* @var string
*/
- protected $_template = 'html/header.phtml';
+ protected $_template = 'Magento_Theme::html/header.phtml';
/**
* Retrieve welcome text
diff --git a/app/code/Magento/Theme/Block/Html/Header/Logo.php b/app/code/Magento/Theme/Block/Html/Header/Logo.php
index 5b0c2eaf04c45..0a0e71f44ba32 100644
--- a/app/code/Magento/Theme/Block/Html/Header/Logo.php
+++ b/app/code/Magento/Theme/Block/Html/Header/Logo.php
@@ -19,7 +19,7 @@ class Logo extends \Magento\Framework\View\Element\Template
*
* @var string
*/
- protected $_template = 'html/header/logo.phtml';
+ protected $_template = 'Magento_Theme::html/header/logo.phtml';
/**
* @var \Magento\MediaStorage\Helper\File\Storage\Database
diff --git a/app/code/Magento/Theme/Controller/Adminhtml/Design/Config/Save.php b/app/code/Magento/Theme/Controller/Adminhtml/Design/Config/Save.php
index 657fbb25795d9..f4dee5834a923 100644
--- a/app/code/Magento/Theme/Controller/Adminhtml/Design/Config/Save.php
+++ b/app/code/Magento/Theme/Controller/Adminhtml/Design/Config/Save.php
@@ -3,6 +3,7 @@
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
+
namespace Magento\Theme\Controller\Adminhtml\Design\Config;
use Magento\Backend\App\Action;
@@ -71,9 +72,12 @@ public function execute()
$data = $this->getRequestData();
try {
+ if (!$this->getRequest()->isPost()) {
+ throw new LocalizedException(__('Wrong request.'));
+ }
$designConfigData = $this->configFactory->create($scope, $scopeId, $data);
$this->designConfigRepository->save($designConfigData);
- $this->messageManager->addSuccess(__('You saved the configuration.'));
+ $this->messageManager->addSuccessMessage(__('You saved the configuration.'));
$this->dataPersistor->clear('theme_design_config');
@@ -86,10 +90,10 @@ public function execute()
} catch (LocalizedException $e) {
$messages = explode("\n", $e->getMessage());
foreach ($messages as $message) {
- $this->messageManager->addError(__('%1', $message));
+ $this->messageManager->addErrorMessage(__('%1', $message));
}
} catch (\Exception $e) {
- $this->messageManager->addException(
+ $this->messageManager->addExceptionMessage(
$e,
__('Something went wrong while saving this configuration:') . ' ' . $e->getMessage()
);
@@ -113,7 +117,7 @@ protected function getRequestData()
$this->getRequest()->getFiles()->toArray()
);
$data = array_filter($data, function ($param) {
- return isset($param['error']) && $param['error'] > 0 ? false : true;
+ return !(isset($param['error']) && $param['error'] > 0);
});
/**
diff --git a/app/code/Magento/Theme/Controller/Result/MessagePlugin.php b/app/code/Magento/Theme/Controller/Result/MessagePlugin.php
index 145493b8e44d8..83172df748a47 100644
--- a/app/code/Magento/Theme/Controller/Result/MessagePlugin.php
+++ b/app/code/Magento/Theme/Controller/Result/MessagePlugin.php
@@ -5,9 +5,12 @@
*/
namespace Magento\Theme\Controller\Result;
+use Magento\Framework\App\ObjectManager;
use Magento\Framework\Controller\Result\Json;
use Magento\Framework\Controller\ResultInterface;
use Magento\Framework\Message\MessageInterface;
+use Magento\Framework\Translate\Inline\ParserInterface;
+use Magento\Framework\Translate\InlineInterface;
/**
* Plugin for putting messages to cookies
@@ -44,26 +47,34 @@ class MessagePlugin
*/
private $serializer;
+ /**
+ * @var InlineInterface
+ */
+ private $inlineTranslate;
+
/**
* @param \Magento\Framework\Stdlib\CookieManagerInterface $cookieManager
* @param \Magento\Framework\Stdlib\Cookie\CookieMetadataFactory $cookieMetadataFactory
* @param \Magento\Framework\Message\ManagerInterface $messageManager
* @param \Magento\Framework\View\Element\Message\InterpretationStrategyInterface $interpretationStrategy
* @param \Magento\Framework\Serialize\Serializer\Json|null $serializer
+ * @param InlineInterface|null $inlineTranslate
*/
public function __construct(
\Magento\Framework\Stdlib\CookieManagerInterface $cookieManager,
\Magento\Framework\Stdlib\Cookie\CookieMetadataFactory $cookieMetadataFactory,
\Magento\Framework\Message\ManagerInterface $messageManager,
\Magento\Framework\View\Element\Message\InterpretationStrategyInterface $interpretationStrategy,
- \Magento\Framework\Serialize\Serializer\Json $serializer = null
+ \Magento\Framework\Serialize\Serializer\Json $serializer = null,
+ InlineInterface $inlineTranslate = null
) {
$this->cookieManager = $cookieManager;
$this->cookieMetadataFactory = $cookieMetadataFactory;
$this->messageManager = $messageManager;
- $this->serializer = $serializer ?: \Magento\Framework\App\ObjectManager::getInstance()
+ $this->serializer = $serializer ?: ObjectManager::getInstance()
->get(\Magento\Framework\Serialize\Serializer\Json::class);
$this->interpretationStrategy = $interpretationStrategy;
+ $this->inlineTranslate = $inlineTranslate ?: ObjectManager::getInstance()->get(InlineInterface::class);
}
/**
@@ -112,6 +123,12 @@ public function afterRenderResult(
private function setCookie(array $messages)
{
if (!empty($messages)) {
+ if ($this->inlineTranslate->isAllowed()) {
+ foreach ($messages as &$message) {
+ $message['text'] = $this->convertMessageText($message['text']);
+ }
+ }
+
$publicCookieMetadata = $this->cookieMetadataFactory->createPublicCookieMetadata();
$publicCookieMetadata->setDurationOneYear();
$publicCookieMetadata->setPath('/');
@@ -125,6 +142,21 @@ private function setCookie(array $messages)
}
}
+ /**
+ * Replace wrapping translation with html body.
+ *
+ * @param string $text
+ * @return string
+ */
+ private function convertMessageText(string $text): string
+ {
+ if (preg_match('#' . ParserInterface::REGEXP_TOKEN . '#', $text, $matches)) {
+ $text = $matches[1];
+ }
+
+ return $text;
+ }
+
/**
* Return messages array and clean message manager messages
*
diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Ui/LICENSE.txt b/app/code/Magento/Theme/Test/Mftf/LICENSE.txt
similarity index 100%
rename from dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Ui/LICENSE.txt
rename to app/code/Magento/Theme/Test/Mftf/LICENSE.txt
diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Ui/LICENSE_AFL.txt b/app/code/Magento/Theme/Test/Mftf/LICENSE_AFL.txt
similarity index 100%
rename from dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Ui/LICENSE_AFL.txt
rename to app/code/Magento/Theme/Test/Mftf/LICENSE_AFL.txt
diff --git a/app/code/Magento/Theme/Test/Mftf/README.md b/app/code/Magento/Theme/Test/Mftf/README.md
new file mode 100644
index 0000000000000..25b16385c3eca
--- /dev/null
+++ b/app/code/Magento/Theme/Test/Mftf/README.md
@@ -0,0 +1,3 @@
+# Theme Functional Tests
+
+The Functional Test Module for **Magento Theme** module.
diff --git a/app/code/Magento/Theme/Test/Mftf/composer.json b/app/code/Magento/Theme/Test/Mftf/composer.json
new file mode 100644
index 0000000000000..d45c901981449
--- /dev/null
+++ b/app/code/Magento/Theme/Test/Mftf/composer.json
@@ -0,0 +1,32 @@
+{
+ "name": "magento/functional-test-module-theme",
+ "description": "N/A",
+ "config": {
+ "sort-packages": true
+ },
+ "require": {
+ "php": "~7.0.13|~7.1.0",
+ "magento/functional-test-module-store": "100.0.0-dev",
+ "magento/functional-test-module-customer": "100.0.0-dev",
+ "magento/functional-test-module-backend": "100.0.0-dev",
+ "magento/functional-test-module-cms": "100.0.0-dev",
+ "magento/functional-test-module-eav": "100.0.0-dev",
+ "magento/functional-test-module-widget": "100.0.0-dev",
+ "magento/functional-test-module-config": "100.0.0-dev",
+ "magento/functional-test-module-media-storage": "100.0.0-dev",
+ "magento/functional-test-module-ui": "100.0.0-dev",
+ "magento/magento2-functional-testing-framework": "2.2.0",
+ "magento/functional-test-module-require-js": "100.0.0-dev"
+ },
+ "suggest": {
+ "magento/functional-test-module-translation": "100.0.0-dev",
+ "magento/functional-test-module-theme-sample-data": "100.0.0-dev",
+ "magento/functional-test-module-deploy": "100.0.0-dev",
+ "magento/functional-test-module-directory": "100.0.0-dev"
+ },
+ "type": "magento2-test",
+ "license": [
+ "OSL-3.0",
+ "AFL-3.0"
+ ]
+}
diff --git a/app/code/Magento/Theme/Test/Unit/Block/Html/TopmenuTest.php b/app/code/Magento/Theme/Test/Unit/Block/Html/TopmenuTest.php
index 49066e79cb798..91c3ce47fc8b8 100644
--- a/app/code/Magento/Theme/Test/Unit/Block/Html/TopmenuTest.php
+++ b/app/code/Magento/Theme/Test/Unit/Block/Html/TopmenuTest.php
@@ -109,6 +109,9 @@ protected function setUp()
);
}
+ /**
+ * @return Topmenu
+ */
protected function getTopmenu()
{
return new Topmenu($this->context, $this->nodeFactory, $this->treeFactory);
diff --git a/app/code/Magento/Theme/Test/Unit/Console/Command/ThemeUninstallCommandTest.php b/app/code/Magento/Theme/Test/Unit/Console/Command/ThemeUninstallCommandTest.php
index 2ae889e69bb12..36daf7d4aff48 100644
--- a/app/code/Magento/Theme/Test/Unit/Console/Command/ThemeUninstallCommandTest.php
+++ b/app/code/Magento/Theme/Test/Unit/Console/Command/ThemeUninstallCommandTest.php
@@ -8,7 +8,7 @@
use Magento\Framework\App\Console\MaintenanceModeEnabler;
use Magento\Theme\Console\Command\ThemeUninstallCommand;
-use Magento\Theme\Model\Theme\themePackageInfo;
+use Magento\Theme\Model\Theme\ThemePackageInfo;
use Magento\Theme\Model\Theme\ThemeUninstaller;
use Magento\Theme\Model\Theme\ThemeDependencyChecker;
use Symfony\Component\Console\Tester\CommandTester;
diff --git a/app/code/Magento/Theme/Test/Unit/Controller/Adminhtml/Design/Config/SaveTest.php b/app/code/Magento/Theme/Test/Unit/Controller/Adminhtml/Design/Config/SaveTest.php
index f90e24678d9e0..89d8dab67d495 100644
--- a/app/code/Magento/Theme/Test/Unit/Controller/Adminhtml/Design/Config/SaveTest.php
+++ b/app/code/Magento/Theme/Test/Unit/Controller/Adminhtml/Design/Config/SaveTest.php
@@ -62,15 +62,13 @@ public function setUp()
'',
false
);
- $this->request = $this->getMockForAbstractClass(
- \Magento\Framework\App\RequestInterface::class,
- [],
- '',
- false,
- false,
- true,
- ['getFiles', 'getParam', 'getParams']
- );
+ $this->request = $this->getMockBuilder(\Magento\Framework\App\Request\Http::class)
+ ->disableOriginalConstructor()->getMock();
+
+ $this->request->expects($this->any())
+ ->method('isPost')
+ ->willReturn(true);
+
$this->context = $objectManager->getObject(
\Magento\Backend\App\Action\Context::class,
[
@@ -138,7 +136,7 @@ public function testSave()
->method('save')
->with($this->designConfig);
$this->messageManager->expects($this->once())
- ->method('addSuccess')
+ ->method('addSuccessMessage')
->with(__('You saved the configuration.'));
$this->dataPersistor->expects($this->once())
->method('clear')
@@ -194,7 +192,7 @@ public function testSaveWithLocalizedException()
->with($this->designConfig)
->willThrowException(new \Magento\Framework\Exception\LocalizedException(__('Exception message')));
$this->messageManager->expects($this->once())
- ->method('addError')
+ ->method('addErrorMessage')
->with(__('Exception message')->render());
$this->dataPersistor->expects($this->once())
@@ -249,7 +247,7 @@ public function testSaveWithException()
->with($this->designConfig)
->willThrowException($exception);
$this->messageManager->expects($this->once())
- ->method('addException')
+ ->method('addExceptionMessage')
->with($exception, 'Something went wrong while saving this configuration: Exception message');
$this->dataPersistor->expects($this->once())
diff --git a/app/code/Magento/Theme/Test/Unit/Controller/Adminhtml/System/Design/Theme/UploadJsTest.php b/app/code/Magento/Theme/Test/Unit/Controller/Adminhtml/System/Design/Theme/UploadJsTest.php
index d5919db5edcba..bbcaa87acb9c3 100644
--- a/app/code/Magento/Theme/Test/Unit/Controller/Adminhtml/System/Design/Theme/UploadJsTest.php
+++ b/app/code/Magento/Theme/Test/Unit/Controller/Adminhtml/System/Design/Theme/UploadJsTest.php
@@ -63,22 +63,22 @@ public function testExecuteWithoutTheme()
->expects($this->at(0))
->method('get')
->with(\Magento\Theme\Model\Uploader\Service::class)
- ->WillReturn($this->serviceModel);
+ ->willReturn($this->serviceModel);
$this->_objectManagerMock
->expects($this->at(1))
->method('get')
->with(\Magento\Framework\View\Design\Theme\FlyweightFactory::class)
- ->WillReturn($this->themeFactory);
+ ->willReturn($this->themeFactory);
$this->_objectManagerMock
->expects($this->at(2))
->method('get')
->with(\Magento\Framework\View\Design\Theme\Customization\File\Js::class)
- ->WillReturn($this->customizationJs);
+ ->willReturn($this->customizationJs);
$this->_objectManagerMock
->expects($this->at(3))
->method('get')
->with(\Magento\Framework\Json\Helper\Data::class)
- ->WillReturn($this->jsonHelper);
+ ->willReturn($this->jsonHelper);
$this->themeFactory->expects($this->once())
->method('create')
@@ -107,21 +107,21 @@ public function testExecuteWithException()
$this->_objectManagerMock->expects($this->at(0))
->method('get')
->with(\Magento\Theme\Model\Uploader\Service::class)
- ->WillReturn($this->serviceModel);
+ ->willReturn($this->serviceModel);
$this->_objectManagerMock->expects($this->at(1))
->method('get')
->with(\Magento\Framework\View\Design\Theme\FlyweightFactory::class)
- ->WillReturn($this->themeFactory);
+ ->willReturn($this->themeFactory);
$this->_objectManagerMock
->expects($this->at(2))
->method('get')
->with(\Magento\Framework\View\Design\Theme\Customization\File\Js::class)
- ->WillReturn($this->customizationJs);
+ ->willReturn($this->customizationJs);
$this->_objectManagerMock
->expects($this->at(4))
->method('get')
->with(\Magento\Framework\Json\Helper\Data::class)
- ->WillReturn($this->jsonHelper);
+ ->willReturn($this->jsonHelper);
$this->themeFactory->expects($this->once())
->method('create')
@@ -172,19 +172,19 @@ public function testExecute()
$this->_objectManagerMock->expects($this->at(0))
->method('get')
->with(\Magento\Theme\Model\Uploader\Service::class)
- ->WillReturn($this->serviceModel);
+ ->willReturn($this->serviceModel);
$this->_objectManagerMock->expects($this->at(1))
->method('get')
->with(\Magento\Framework\View\Design\Theme\FlyweightFactory::class)
- ->WillReturn($this->themeFactory);
+ ->willReturn($this->themeFactory);
$this->_objectManagerMock->expects($this->at(2))
->method('get')
->with(\Magento\Framework\View\Design\Theme\Customization\File\Js::class)
- ->WillReturn($this->customizationJs);
+ ->willReturn($this->customizationJs);
$this->_objectManagerMock->expects($this->at(4))
->method('get')
->with(\Magento\Framework\Json\Helper\Data::class)
- ->WillReturn($this->jsonHelper);
+ ->willReturn($this->jsonHelper);
$this->themeFactory->expects($this->once())
->method('create')
diff --git a/app/code/Magento/Theme/Test/Unit/Controller/Result/MessagePluginTest.php b/app/code/Magento/Theme/Test/Unit/Controller/Result/MessagePluginTest.php
index 60457fc1436c0..389e404ed129f 100644
--- a/app/code/Magento/Theme/Test/Unit/Controller/Result/MessagePluginTest.php
+++ b/app/code/Magento/Theme/Test/Unit/Controller/Result/MessagePluginTest.php
@@ -14,6 +14,7 @@
use Magento\Framework\Stdlib\Cookie\CookieMetadataFactory;
use Magento\Framework\Stdlib\Cookie\PublicCookieMetadata;
use Magento\Framework\Stdlib\CookieManagerInterface;
+use Magento\Framework\Translate\InlineInterface;
use Magento\Framework\View\Element\Message\InterpretationStrategyInterface;
use Magento\Theme\Controller\Result\MessagePlugin;
@@ -40,6 +41,9 @@ class MessagePluginTest extends \PHPUnit\Framework\TestCase
/** @var \Magento\Framework\Serialize\Serializer\Json|\PHPUnit_Framework_MockObject_MockObject */
private $serializerMock;
+ /** @var InlineInterface|\PHPUnit_Framework_MockObject_MockObject */
+ private $inlineTranslateMock;
+
protected function setUp()
{
$this->cookieManagerMock = $this->getMockBuilder(CookieManagerInterface::class)
@@ -53,13 +57,15 @@ protected function setUp()
->getMockForAbstractClass();
$this->serializerMock = $this->getMockBuilder(\Magento\Framework\Serialize\Serializer\Json::class)
->getMock();
+ $this->inlineTranslateMock = $this->getMockBuilder(InlineInterface::class)->getMockForAbstractClass();
$this->model = new MessagePlugin(
$this->cookieManagerMock,
$this->cookieMetadataFactoryMock,
$this->managerMock,
$this->interpretationStrategyMock,
- $this->serializerMock
+ $this->serializerMock,
+ $this->inlineTranslateMock
);
}
@@ -450,4 +456,93 @@ function ($data) {
$this->assertEquals($resultMock, $this->model->afterRenderResult($resultMock, $resultMock));
}
+
+ /**
+ * @return void
+ */
+ public function testAfterRenderResultWithAllowedInlineTranslate()
+ {
+ $messageType = 'message1type';
+ $messageText = '{{{message1text}}{{message1text}}{{message1text}}{{theme/luma}}}';
+ $expectedMessages = [
+ [
+ 'type' => $messageType,
+ 'text' => 'message1text',
+ ],
+ ];
+
+ /** @var Redirect|\PHPUnit_Framework_MockObject_MockObject $resultMock */
+ $resultMock = $this->getMockBuilder(Redirect::class)
+ ->disableOriginalConstructor()
+ ->getMock();
+
+ /** @var PublicCookieMetadata|\PHPUnit_Framework_MockObject_MockObject $cookieMetadataMock */
+ $cookieMetadataMock = $this->getMockBuilder(PublicCookieMetadata::class)
+ ->disableOriginalConstructor()
+ ->getMock();
+
+ $this->cookieMetadataFactoryMock->expects($this->once())
+ ->method('createPublicCookieMetadata')
+ ->willReturn($cookieMetadataMock);
+
+ $this->cookieManagerMock->expects($this->once())
+ ->method('setPublicCookie')
+ ->with(
+ MessagePlugin::MESSAGES_COOKIES_NAME,
+ json_encode($expectedMessages),
+ $cookieMetadataMock
+ );
+ $this->cookieManagerMock->expects($this->once())
+ ->method('getCookie')
+ ->with(
+ MessagePlugin::MESSAGES_COOKIES_NAME
+ )
+ ->willReturn(json_encode([]));
+
+ $this->serializerMock->expects($this->once())
+ ->method('unserialize')
+ ->willReturnCallback(
+ function ($data) {
+ return json_decode($data, true);
+ }
+ );
+ $this->serializerMock->expects($this->once())
+ ->method('serialize')
+ ->willReturnCallback(
+ function ($data) {
+ return json_encode($data);
+ }
+ );
+
+ /** @var MessageInterface|\PHPUnit_Framework_MockObject_MockObject $messageMock */
+ $messageMock = $this->getMockBuilder(MessageInterface::class)
+ ->getMock();
+ $messageMock->expects($this->once())
+ ->method('getType')
+ ->willReturn($messageType);
+
+ $this->interpretationStrategyMock->expects($this->once())
+ ->method('interpret')
+ ->with($messageMock)
+ ->willReturn($messageText);
+
+ $this->inlineTranslateMock->expects($this->once())
+ ->method('isAllowed')
+ ->willReturn(true);
+
+ /** @var Collection|\PHPUnit_Framework_MockObject_MockObject $collectionMock */
+ $collectionMock = $this->getMockBuilder(Collection::class)
+ ->disableOriginalConstructor()
+ ->getMock();
+ $collectionMock->expects($this->once())
+ ->method('getItems')
+ ->willReturn([$messageMock]);
+
+ $this->managerMock->expects($this->once())
+ ->method('getMessages')
+ ->with(true, null)
+ ->willReturn($collectionMock);
+
+ $this->assertEquals($resultMock, $this->model->afterRenderResult($resultMock, $resultMock));
+ }
}
diff --git a/app/code/Magento/Theme/Test/Unit/Model/Design/Backend/ThemeTest.php b/app/code/Magento/Theme/Test/Unit/Model/Design/Backend/ThemeTest.php
index d959b95dcb0ca..1725fe158c16c 100644
--- a/app/code/Magento/Theme/Test/Unit/Model/Design/Backend/ThemeTest.php
+++ b/app/code/Magento/Theme/Test/Unit/Model/Design/Backend/ThemeTest.php
@@ -123,6 +123,9 @@ public function testGetValue($value, $expectedResult)
$this->assertEquals($expectedResult, $this->model->getValue());
}
+ /**
+ * @return array
+ */
public function getValueDataProvider()
{
return [
@@ -131,6 +134,9 @@ public function getValueDataProvider()
];
}
+ /**
+ * @return array
+ */
public function afterSaveDataProvider()
{
return [
diff --git a/app/code/Magento/Theme/Test/Unit/Model/Theme/ValidationTest.php b/app/code/Magento/Theme/Test/Unit/Model/Theme/ValidationTest.php
index 5d1c9f8cf7c3c..e302762c1c783 100644
--- a/app/code/Magento/Theme/Test/Unit/Model/Theme/ValidationTest.php
+++ b/app/code/Magento/Theme/Test/Unit/Model/Theme/ValidationTest.php
@@ -31,6 +31,9 @@ public function testValidate(array $data, $result, array $messages)
$this->assertEquals($messages, $validator->getErrorMessages());
}
+ /**
+ * @return array
+ */
public function dataProviderValidate()
{
return [
diff --git a/app/code/Magento/Theme/Test/Unit/Model/ThemeTest.php b/app/code/Magento/Theme/Test/Unit/Model/ThemeTest.php
index 4ff64e6f694e8..b191a64ac2c21 100644
--- a/app/code/Magento/Theme/Test/Unit/Model/ThemeTest.php
+++ b/app/code/Magento/Theme/Test/Unit/Model/ThemeTest.php
@@ -481,6 +481,9 @@ public function testToArray(array $themeData, array $expected)
$this->assertEquals($expected, $this->_model->toArray());
}
+ /**
+ * @return array
+ */
public function toArrayDataProvider()
{
$parentTheme = $this->getMockBuilder(\Magento\Theme\Model\Theme::class)
@@ -555,6 +558,9 @@ public function testPopulateFromArray(array $value, array $expected, $expectedCa
$this->assertEquals($expected, $this->_model->getData());
}
+ /**
+ * @return array
+ */
public function populateFromArrayDataProvider()
{
return [
diff --git a/app/code/Magento/Theme/Test/Unit/Model/Wysiwyg/StorageTest.php b/app/code/Magento/Theme/Test/Unit/Model/Wysiwyg/StorageTest.php
index 62b644042b68d..913561590607a 100644
--- a/app/code/Magento/Theme/Test/Unit/Model/Wysiwyg/StorageTest.php
+++ b/app/code/Magento/Theme/Test/Unit/Model/Wysiwyg/StorageTest.php
@@ -172,6 +172,9 @@ public function testUploadInvalidFile()
$this->_storageModel->uploadFile($this->_storageRoot);
}
+ /**
+ * @return \PHPUnit_Framework_MockObject_MockObject
+ */
protected function _prepareUploader()
{
$uploader = $this->createMock(\Magento\MediaStorage\Model\File\Uploader::class);
@@ -538,6 +541,9 @@ public function testDeleteRootDirectory()
$this->_storageModel->deleteDirectory($directoryPath);
}
+ /**
+ * @return array
+ */
public function booleanCasesDataProvider()
{
return [[true], [false]];
diff --git a/app/code/Magento/Theme/Test/Unit/Ui/Component/Listing/Column/EditActionTest.php b/app/code/Magento/Theme/Test/Unit/Ui/Component/Listing/Column/EditActionTest.php
index 068738f17c967..2ac959d0a9881 100644
--- a/app/code/Magento/Theme/Test/Unit/Ui/Component/Listing/Column/EditActionTest.php
+++ b/app/code/Magento/Theme/Test/Unit/Ui/Component/Listing/Column/EditActionTest.php
@@ -82,6 +82,9 @@ public function testPrepareDataSource($dataSourceItem, $scope, $scopeId)
$this->assertEquals($expectedDataSource, $dataSource);
}
+ /**
+ * @return array
+ */
public function getPrepareDataSourceDataProvider()
{
return [
diff --git a/app/code/Magento/Theme/composer.json b/app/code/Magento/Theme/composer.json
index 6a2c505ab4627..dbf28aa03c9fe 100644
--- a/app/code/Magento/Theme/composer.json
+++ b/app/code/Magento/Theme/composer.json
@@ -22,7 +22,7 @@
"magento/module-directory": "100.2.*"
},
"type": "magento2-module",
- "version": "100.2.4",
+ "version": "100.2.5",
"license": [
"OSL-3.0",
"AFL-3.0"
diff --git a/app/code/Magento/Theme/etc/di.xml b/app/code/Magento/Theme/etc/di.xml
index c20184fec6bc4..21e1736d01bf1 100644
--- a/app/code/Magento/Theme/etc/di.xml
+++ b/app/code/Magento/Theme/etc/di.xml
@@ -69,7 +69,7 @@
- Magento\Framework\Translate
+ Magento\Framework\TranslateInterface
Magento\Theme\Model\Design\Proxy
diff --git a/app/code/Magento/Theme/view/frontend/templates/html/bugreport.phtml b/app/code/Magento/Theme/view/frontend/templates/html/bugreport.phtml
index 5d8203244256e..f147b7085945f 100644
--- a/app/code/Magento/Theme/view/frontend/templates/html/bugreport.phtml
+++ b/app/code/Magento/Theme/view/frontend/templates/html/bugreport.phtml
@@ -7,7 +7,7 @@
= /* @escapeNotVerified */ __('Help Us Keep Magento Healthy') ?>
+ target="_blank" title="= /* @escapeNotVerified */ __('Report All Bugs') ?>">
= /* @escapeNotVerified */ __('Report All Bugs') ?>
diff --git a/app/code/Magento/Theme/view/frontend/templates/html/header/logo.phtml b/app/code/Magento/Theme/view/frontend/templates/html/header/logo.phtml
index 8c3663337cbbe..17f8d7c70f574 100644
--- a/app/code/Magento/Theme/view/frontend/templates/html/header/logo.phtml
+++ b/app/code/Magento/Theme/view/frontend/templates/html/header/logo.phtml
@@ -18,6 +18,7 @@
getLogoWidth() ? 'width="' . $block->getLogoWidth() . '"' : '' ?>
= $block->getLogoHeight() ? 'height="' . $block->getLogoHeight() . '"' : '' ?>
diff --git a/app/code/Magento/Theme/view/frontend/web/js/row-builder.js b/app/code/Magento/Theme/view/frontend/web/js/row-builder.js
index 62537c8b1b899..7785ced2e4bd5 100644
--- a/app/code/Magento/Theme/view/frontend/web/js/row-builder.js
+++ b/app/code/Magento/Theme/view/frontend/web/js/row-builder.js
@@ -144,7 +144,7 @@ define([
$(tmpl).appendTo(row);
- $(this.options.rowContainer).append(row);
+ $(this.options.rowContainer).append(row).trigger('contentUpdated');
row.addClass(this.options.additionalRowClass);
diff --git a/app/code/Magento/Translation/Model/Js/DataProvider.php b/app/code/Magento/Translation/Model/Js/DataProvider.php
index 9037574e28a5b..a1cfab00b6c8d 100644
--- a/app/code/Magento/Translation/Model/Js/DataProvider.php
+++ b/app/code/Magento/Translation/Model/Js/DataProvider.php
@@ -114,7 +114,8 @@ public function getData($themePath)
}
} catch (\Exception $e) {
throw new LocalizedException(
- __('Error while translating phrase "%s" in file %s.', $phrase, $filePath[0])
+ __('Error while translating phrase "%s" in file %s.', $phrase, $filePath[0]),
+ $e
);
}
}
diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Ups/LICENSE.txt b/app/code/Magento/Translation/Test/Mftf/LICENSE.txt
similarity index 100%
rename from dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Ups/LICENSE.txt
rename to app/code/Magento/Translation/Test/Mftf/LICENSE.txt
diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Ups/LICENSE_AFL.txt b/app/code/Magento/Translation/Test/Mftf/LICENSE_AFL.txt
similarity index 100%
rename from dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Ups/LICENSE_AFL.txt
rename to app/code/Magento/Translation/Test/Mftf/LICENSE_AFL.txt
diff --git a/app/code/Magento/Translation/Test/Mftf/README.md b/app/code/Magento/Translation/Test/Mftf/README.md
new file mode 100644
index 0000000000000..99e8bd0e13ab3
--- /dev/null
+++ b/app/code/Magento/Translation/Test/Mftf/README.md
@@ -0,0 +1,3 @@
+# Translation Functional Tests
+
+The Functional Test Module for **Magento Translation** module.
diff --git a/app/code/Magento/Translation/Test/Mftf/composer.json b/app/code/Magento/Translation/Test/Mftf/composer.json
new file mode 100644
index 0000000000000..1d012752255e5
--- /dev/null
+++ b/app/code/Magento/Translation/Test/Mftf/composer.json
@@ -0,0 +1,22 @@
+{
+ "name": "magento/functional-test-module-translation",
+ "description": "N/A",
+ "config": {
+ "sort-packages": true
+ },
+ "require": {
+ "php": "~7.0.13|~7.1.0",
+ "magento/functional-test-module-backend": "100.0.0-dev",
+ "magento/functional-test-module-developer": "100.0.0-dev",
+ "magento/functional-test-module-store": "100.0.0-dev",
+ "magento/magento2-functional-testing-framework": "2.2.0"
+ },
+ "suggest": {
+ "magento/functional-test-module-deploy": "100.0.0-dev"
+ },
+ "type": "magento2-test",
+ "license": [
+ "OSL-3.0",
+ "AFL-3.0"
+ ]
+}
diff --git a/app/code/Magento/Translation/composer.json b/app/code/Magento/Translation/composer.json
index 338b087af53da..398f2506cb1d6 100644
--- a/app/code/Magento/Translation/composer.json
+++ b/app/code/Magento/Translation/composer.json
@@ -12,7 +12,7 @@
"magento/module-deploy": "100.2.*"
},
"type": "magento2-module",
- "version": "100.2.3",
+ "version": "100.2.4",
"license": [
"OSL-3.0",
"AFL-3.0"
diff --git a/app/code/Magento/Translation/etc/adminhtml/system.xml b/app/code/Magento/Translation/etc/adminhtml/system.xml
index 8c3cdc5c39916..ab854f8a4db52 100644
--- a/app/code/Magento/Translation/etc/adminhtml/system.xml
+++ b/app/code/Magento/Translation/etc/adminhtml/system.xml
@@ -9,7 +9,7 @@
-
+
Translation Strategy
Magento\Translation\Model\Js\Config\Source\Strategy
Please put your store into maintenance mode and redeploy static files after changing strategy
diff --git a/app/code/Magento/Translation/view/frontend/requirejs-config.js b/app/code/Magento/Translation/view/frontend/requirejs-config.js
index 47ccaf5a33e57..b4b3ce0f8c554 100644
--- a/app/code/Magento/Translation/view/frontend/requirejs-config.js
+++ b/app/code/Magento/Translation/view/frontend/requirejs-config.js
@@ -7,7 +7,8 @@ var config = {
map: {
'*': {
editTrigger: 'mage/edit-trigger',
- addClass: 'Magento_Translation/add-class'
+ addClass: 'Magento_Translation/js/add-class',
+ 'Magento_Translation/add-class': 'Magento_Translation/js/add-class'
}
},
deps: [
diff --git a/app/code/Magento/Translation/view/frontend/web/add-class.js b/app/code/Magento/Translation/view/frontend/web/js/add-class.js
similarity index 100%
rename from app/code/Magento/Translation/view/frontend/web/add-class.js
rename to app/code/Magento/Translation/view/frontend/web/js/add-class.js
diff --git a/app/code/Magento/Ui/Component/Filters/Type/Input.php b/app/code/Magento/Ui/Component/Filters/Type/Input.php
index 9cc060ae58172..230f3dbce3497 100644
--- a/app/code/Magento/Ui/Component/Filters/Type/Input.php
+++ b/app/code/Magento/Ui/Component/Filters/Type/Input.php
@@ -67,7 +67,7 @@ protected function applyFilter()
if (isset($this->filterData[$this->getName()])) {
$value = str_replace(['%', '_'], ['\%', '\_'], $this->filterData[$this->getName()]);
- if (!empty($value)) {
+ if (!$this->isEmptyValue($value)) {
$filter = $this->filterBuilder->setConditionType('like')
->setField($this->getName())
->setValue(sprintf('%%%s%%', $value))
@@ -77,4 +77,15 @@ protected function applyFilter()
}
}
}
+
+ /**
+ * Empty values are null, empty string and empty array.
+ *
+ * @param mixed $value
+ * @return bool
+ */
+ private function isEmptyValue($value)
+ {
+ return $value === null || $value === '' || (is_array($value) && empty($value));
+ }
}
diff --git a/app/code/Magento/Ui/Component/Form/Element/AbstractElement.php b/app/code/Magento/Ui/Component/Form/Element/AbstractElement.php
index fb8db59c90bd7..c00affc748e67 100644
--- a/app/code/Magento/Ui/Component/Form/Element/AbstractElement.php
+++ b/app/code/Magento/Ui/Component/Form/Element/AbstractElement.php
@@ -44,7 +44,7 @@ public function getFormInputName()
*/
public function isReadonly()
{
- return (bool) $this->getData('readonly');
+ return (bool)$this->getData('readonly');
}
/**
diff --git a/app/code/Magento/Ui/Component/MassAction/Filter.php b/app/code/Magento/Ui/Component/MassAction/Filter.php
index 6b089233c210a..483cf1ed154f0 100644
--- a/app/code/Magento/Ui/Component/MassAction/Filter.php
+++ b/app/code/Magento/Ui/Component/MassAction/Filter.php
@@ -98,14 +98,12 @@ public function getCollection(AbstractDb $collection)
throw new LocalizedException(__('Please select item(s).'));
}
}
- /** @var \Magento\Customer\Model\ResourceModel\Customer\Collection $collection */
- $idsArray = $this->getFilterIds();
- if (!empty($idsArray)) {
- $collection->addFieldToFilter(
- $collection->getIdFieldName(),
- ['in' => $idsArray]
- );
- }
+
+ $collection->addFieldToFilter(
+ $collection->getIdFieldName(),
+ ['in' => $this->getFilterIds()]
+ );
+
return $collection;
}
diff --git a/app/code/Magento/Ui/DataProvider/AbstractDataProvider.php b/app/code/Magento/Ui/DataProvider/AbstractDataProvider.php
index cff6171395ec9..efe4a1b8f0859 100644
--- a/app/code/Magento/Ui/DataProvider/AbstractDataProvider.php
+++ b/app/code/Magento/Ui/DataProvider/AbstractDataProvider.php
@@ -292,6 +292,6 @@ public function setConfigData($config)
*/
public function getAllIds()
{
- return $this->collection->getAllIds();
+ return $this->getCollection()->getAllIds();
}
}
diff --git a/app/code/Magento/Ui/DataProvider/EavValidationRules.php b/app/code/Magento/Ui/DataProvider/EavValidationRules.php
index 12e345e1fa12c..6e2bb3866e947 100644
--- a/app/code/Magento/Ui/DataProvider/EavValidationRules.php
+++ b/app/code/Magento/Ui/DataProvider/EavValidationRules.php
@@ -3,6 +3,7 @@
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
+
namespace Magento\Ui\DataProvider;
use Magento\Eav\Model\Entity\Attribute\AbstractAttribute;
@@ -31,25 +32,51 @@ class EavValidationRules
*/
public function build(AbstractAttribute $attribute, array $data)
{
- $validation = [];
+ $validations = [];
if (isset($data['required']) && $data['required'] == 1) {
- $validation = array_merge($validation, ['required-entry' => true]);
+ $validations = array_merge($validations, ['required-entry' => true]);
}
if ($attribute->getFrontendInput() === 'price') {
- $validation = array_merge($validation, ['validate-zero-or-greater' => true]);
+ $validations = array_merge($validations, ['validate-zero-or-greater' => true]);
}
if ($attribute->getValidateRules()) {
- $validation = array_merge($validation, $attribute->getValidateRules());
+ $validations = array_merge($validations, $this->clipLengthRules($attribute->getValidateRules()));
}
+ return $this->aggregateRules($validations);
+ }
+
+ /**
+ * @param array $validations
+ * @return array
+ */
+ private function aggregateRules(array $validations): array
+ {
$rules = [];
- foreach ($validation as $type => $ruleName) {
- $rule = [$type => $ruleName];
+ foreach ($validations as $type => $ruleValue) {
+ $rule = [$type => $ruleValue];
if ($type === 'input_validation') {
- $rule = isset($this->validationRules[$ruleName]) ? $this->validationRules[$ruleName] : [];
+ $rule = $this->validationRules[$ruleValue] ?? [];
+ }
+ if (count($rule) !== 0) {
+ $key = key($rule);
+ $rules[$key] = $rule[$key];
}
- $rules = array_merge($rules, $rule);
}
+ return $rules;
+ }
+ /**
+ * @param array $rules
+ * @return array
+ */
+ private function clipLengthRules(array $rules): array
+ {
+ if (empty($rules['input_validation'])) {
+ unset(
+ $rules['min_text_length'],
+ $rules['max_text_length']
+ );
+ }
return $rules;
}
}
diff --git a/app/code/Magento/Ui/Model/Export/ConvertToCsv.php b/app/code/Magento/Ui/Model/Export/ConvertToCsv.php
index 9eba829982533..eb811bfae788f 100644
--- a/app/code/Magento/Ui/Model/Export/ConvertToCsv.php
+++ b/app/code/Magento/Ui/Model/Export/ConvertToCsv.php
@@ -6,9 +6,9 @@
namespace Magento\Ui\Model\Export;
use Magento\Framework\App\Filesystem\DirectoryList;
+use Magento\Framework\Exception\FileSystemException;
use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\Filesystem;
-use Magento\Framework\Filesystem\Directory\WriteInterface;
use Magento\Ui\Component\MassAction\Filter;
/**
@@ -17,7 +17,7 @@
class ConvertToCsv
{
/**
- * @var WriteInterface
+ * @var DirectoryList
*/
protected $directory;
@@ -31,11 +31,17 @@ class ConvertToCsv
*/
protected $pageSize = null;
+ /**
+ * @var Filter
+ */
+ protected $filter;
+
/**
* @param Filesystem $filesystem
* @param Filter $filter
* @param MetadataProvider $metadataProvider
* @param int $pageSize
+ * @throws FileSystemException
*/
public function __construct(
Filesystem $filesystem,
diff --git a/app/code/Magento/Ui/Model/Export/ConvertToXml.php b/app/code/Magento/Ui/Model/Export/ConvertToXml.php
index b707742063dbd..19eb651113fcf 100644
--- a/app/code/Magento/Ui/Model/Export/ConvertToXml.php
+++ b/app/code/Magento/Ui/Model/Export/ConvertToXml.php
@@ -10,9 +10,9 @@
use Magento\Framework\App\Filesystem\DirectoryList;
use Magento\Framework\Convert\Excel;
use Magento\Framework\Convert\ExcelFactory;
+use Magento\Framework\Exception\FileSystemException;
use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\Filesystem;
-use Magento\Framework\Filesystem\Directory\WriteInterface;
use Magento\Ui\Component\MassAction\Filter;
/**
@@ -21,7 +21,7 @@
class ConvertToXml
{
/**
- * @var WriteInterface
+ * @var DirectoryList
*/
protected $directory;
@@ -50,12 +50,18 @@ class ConvertToXml
*/
protected $fields;
+ /**
+ * @var Filter
+ */
+ protected $filter;
+
/**
* @param Filesystem $filesystem
* @param Filter $filter
* @param MetadataProvider $metadataProvider
* @param ExcelFactory $excelFactory
* @param SearchResultIteratorFactory $iteratorFactory
+ * @throws FileSystemException
*/
public function __construct(
Filesystem $filesystem,
@@ -88,6 +94,7 @@ protected function getOptions()
* Returns DB fields list
*
* @return array
+ * @throws LocalizedException
*/
protected function getFields()
{
@@ -103,6 +110,7 @@ protected function getFields()
*
* @param DocumentInterface $document
* @return array
+ * @throws LocalizedException
*/
public function getRowData(DocumentInterface $document)
{
diff --git a/app/code/Magento/Ui/Model/Export/MetadataProvider.php b/app/code/Magento/Ui/Model/Export/MetadataProvider.php
index 499cd06e505f6..54d856e8a6104 100644
--- a/app/code/Magento/Ui/Model/Export/MetadataProvider.php
+++ b/app/code/Magento/Ui/Model/Export/MetadataProvider.php
@@ -118,6 +118,13 @@ public function getHeaders(UiComponentInterface $component)
foreach ($this->getColumns($component) as $column) {
$row[] = $column->getData('config/label');
}
+
+ array_walk($row, function (&$header) {
+ if (mb_strpos($header, 'ID') === 0) {
+ $header = '"' . $header . '"';
+ }
+ });
+
return $row;
}
diff --git a/app/code/Magento/Ui/Test/Mftf/ActionGroup/AdminDataGridFilterActionGroup.xml b/app/code/Magento/Ui/Test/Mftf/ActionGroup/AdminDataGridFilterActionGroup.xml
new file mode 100644
index 0000000000000..2c65f4d548c31
--- /dev/null
+++ b/app/code/Magento/Ui/Test/Mftf/ActionGroup/AdminDataGridFilterActionGroup.xml
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/code/Magento/Ui/Test/Mftf/ActionGroup/AdminSaveAndCloseActionGroup.xml b/app/code/Magento/Ui/Test/Mftf/ActionGroup/AdminSaveAndCloseActionGroup.xml
new file mode 100644
index 0000000000000..133b81a5d6044
--- /dev/null
+++ b/app/code/Magento/Ui/Test/Mftf/ActionGroup/AdminSaveAndCloseActionGroup.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/UrlRewrite/LICENSE.txt b/app/code/Magento/Ui/Test/Mftf/LICENSE.txt
similarity index 100%
rename from dev/tests/acceptance/tests/functional/Magento/FunctionalTest/UrlRewrite/LICENSE.txt
rename to app/code/Magento/Ui/Test/Mftf/LICENSE.txt
diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/UrlRewrite/LICENSE_AFL.txt b/app/code/Magento/Ui/Test/Mftf/LICENSE_AFL.txt
similarity index 100%
rename from dev/tests/acceptance/tests/functional/Magento/FunctionalTest/UrlRewrite/LICENSE_AFL.txt
rename to app/code/Magento/Ui/Test/Mftf/LICENSE_AFL.txt
diff --git a/app/code/Magento/Ui/Test/Mftf/README.md b/app/code/Magento/Ui/Test/Mftf/README.md
new file mode 100644
index 0000000000000..9f61e8fc9a009
--- /dev/null
+++ b/app/code/Magento/Ui/Test/Mftf/README.md
@@ -0,0 +1,3 @@
+# Ui Functional Tests
+
+The Functional Test Module for **Magento Ui** module.
diff --git a/app/code/Magento/Ui/Test/Mftf/Section/AdminDataGridHeaderSection.xml b/app/code/Magento/Ui/Test/Mftf/Section/AdminDataGridHeaderSection.xml
new file mode 100644
index 0000000000000..e5766300b0e87
--- /dev/null
+++ b/app/code/Magento/Ui/Test/Mftf/Section/AdminDataGridHeaderSection.xml
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/code/Magento/Ui/Test/Mftf/Section/AdminDataGridTableSection.xml b/app/code/Magento/Ui/Test/Mftf/Section/AdminDataGridTableSection.xml
new file mode 100644
index 0000000000000..ea0f7e64a8448
--- /dev/null
+++ b/app/code/Magento/Ui/Test/Mftf/Section/AdminDataGridTableSection.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
diff --git a/app/code/Magento/Ui/Test/Mftf/composer.json b/app/code/Magento/Ui/Test/Mftf/composer.json
new file mode 100644
index 0000000000000..6889a12747a2d
--- /dev/null
+++ b/app/code/Magento/Ui/Test/Mftf/composer.json
@@ -0,0 +1,23 @@
+{
+ "name": "magento/functional-test-module-ui",
+ "description": "N/A",
+ "config": {
+ "sort-packages": true
+ },
+ "require": {
+ "php": "~7.0.13|~7.1.0",
+ "magento/functional-test-module-backend": "100.0.0-dev",
+ "magento/magento2-functional-testing-framework": "2.2.0",
+ "magento/functional-test-module-eav": "100.0.0-dev",
+ "magento/functional-test-module-authorization": "100.0.0-dev",
+ "magento/functional-test-module-user": "100.0.0-dev"
+ },
+ "suggest": {
+ "magento/functional-test-module-config": "100.0.0-dev"
+ },
+ "type": "magento2-test",
+ "license": [
+ "OSL-3.0",
+ "AFL-3.0"
+ ]
+}
diff --git a/app/code/Magento/Ui/Test/Unit/Component/Filters/Type/InputTest.php b/app/code/Magento/Ui/Test/Unit/Component/Filters/Type/InputTest.php
index d814fdcd153da..be5a37a709a6e 100644
--- a/app/code/Magento/Ui/Test/Unit/Component/Filters/Type/InputTest.php
+++ b/app/code/Magento/Ui/Test/Unit/Component/Filters/Type/InputTest.php
@@ -177,6 +177,16 @@ public function getPrepareDataProvider()
['test_date' => ''],
null,
],
+ [
+ 'test_date',
+ ['test_date' => null],
+ null,
+ ],
+ [
+ 'test_date',
+ ['test_date' => '0'],
+ ['like' => '%0%'],
+ ],
[
'test_date',
['test_date' => 'some_value'],
diff --git a/app/code/Magento/Ui/Test/Unit/Component/Form/Element/AbstractElementTest.php b/app/code/Magento/Ui/Test/Unit/Component/Form/Element/AbstractElementTest.php
index 54bf0c9e8b37e..d9afe8f16a1a7 100644
--- a/app/code/Magento/Ui/Test/Unit/Component/Form/Element/AbstractElementTest.php
+++ b/app/code/Magento/Ui/Test/Unit/Component/Form/Element/AbstractElementTest.php
@@ -46,6 +46,9 @@ protected function setUp()
*/
abstract protected function getModelName();
+ /**
+ * @return mixed
+ */
abstract public function testGetComponentName();
/**
diff --git a/app/code/Magento/Ui/Test/Unit/Component/Form/Element/ActionDeleteTest.php b/app/code/Magento/Ui/Test/Unit/Component/Form/Element/ActionDeleteTest.php
index 6f45c192d6c4c..890737965d559 100644
--- a/app/code/Magento/Ui/Test/Unit/Component/Form/Element/ActionDeleteTest.php
+++ b/app/code/Magento/Ui/Test/Unit/Component/Form/Element/ActionDeleteTest.php
@@ -20,6 +20,9 @@ protected function getModelName()
return ActionDelete::class;
}
+ /**
+ * @return mixed|void
+ */
public function testGetComponentName()
{
$this->assertSame(ActionDelete::NAME, $this->getModel()->getComponentName());
diff --git a/app/code/Magento/Ui/Test/Unit/Component/Form/Element/CheckboxSetTest.php b/app/code/Magento/Ui/Test/Unit/Component/Form/Element/CheckboxSetTest.php
index 025f4a1582458..968155b92a3b9 100644
--- a/app/code/Magento/Ui/Test/Unit/Component/Form/Element/CheckboxSetTest.php
+++ b/app/code/Magento/Ui/Test/Unit/Component/Form/Element/CheckboxSetTest.php
@@ -22,6 +22,9 @@ protected function getModelName()
return CheckboxSet::class;
}
+ /**
+ * @return mixed|void
+ */
public function testGetComponentName()
{
$this->assertSame(CheckboxSet::NAME, $this->getModel()->getComponentName());
diff --git a/app/code/Magento/Ui/Test/Unit/Component/Form/Element/MultiSelectTest.php b/app/code/Magento/Ui/Test/Unit/Component/Form/Element/MultiSelectTest.php
index cb91fbb945bb5..723d6402fe865 100644
--- a/app/code/Magento/Ui/Test/Unit/Component/Form/Element/MultiSelectTest.php
+++ b/app/code/Magento/Ui/Test/Unit/Component/Form/Element/MultiSelectTest.php
@@ -22,6 +22,9 @@ protected function getModelName()
return MultiSelect::class;
}
+ /**
+ * @return mixed|void
+ */
public function testGetComponentName()
{
$this->contextMock->expects($this->never())->method('getProcessor');
diff --git a/app/code/Magento/Ui/Test/Unit/Component/Form/Element/RadioSetTest.php b/app/code/Magento/Ui/Test/Unit/Component/Form/Element/RadioSetTest.php
index 0e0fef60df60b..ea4f0f9f94a00 100644
--- a/app/code/Magento/Ui/Test/Unit/Component/Form/Element/RadioSetTest.php
+++ b/app/code/Magento/Ui/Test/Unit/Component/Form/Element/RadioSetTest.php
@@ -22,6 +22,9 @@ protected function getModelName()
return RadioSet::class;
}
+ /**
+ * @return mixed|void
+ */
public function testGetComponentName()
{
$this->assertSame(RadioSet::NAME, $this->getModel()->getComponentName());
diff --git a/app/code/Magento/Ui/Test/Unit/Component/Form/Element/SelectTest.php b/app/code/Magento/Ui/Test/Unit/Component/Form/Element/SelectTest.php
index c695262681063..6432f8404eaff 100644
--- a/app/code/Magento/Ui/Test/Unit/Component/Form/Element/SelectTest.php
+++ b/app/code/Magento/Ui/Test/Unit/Component/Form/Element/SelectTest.php
@@ -22,6 +22,9 @@ protected function getModelName()
return Select::class;
}
+ /**
+ * @return mixed|void
+ */
public function testGetComponentName()
{
$this->assertSame(Select::NAME, $this->getModel()->getComponentName());
diff --git a/app/code/Magento/Ui/Test/Unit/Component/Form/Element/WysiwygTest.php b/app/code/Magento/Ui/Test/Unit/Component/Form/Element/WysiwygTest.php
index d0e0542a19480..2304883666b74 100644
--- a/app/code/Magento/Ui/Test/Unit/Component/Form/Element/WysiwygTest.php
+++ b/app/code/Magento/Ui/Test/Unit/Component/Form/Element/WysiwygTest.php
@@ -62,6 +62,9 @@ protected function setUp()
->method('getElementHtml');
}
+ /**
+ * @return \Magento\Ui\Component\Form\Element\AbstractElement|object
+ */
protected function getModel()
{
return $this->objectManager->getObject(Wysiwyg::class, [
@@ -82,6 +85,9 @@ protected function getModelName()
return Wysiwyg::class;
}
+ /**
+ * @return mixed|void
+ */
public function testGetComponentName()
{
$this->assertSame(Wysiwyg::NAME, $this->getModel()->getComponentName());
diff --git a/app/code/Magento/Ui/Test/Unit/Component/MassActionTest.php b/app/code/Magento/Ui/Test/Unit/Component/MassActionTest.php
index 123b4cacf71a7..b2f494351597f 100644
--- a/app/code/Magento/Ui/Test/Unit/Component/MassActionTest.php
+++ b/app/code/Magento/Ui/Test/Unit/Component/MassActionTest.php
@@ -93,6 +93,9 @@ public function testPrepare($componentName, $componentData)
$this->assertEquals(['actions' => [$action->getConfiguration()]], $massAction->getConfiguration());
}
+ /**
+ * @return array
+ */
public function getPrepareDataProvider()
{
return [
diff --git a/app/code/Magento/Ui/Test/Unit/Config/Converter/ActionsTest.php b/app/code/Magento/Ui/Test/Unit/Config/Converter/ActionsTest.php
index 8228026dff3d1..d146a18a710c6 100644
--- a/app/code/Magento/Ui/Test/Unit/Config/Converter/ActionsTest.php
+++ b/app/code/Magento/Ui/Test/Unit/Config/Converter/ActionsTest.php
@@ -61,6 +61,9 @@ public function testConvert(array $expectedResult, $xpath)
$this->assertEquals($expectedResult, $this->converter->convert($actions));
}
+ /**
+ * @return array
+ */
public function convertDataProvider()
{
return [
diff --git a/app/code/Magento/Ui/Test/Unit/Config/Converter/OptionsTest.php b/app/code/Magento/Ui/Test/Unit/Config/Converter/OptionsTest.php
index 058e3651bde5c..8f5ab55f7a914 100644
--- a/app/code/Magento/Ui/Test/Unit/Config/Converter/OptionsTest.php
+++ b/app/code/Magento/Ui/Test/Unit/Config/Converter/OptionsTest.php
@@ -41,6 +41,9 @@ public function testConvert(array $expectedResult, $xpath)
$this->assertEquals($expectedResult, $res);
}
+ /**
+ * @return array
+ */
public function convertDataProvider()
{
return [
diff --git a/app/code/Magento/Ui/Test/Unit/DataProvider/EavValidationRulesTest.php b/app/code/Magento/Ui/Test/Unit/DataProvider/EavValidationRulesTest.php
index debcde4765fc7..b9a5262e64eb8 100644
--- a/app/code/Magento/Ui/Test/Unit/DataProvider/EavValidationRulesTest.php
+++ b/app/code/Magento/Ui/Test/Unit/DataProvider/EavValidationRulesTest.php
@@ -3,6 +3,7 @@
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
+
namespace Magento\Ui\Test\Unit\DataProvider;
use Magento\Eav\Model\Entity\Attribute\AbstractAttribute;
@@ -70,11 +71,25 @@ public function buildDataProvider()
['', ['input_validation' => 'email'], [], ['validate-email' => true]],
['', ['input_validation' => 'date'], [], ['validate-date' => true]],
['', ['input_validation' => 'other'], [], []],
- ['', ['max_text_length' => '254'], ['required' => 1], ['max_text_length' => 254, 'required-entry' => true]],
- ['', ['max_text_length' => '254', 'min_text_length' => 1], [],
- ['max_text_length' => 254, 'min_text_length' => 1]],
- ['', ['max_text_length' => '254', 'input_validation' => 'date'], [],
- ['max_text_length' => 254, 'validate-date' => true]],
+ ['', ['max_text_length' => '254'], ['required' => 1], ['required-entry' => true]],
+ [
+ '',
+ ['input_validation' => 'other', 'max_text_length' => '254'],
+ ['required' => 1],
+ ['max_text_length' => 254, 'required-entry' => true]
+ ],
+ [
+ '',
+ ['input_validation' => 'other', 'max_text_length' => '254', 'min_text_length' => 1],
+ [],
+ ['max_text_length' => 254, 'min_text_length' => 1]
+ ],
+ [
+ '',
+ ['max_text_length' => '254', 'input_validation' => 'date'],
+ [],
+ ['max_text_length' => 254, 'validate-date' => true]
+ ],
];
}
}
diff --git a/app/code/Magento/Ui/Test/Unit/Model/Export/MetadataProviderTest.php b/app/code/Magento/Ui/Test/Unit/Model/Export/MetadataProviderTest.php
index dd6fd58d355e6..adbc6e04636a9 100644
--- a/app/code/Magento/Ui/Test/Unit/Model/Export/MetadataProviderTest.php
+++ b/app/code/Magento/Ui/Test/Unit/Model/Export/MetadataProviderTest.php
@@ -40,18 +40,37 @@ protected function setUp()
);
}
- public function testGetHeaders()
+ /**
+ * @param array $columnLabels
+ * @param array $expected
+ * @return void
+ * @dataProvider getColumnsDataProvider
+ */
+ public function testGetHeaders(array $columnLabels, array $expected)
{
$componentName = 'component_name';
$columnName = 'column_name';
- $columnLabel = 'column_label';
-
- $component = $this->prepareColumns($componentName, $columnName, $columnLabel);
+ $component = $this->prepareColumns($componentName, $columnName, $columnLabels[0]);
$result = $this->model->getHeaders($component);
$this->assertTrue(is_array($result));
$this->assertCount(1, $result);
- $this->assertEquals($columnLabel, $result[0]);
+ $this->assertEquals($expected, $result);
+ }
+
+ /**
+ * @return array
+ */
+ public function getColumnsDataProvider(): array
+ {
+ return [
+ [['ID'],['"ID"']],
+ [['Name'],['Name']],
+ [['Id'],['Id']],
+ [['id'],['id']],
+ [['IDTEST'],['"IDTEST"']],
+ [['ID TEST'],['"ID TEST"']],
+ ];
}
public function testGetFields()
diff --git a/app/code/Magento/Ui/Test/Unit/Model/ManagerTest.php b/app/code/Magento/Ui/Test/Unit/Model/ManagerTest.php
index 96468b63314b4..fde743390816d 100644
--- a/app/code/Magento/Ui/Test/Unit/Model/ManagerTest.php
+++ b/app/code/Magento/Ui/Test/Unit/Model/ManagerTest.php
@@ -193,6 +193,9 @@ public function testPrepareGetData($componentName, $componentData, $isCached, $r
);
}
+ /**
+ * @return array
+ */
public function getComponentData()
{
$cachedData = new \ArrayObject(
@@ -293,6 +296,9 @@ public function testCreateRawComponentData($componentName, $configData, $compone
$this->assertEquals($componentData, $this->manager->createRawComponentData($componentName, $needEvaluate));
}
+ /**
+ * @return array
+ */
public function getComponentDataProvider()
{
return [
diff --git a/app/code/Magento/Ui/composer.json b/app/code/Magento/Ui/composer.json
index 1a9f47283c134..0a2295ba9152c 100644
--- a/app/code/Magento/Ui/composer.json
+++ b/app/code/Magento/Ui/composer.json
@@ -13,7 +13,7 @@
"magento/module-config": "101.0.*"
},
"type": "magento2-module",
- "version": "101.0.4",
+ "version": "101.0.5",
"license": [
"OSL-3.0",
"AFL-3.0"
diff --git a/app/code/Magento/Ui/etc/adminhtml/system.xml b/app/code/Magento/Ui/etc/adminhtml/system.xml
index 74e2e076b93c8..ab4272f8d2a34 100644
--- a/app/code/Magento/Ui/etc/adminhtml/system.xml
+++ b/app/code/Magento/Ui/etc/adminhtml/system.xml
@@ -9,12 +9,12 @@
-
+
Log JS Errors to Session Storage
Magento\Config\Model\Config\Source\Yesno
If enabled, can be used by functional tests for extended reporting
-
+
Log JS Errors to Session Storage Key
Use this key to retrieve collected js errors
diff --git a/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows-grid.js b/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows-grid.js
index d4962c0658bdf..27a32b04a7e1c 100644
--- a/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows-grid.js
+++ b/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows-grid.js
@@ -109,9 +109,8 @@ define([
* @param {String|Number} recordId
*/
deleteRecord: function (index, recordId) {
- this._super();
-
this.updateInsertData(recordId);
+ this._super();
},
/**
diff --git a/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows.js b/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows.js
index 94a05e5fcde33..63d44e09a59bb 100644
--- a/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows.js
+++ b/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows.js
@@ -330,9 +330,7 @@ define([
}
if (this.defaultPagesState[this.currentPage()]) {
- this.pagesChanged[this.currentPage()] =
- !compareArrays(this.defaultPagesState[this.currentPage()], this.arrayFilter(this.getChildItems()));
- this.changed(_.some(this.pagesChanged));
+ this.setChangedForCurrentPage();
}
},
@@ -442,13 +440,9 @@ define([
return initialize;
}));
- this.pagesChanged[this.currentPage()] =
- !compareArrays(this.defaultPagesState[this.currentPage()], this.arrayFilter(this.getChildItems()));
- this.changed(_.some(this.pagesChanged));
+ this.setChangedForCurrentPage();
} else if (this.hasInitialPagesState[this.currentPage()]) {
- this.pagesChanged[this.currentPage()] =
- !compareArrays(this.defaultPagesState[this.currentPage()], this.arrayFilter(this.getChildItems()));
- this.changed(_.some(this.pagesChanged));
+ this.setChangedForCurrentPage();
}
},
@@ -722,6 +716,8 @@ define([
* @param {Number} page - current page
*/
changePage: function (page) {
+ this.clear();
+
if (page === 1 && !this.recordData().length) {
return false;
}
@@ -763,7 +759,6 @@ define([
* Change page to next
*/
nextPage: function () {
- this.clear();
this.currentPage(this.currentPage() + 1);
},
@@ -771,7 +766,6 @@ define([
* Change page to previous
*/
previousPage: function () {
- this.clear();
this.currentPage(this.currentPage() - 1);
},
@@ -849,7 +843,8 @@ define([
deleteRecord: function (index, recordId) {
var recordInstance,
lastRecord,
- recordsData;
+ recordsData,
+ lastRecordIndex;
if (this.deleteProperty) {
recordsData = this.recordData();
@@ -868,12 +863,13 @@ define([
this.update = true;
if (~~this.currentPage() === this.pages()) {
+ lastRecordIndex = this.startIndex + this.getChildItems().length - 1;
lastRecord =
_.findWhere(this.elems(), {
- index: this.startIndex + this.getChildItems().length - 1
+ index: lastRecordIndex
}) ||
_.findWhere(this.elems(), {
- index: (this.startIndex + this.getChildItems().length - 1).toString()
+ index: lastRecordIndex.toString()
});
lastRecord.destroy();
@@ -1134,6 +1130,18 @@ define([
});
this.isDifferedFromDefault(!_.isEqual(recordData, this.default));
+ },
+
+ /**
+ * Set the changed property if the current page is different
+ * than the default state
+ *
+ * @return void
+ */
+ setChangedForCurrentPage: function () {
+ this.pagesChanged[this.currentPage()] =
+ !compareArrays(this.defaultPagesState[this.currentPage()], this.arrayFilter(this.getChildItems()));
+ this.changed(_.some(this.pagesChanged));
}
});
});
diff --git a/app/code/Magento/Ui/view/base/web/js/form/components/fieldset.js b/app/code/Magento/Ui/view/base/web/js/form/components/fieldset.js
index 371a0773f9d7e..6d33386fa1f1c 100644
--- a/app/code/Magento/Ui/view/base/web/js/form/components/fieldset.js
+++ b/app/code/Magento/Ui/view/base/web/js/form/components/fieldset.js
@@ -22,7 +22,7 @@ define([
opened: false,
level: 0,
visible: true,
- initializeFieldsetDataByDefault: false, /* Data in some fieldsets should be initialized before open */
+ initializeFieldsetDataByDefault: false, /* Data in some fieldsets should be initialized before open */
disabled: false,
listens: {
'opened': 'onVisibilityChange'
@@ -77,9 +77,9 @@ define([
elem.initContainer(this);
elem.on({
- 'update': this.onChildrenUpdate,
- 'loading': this.onContentLoading,
- 'error': this.onChildrenError
+ 'update': this.onChildrenUpdate,
+ 'loading': this.onContentLoading,
+ 'error': this.onChildrenError
});
if (this.disabled) {
@@ -115,14 +115,14 @@ define([
* @returns {Group} Chainable.
*/
_setClasses: function () {
- var addtional = this.additionalClasses,
+ var additional = this.additionalClasses,
classes;
- if (_.isString(addtional)) {
- addtional = this.additionalClasses.split(' ');
+ if (_.isString(additional)) {
+ additional = this.additionalClasses.split(' ');
classes = this.additionalClasses = {};
- addtional.forEach(function (name) {
+ additional.forEach(function (name) {
classes[name] = true;
}, this);
}
@@ -155,11 +155,42 @@ define([
* @param {String} message - error message.
*/
onChildrenError: function (message) {
- var hasErrors = this.elems.some('error');
+ var hasErrors = false;
+
+ if (!message) {
+ hasErrors = this._isChildrenHasErrors(hasErrors, this);
+ }
this.error(hasErrors || message);
},
+ /**
+ * Returns errors of children if exist
+ *
+ * @param {Boolean} hasErrors
+ * @param {*} container
+ * @return {Boolean}
+ * @private
+ */
+ _isChildrenHasErrors: function (hasErrors, container) {
+ var self = this;
+
+ if (hasErrors === false && container.hasOwnProperty('elems')) {
+ hasErrors = container.elems.some('error');
+
+ if (hasErrors === false && container.hasOwnProperty('_elems')) {
+ container._elems.forEach(function (child) {
+
+ if (hasErrors === false) {
+ hasErrors = self._isChildrenHasErrors(hasErrors, child);
+ }
+ });
+ }
+ }
+
+ return hasErrors;
+ },
+
/**
* Callback that sets loading property to true.
*/
diff --git a/app/code/Magento/Ui/view/base/web/js/form/components/group.js b/app/code/Magento/Ui/view/base/web/js/form/components/group.js
index f6937cffe1f2f..8c5950f7e2fa1 100644
--- a/app/code/Magento/Ui/view/base/web/js/form/components/group.js
+++ b/app/code/Magento/Ui/view/base/web/js/form/components/group.js
@@ -58,14 +58,14 @@ define([
* @returns {Group} Chainable.
*/
_setClasses: function () {
- var addtional = this.additionalClasses,
+ var additional = this.additionalClasses,
classes;
- if (_.isString(addtional)) {
- addtional = this.additionalClasses.split(' ');
+ if (_.isString(additional)) {
+ additional = this.additionalClasses.split(' ');
classes = this.additionalClasses = {};
- addtional.forEach(function (name) {
+ additional.forEach(function (name) {
classes[name] = true;
}, this);
}
diff --git a/app/code/Magento/Ui/view/base/web/js/form/element/abstract.js b/app/code/Magento/Ui/view/base/web/js/form/element/abstract.js
index 5177b4a378d69..3b1026e1d7fd4 100755
--- a/app/code/Magento/Ui/view/base/web/js/form/element/abstract.js
+++ b/app/code/Magento/Ui/view/base/web/js/form/element/abstract.js
@@ -40,6 +40,7 @@ define([
showFallbackReset: false,
additionalClasses: {},
isUseDefault: '',
+ serviceDisabled: false,
valueUpdate: false, // ko binding valueUpdate
switcherConfig: {
@@ -97,7 +98,7 @@ define([
this._super();
this.observe('error disabled focused preview visible value warn notice isDifferedFromDefault')
- .observe('isUseDefault')
+ .observe('isUseDefault serviceDisabled')
.observe({
'required': !!rules['required-entry']
});
@@ -449,6 +450,10 @@ define([
*/
toggleUseDefault: function (state) {
this.disabled(state);
+
+ if (this.source && this.hasService()) {
+ this.source.set('data.use_default.' + this.index, Number(state));
+ }
},
/**
diff --git a/app/code/Magento/Ui/view/base/web/js/form/element/file-uploader.js b/app/code/Magento/Ui/view/base/web/js/form/element/file-uploader.js
index 4641ae96c9ece..b81119f2bd5f3 100644
--- a/app/code/Magento/Ui/view/base/web/js/form/element/file-uploader.js
+++ b/app/code/Magento/Ui/view/base/web/js/form/element/file-uploader.js
@@ -133,7 +133,7 @@ define([
/**
* Retrieves from the list file which matches
- * search criteria implemented in itertor function.
+ * search criteria implemented in iterator function.
*
* @param {Function} fn - Function that will be invoked
* for each file in the list.
@@ -193,7 +193,7 @@ define([
},
/**
- * Returns path to the files' preview image.
+ * Returns path to the file's preview image.
*
* @param {Object} file
* @returns {String}
@@ -310,7 +310,7 @@ define([
/**
* Abstract handler which is invoked when files are choosed for upload.
- * May be used for implementation of aditional validation rules,
+ * May be used for implementation of additional validation rules,
* e.g. total files and a total size rules.
*
* @abstract
diff --git a/app/code/Magento/Ui/view/base/web/js/form/element/region.js b/app/code/Magento/Ui/view/base/web/js/form/element/region.js
index 0edb4c1966b54..fec69bf8558b5 100644
--- a/app/code/Magento/Ui/view/base/web/js/form/element/region.js
+++ b/app/code/Magento/Ui/view/base/web/js/form/element/region.js
@@ -57,6 +57,7 @@ define([
registry.get(this.customName, function (input) {
isRegionRequired = !!option['is_region_required'];
input.validation['required-entry'] = isRegionRequired;
+ input.validation['validate-not-number-first'] = true;
input.required(isRegionRequired);
});
}
diff --git a/app/code/Magento/Ui/view/base/web/js/form/element/single-checkbox-use-config.js b/app/code/Magento/Ui/view/base/web/js/form/element/single-checkbox-use-config.js
index b20b2c31ee1fb..3ee7ddd1e738f 100644
--- a/app/code/Magento/Ui/view/base/web/js/form/element/single-checkbox-use-config.js
+++ b/app/code/Magento/Ui/view/base/web/js/form/element/single-checkbox-use-config.js
@@ -36,6 +36,10 @@ define([
*/
toggleElement: function () {
this.disabled(this.isUseDefault() || this.isUseConfig());
+
+ if (this.source) {
+ this.source.set('data.use_default.' + this.index, Number(this.isUseDefault()));
+ }
}
});
});
diff --git a/app/code/Magento/Ui/view/base/web/js/grid/columns/multiselect.js b/app/code/Magento/Ui/view/base/web/js/grid/columns/multiselect.js
index 0a29728390592..188431fdeedc5 100644
--- a/app/code/Magento/Ui/view/base/web/js/grid/columns/multiselect.js
+++ b/app/code/Magento/Ui/view/base/web/js/grid/columns/multiselect.js
@@ -229,6 +229,15 @@ define([
return this;
},
+ /**
+ * Selects or deselects all records on the current page.
+ *
+ * @returns {Multiselect} Chainable.
+ */
+ togglePage: function () {
+ return this.isPageSelected() ? this.deselectPage() : this.selectPage();
+ },
+
/**
* Clears the array of not selected records.
*
diff --git a/app/code/Magento/Ui/view/base/web/js/grid/filters/range.js b/app/code/Magento/Ui/view/base/web/js/grid/filters/range.js
index 438d6ccd58a55..ccfba8e98b6f4 100644
--- a/app/code/Magento/Ui/view/base/web/js/grid/filters/range.js
+++ b/app/code/Magento/Ui/view/base/web/js/grid/filters/range.js
@@ -27,7 +27,8 @@ define([
},
date: {
component: 'Magento_Ui/js/form/element/date',
- dateFormat: 'MM/dd/YYYY'
+ dateFormat: 'MM/dd/YYYY',
+ shiftedValue: 'filter'
},
text: {
component: 'Magento_Ui/js/form/element/abstract'
diff --git a/app/code/Magento/Ui/view/base/web/js/grid/massactions.js b/app/code/Magento/Ui/view/base/web/js/grid/massactions.js
index 046ff12bfaa6f..48c04458ff49a 100644
--- a/app/code/Magento/Ui/view/base/web/js/grid/massactions.js
+++ b/app/code/Magento/Ui/view/base/web/js/grid/massactions.js
@@ -175,11 +175,14 @@ define([
* invoked if action is confirmed.
*/
_confirm: function (action, callback) {
- var confirmData = action.confirm;
+ var confirmData = action.confirm,
+ data = this.getSelections(),
+ total = data.total ? data.total : 0,
+ confirmMessage = confirmData.message + ' (' + total + ' record' + (total > 1 ? 's' : '') + ')';
confirm({
title: confirmData.title,
- content: confirmData.message,
+ content: confirmMessage,
actions: {
confirm: callback
}
diff --git a/app/code/Magento/Ui/view/base/web/js/lib/core/element/element.js b/app/code/Magento/Ui/view/base/web/js/lib/core/element/element.js
index b228494b422c3..b05fed939b7a5 100644
--- a/app/code/Magento/Ui/view/base/web/js/lib/core/element/element.js
+++ b/app/code/Magento/Ui/view/base/web/js/lib/core/element/element.js
@@ -46,7 +46,7 @@ define([
}
/**
- * Creates observable propery using 'track' method.
+ * Creates observable property using 'track' method.
*
* @param {Object} obj - Object to whom property belongs.
* @param {String} key - Key of the property.
@@ -66,7 +66,7 @@ define([
Element = _.extend({
defaults: {
- _requesetd: {},
+ _requested: {},
containers: [],
exports: {},
imports: {},
@@ -249,7 +249,7 @@ define([
* @returns {Function} Async module wrapper.
*/
requestModule: function (name) {
- var requested = this._requesetd;
+ var requested = this._requested;
if (!requested[name]) {
requested[name] = registry.async(name);
diff --git a/app/code/Magento/Ui/view/base/web/js/lib/validation/rules.js b/app/code/Magento/Ui/view/base/web/js/lib/validation/rules.js
index 759f74b95e8e0..041b6eb3b48c1 100644
--- a/app/code/Magento/Ui/view/base/web/js/lib/validation/rules.js
+++ b/app/code/Magento/Ui/view/base/web/js/lib/validation/rules.js
@@ -72,13 +72,13 @@ define([
],
'max-words': [
function (value, params) {
- return utils.stripHtml(value).match(/\b\w+\b/g).length < params;
+ return utils.isEmpty(value) || utils.stripHtml(value).match(/\b\w+\b/g).length < params;
},
$.mage.__('Please enter {0} words or less.')
],
'min-words': [
function (value, params) {
- return utils.stripHtml(value).match(/\b\w+\b/g).length >= params;
+ return utils.isEmpty(value) || utils.stripHtml(value).match(/\b\w+\b/g).length >= params;
},
$.mage.__('Please enter at least {0} words.')
],
@@ -86,49 +86,53 @@ define([
function (value, params) {
var match = utils.stripHtml(value).match(/\b\w+\b/g) || [];
- return match.length >= params[0] &&
+ return utils.isEmpty(value) || match.length >= params[0] &&
match.length <= params[1];
},
$.mage.__('Please enter between {0} and {1} words.')
],
'letters-with-basic-punc': [
function (value) {
- return /^[a-z\-.,()\u0027\u0022\s]+$/i.test(value);
+ return utils.isEmpty(value) || /^[a-z\-.,()\u0027\u0022\s]+$/i.test(value);
},
$.mage.__('Letters or punctuation only please')
],
'alphanumeric': [
function (value) {
- return /^\w+$/i.test(value);
+ return utils.isEmpty(value) || /^\w+$/i.test(value);
},
$.mage.__('Letters, numbers, spaces or underscores only please')
],
'letters-only': [
function (value) {
- return /^[a-z]+$/i.test(value);
+ return utils.isEmpty(value) || /^[a-z]+$/i.test(value);
},
$.mage.__('Letters only please')
],
'no-whitespace': [
function (value) {
- return /^\S+$/i.test(value);
+ return utils.isEmpty(value) || /^\S+$/i.test(value);
},
$.mage.__('No white space please')
],
'zip-range': [
function (value) {
- return /^90[2-5]-\d{2}-\d{4}$/.test(value);
+ return utils.isEmpty(value) || /^90[2-5]-\d{2}-\d{4}$/.test(value);
},
$.mage.__('Your ZIP-code must be in the range 902xx-xxxx to 905-xx-xxxx')
],
'integer': [
function (value) {
- return /^-?\d+$/.test(value);
+ return utils.isEmpty(value) || /^-?\d+$/.test(value);
},
$.mage.__('A positive or negative non-decimal number please')
],
'vinUS': [
function (value) {
+ if (utils.isEmpty(value)) {
+ return true;
+ }
+
if (value.length !== 17) {
return false;
}
@@ -214,13 +218,13 @@ define([
],
'time': [
function (value) {
- return /^([01]\d|2[0-3])(:[0-5]\d){0,2}$/.test(value);
+ return utils.isEmpty(value) || /^([01]\d|2[0-3])(:[0-5]\d){0,2}$/.test(value);
},
$.mage.__('Please enter a valid time, between 00:00 and 23:59')
],
'time12h': [
function (value) {
- return /^((0?[1-9]|1[012])(:[0-5]\d){0,2}(\ [AP]M))$/i.test(value);
+ return utils.isEmpty(value) || /^((0?[1-9]|1[012])(:[0-5]\d){0,2}(\ [AP]M))$/i.test(value);
},
$.mage.__('Please enter a valid time, between 00:00 am and 12:00 pm')
],
@@ -228,19 +232,21 @@ define([
function (value) {
value = value.replace(/\s+/g, '');
- return value.length > 9 && value.match(/^(1-?)?(\([2-9]\d{2}\)|[2-9]\d{2})-?[2-9]\d{2}-?\d{4}$/);
+ return utils.isEmpty(value) || value.length > 9 &&
+ value.match(/^(1-?)?(\([2-9]\d{2}\)|[2-9]\d{2})-?[2-9]\d{2}-?\d{4}$/);
},
$.mage.__('Please specify a valid phone number')
],
'phoneUK': [
function (value) {
- return value.length > 9 && value.match(/^(\(?(0|\+44)[1-9]{1}\d{1,4}?\)?\s?\d{3,4}\s?\d{3,4})$/);
+ return utils.isEmpty(value) || value.length > 9 &&
+ value.match(/^(\(?(0|\+44)[1-9]{1}\d{1,4}?\)?\s?\d{3,4}\s?\d{3,4})$/);
},
$.mage.__('Please specify a valid phone number')
],
'mobileUK': [
function (value) {
- return value.length > 9 && value.match(/^((0|\+44)7\d{3}\s?\d{6})$/);
+ return utils.isEmpty(value) || value.length > 9 && value.match(/^((0|\+44)7\d{3}\s?\d{6})$/);
},
$.mage.__('Please specify a valid mobile number')
],
@@ -252,13 +258,13 @@ define([
],
'email2': [
function (value) {
- return /^((([a-z]|\d|[!#\$%&\u0027\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&\u0027\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\u0022)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\u0022)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)*(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?$/i.test(value);//eslint-disable-line max-len
+ return utils.isEmpty(value) || /^((([a-z]|\d|[!#\$%&\u0027\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&\u0027\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\u0022)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\u0022)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)*(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?$/i.test(value);//eslint-disable-line max-len
},
$.validator.messages.email
],
'url2': [
function (value) {
- return /^(https?|ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&\u0027\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)*(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&\u0027\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&\u0027\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&\u0027\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(\#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&\u0027\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i.test(value);//eslint-disable-line max-len
+ return utils.isEmpty(value) || /^(https?|ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&\u0027\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)*(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&\u0027\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&\u0027\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&\u0027\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(\#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&\u0027\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i.test(value);//eslint-disable-line max-len
},
$.validator.messages.url
],
@@ -266,6 +272,10 @@ define([
function (value, param) {
var validTypes;
+ if (utils.isEmpty(value)) {
+ return true;
+ }
+
if (/[^0-9-]+/.test(value)) {
return false;
}
@@ -350,19 +360,19 @@ define([
],
'ipv4': [
function (value) {
- return /^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/i.test(value);//eslint-disable-line max-len
+ return utils.isEmpty(value) || /^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/i.test(value);//eslint-disable-line max-len
},
$.mage.__('Please enter a valid IP v4 address.')
],
'ipv6': [
function (value) {
- return /^((([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}:[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){5}:([0-9A-Fa-f]{1,4}:)?[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){4}:([0-9A-Fa-f]{1,4}:){0,2}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){3}:([0-9A-Fa-f]{1,4}:){0,3}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){2}:([0-9A-Fa-f]{1,4}:){0,4}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|(([0-9A-Fa-f]{1,4}:){0,5}:((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|(::([0-9A-Fa-f]{1,4}:){0,5}((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|([0-9A-Fa-f]{1,4}::([0-9A-Fa-f]{1,4}:){0,5}[0-9A-Fa-f]{1,4})|(::([0-9A-Fa-f]{1,4}:){0,6}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){1,7}:))$/i.test(value);//eslint-disable-line max-len
+ return utils.isEmpty(value) || /^((([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}:[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){5}:([0-9A-Fa-f]{1,4}:)?[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){4}:([0-9A-Fa-f]{1,4}:){0,2}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){3}:([0-9A-Fa-f]{1,4}:){0,3}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){2}:([0-9A-Fa-f]{1,4}:){0,4}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|(([0-9A-Fa-f]{1,4}:){0,5}:((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|(::([0-9A-Fa-f]{1,4}:){0,5}((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|([0-9A-Fa-f]{1,4}::([0-9A-Fa-f]{1,4}:){0,5}[0-9A-Fa-f]{1,4})|(::([0-9A-Fa-f]{1,4}:){0,6}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){1,7}:))$/i.test(value);//eslint-disable-line max-len
},
$.mage.__('Please enter a valid IP v6 address.')
],
'pattern': [
function (value, param) {
- return new RegExp(param).test(value);
+ return utils.isEmpty(value) || new RegExp(param).test(value);
},
$.mage.__('Invalid format.')
],
@@ -635,7 +645,7 @@ define([
'validate-number': [
function (value) {
return utils.isEmptyNoTrim(value) ||
- !isNaN(utils.parseNumber(value)) && /^\s*-?\d*(\.\d*)?\s*$/.test(value);
+ !isNaN(utils.parseNumber(value)) && /^\s*-?\d*(,\d*)*(\.\d*)?\s*$/.test(value);
},
$.mage.__('Please enter a valid number in this field.')
],
@@ -754,6 +764,12 @@ define([
},
$.mage.__('Please use only letters (a-z or A-Z) or numbers (0-9) in this field. No spaces or other characters are allowed.')//eslint-disable-line max-len
],
+ 'validate-not-number-first': [
+ function (value) {
+ return utils.isEmptyNoTrim(value) || /^[^0-9-\.].*$/.test(value.trim());
+ },
+ $.mage.__('First character must be letter.')
+ ],
'validate-date': [
function (value, params, additionalParams) {
var test = moment(value, additionalParams.dateFormat);
@@ -838,7 +854,7 @@ define([
return validateCreditCard(value);
}
- return false;
+ return true;
},
$.mage.__('Please enter a valid credit card number.')
],
@@ -879,10 +895,14 @@ define([
],
'validate-per-page-value-list': [
function (value) {
- var isValid = !utils.isEmpty(value),
+ var isValid = utils.isEmpty(value),
values = value.split(','),
i;
+ if (isValid) {
+ return true;
+ }
+
for (i = 0; i < values.length; i++) {
if (!/^[0-9]+$/.test(values[i])) {
isValid = false;
diff --git a/app/code/Magento/Ui/view/base/web/js/modal/confirm.js b/app/code/Magento/Ui/view/base/web/js/modal/confirm.js
index 9cb14f7b2ef11..eceab940d1141 100644
--- a/app/code/Magento/Ui/view/base/web/js/modal/confirm.js
+++ b/app/code/Magento/Ui/view/base/web/js/modal/confirm.js
@@ -9,10 +9,10 @@
define([
'jquery',
'underscore',
+ 'mage/translate',
'jquery/ui',
- 'Magento_Ui/js/modal/modal',
- 'mage/translate'
-], function ($, _) {
+ 'Magento_Ui/js/modal/modal'
+], function ($, _, $t) {
'use strict';
$.widget('mage.confirm', $.mage.modal, {
@@ -38,7 +38,7 @@ define([
cancel: function () {}
},
buttons: [{
- text: $.mage.__('Cancel'),
+ text: $t('Cancel'),
class: 'action-secondary action-dismiss',
/**
@@ -48,7 +48,7 @@ define([
this.closeModal(event);
}
}, {
- text: $.mage.__('OK'),
+ text: $t('OK'),
class: 'action-primary action-accept',
/**
diff --git a/app/code/Magento/Ui/view/base/web/js/modal/modal.js b/app/code/Magento/Ui/view/base/web/js/modal/modal.js
index 6c9b4b89bec7a..147a18c08c54c 100644
--- a/app/code/Magento/Ui/view/base/web/js/modal/modal.js
+++ b/app/code/Magento/Ui/view/base/web/js/modal/modal.js
@@ -104,11 +104,12 @@ define([
/**
* Escape key press handler,
* close modal window
+ * @param {Object} event - event
*/
- escapeKey: function () {
+ escapeKey: function (event) {
if (this.options.isOpen && this.modal.find(document.activeElement).length ||
this.options.isOpen && this.modal[0] === document.activeElement) {
- this.closeModal();
+ this.closeModal(event);
}
}
}
diff --git a/app/code/Magento/Ui/view/base/web/templates/block-loader.html b/app/code/Magento/Ui/view/base/web/templates/block-loader.html
index 3d8b730a9e8c5..cb28b09e4da83 100644
--- a/app/code/Magento/Ui/view/base/web/templates/block-loader.html
+++ b/app/code/Magento/Ui/view/base/web/templates/block-loader.html
@@ -6,6 +6,6 @@
-->
-
+
diff --git a/app/code/Magento/Ui/view/base/web/templates/form/components/collection.html b/app/code/Magento/Ui/view/base/web/templates/form/components/collection.html
index e153beab8748b..873b0ca744a88 100644
--- a/app/code/Magento/Ui/view/base/web/templates/form/components/collection.html
+++ b/app/code/Magento/Ui/view/base/web/templates/form/components/collection.html
@@ -30,7 +30,7 @@
-
+
diff --git a/app/code/Magento/Ui/view/base/web/templates/form/element/checkbox-set.html b/app/code/Magento/Ui/view/base/web/templates/form/element/checkbox-set.html
index 79478d2417110..ce06201adb8ba 100644
--- a/app/code/Magento/Ui/view/base/web/templates/form/element/checkbox-set.html
+++ b/app/code/Magento/Ui/view/base/web/templates/form/element/checkbox-set.html
@@ -16,14 +16,14 @@
-
diff --git a/app/code/Magento/Ui/view/base/web/templates/form/element/helper/service.html b/app/code/Magento/Ui/view/base/web/templates/form/element/helper/service.html
index e3c3ab5b5df5c..195104b36721e 100644
--- a/app/code/Magento/Ui/view/base/web/templates/form/element/helper/service.html
+++ b/app/code/Magento/Ui/view/base/web/templates/form/element/helper/service.html
@@ -10,8 +10,8 @@
attr="
id: $data.uid + '_default',
name: 'use_default[' + $data.index + ']',
- 'data-form-part': $data.ns
"
- ko-checked="isUseDefault">
+ ko-checked="isUseDefault"
+ ko-disabled="$data.serviceDisabled">
diff --git a/app/code/Magento/Ui/view/base/web/templates/form/field.html b/app/code/Magento/Ui/view/base/web/templates/form/field.html
index 6143900d5dd7b..144825967401e 100644
--- a/app/code/Magento/Ui/view/base/web/templates/form/field.html
+++ b/app/code/Magento/Ui/view/base/web/templates/form/field.html
@@ -8,9 +8,9 @@
visible="visible"
css="$data.additionalClasses"
attr="'data-index': index">
-
-
-
+
+
+
@@ -35,7 +35,7 @@
-
+
diff --git a/app/code/Magento/Ui/view/base/web/templates/grid/columns/multiselect.html b/app/code/Magento/Ui/view/base/web/templates/grid/columns/multiselect.html
index 18dd49bd56ee3..e6e14d5aa335b 100644
--- a/app/code/Magento/Ui/view/base/web/templates/grid/columns/multiselect.html
+++ b/app/code/Magento/Ui/view/base/web/templates/grid/columns/multiselect.html
@@ -11,7 +11,7 @@
data-bind="
checked: allSelected(),
attr: {id: ++ko.uid},
- event: { change: toggleSelectAll },
+ event: { change: togglePage },
css: { '_indeterminate': indetermine },
enable: totalRecords">
diff --git a/app/code/Magento/Ui/view/base/web/templates/grid/editing/bulk.html b/app/code/Magento/Ui/view/base/web/templates/grid/editing/bulk.html
index a11e56a68dab2..81c7acaf4aa33 100644
--- a/app/code/Magento/Ui/view/base/web/templates/grid/editing/bulk.html
+++ b/app/code/Magento/Ui/view/base/web/templates/grid/editing/bulk.html
@@ -13,7 +13,7 @@
-
+
diff --git a/app/code/Magento/Ui/view/base/web/templates/grid/editing/row.html b/app/code/Magento/Ui/view/base/web/templates/grid/editing/row.html
index 4b3109e522f0b..c82456b2a357c 100644
--- a/app/code/Magento/Ui/view/base/web/templates/grid/editing/row.html
+++ b/app/code/Magento/Ui/view/base/web/templates/grid/editing/row.html
@@ -11,8 +11,8 @@
-
-
+
+
diff --git a/app/code/Magento/Ui/view/base/web/templates/grid/sticky/sticky.html b/app/code/Magento/Ui/view/base/web/templates/grid/sticky/sticky.html
index 0bd5ea06dbf86..8d79bfe6a1b4c 100644
--- a/app/code/Magento/Ui/view/base/web/templates/grid/sticky/sticky.html
+++ b/app/code/Magento/Ui/view/base/web/templates/grid/sticky/sticky.html
@@ -7,7 +7,7 @@